@noodleseed/one 0.136.0 → 0.138.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/assistant-ops.d.ts.map +1 -1
- package/dist/commands/assistant-ops.js +30 -1
- package/dist/commands/assistant-ops.js.map +1 -1
- package/dist/commands/deploy-first-flow.d.ts +2 -0
- package/dist/commands/deploy-first-flow.d.ts.map +1 -1
- package/dist/commands/deploy-first-flow.js +46 -14
- package/dist/commands/deploy-first-flow.js.map +1 -1
- package/dist/commands/deploy-ops.d.ts.map +1 -1
- package/dist/commands/deploy-ops.js +27 -1
- package/dist/commands/deploy-ops.js.map +1 -1
- package/dist/commands/deploy-preflight.d.ts +1 -0
- package/dist/commands/deploy-preflight.d.ts.map +1 -1
- package/dist/commands/deploy-preflight.js +1 -0
- package/dist/commands/deploy-preflight.js.map +1 -1
- package/dist/commands/deploy-status-ops.d.ts +1 -0
- package/dist/commands/deploy-status-ops.d.ts.map +1 -1
- package/dist/commands/deploy-status-ops.js +59 -4
- package/dist/commands/deploy-status-ops.js.map +1 -1
- package/dist/commands/deployments-ops.d.ts.map +1 -1
- package/dist/commands/deployments-ops.js +2 -0
- package/dist/commands/deployments-ops.js.map +1 -1
- package/dist/commands/diagnostics-ops.d.ts +1 -0
- package/dist/commands/diagnostics-ops.d.ts.map +1 -1
- package/dist/commands/diagnostics-ops.js +3 -0
- package/dist/commands/diagnostics-ops.js.map +1 -1
- package/dist/deploy.d.ts +3 -0
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +4 -0
- package/dist/deploy.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/node_modules/@noodle-borg/admission-limits/dist/envelope.js +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +4 -4
- package/node_modules/@noodle-borg/agent-kit/dist/generated/surface.js +1 -0
- package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js +22 -13
- package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-store.d.ts +6 -2
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-store.js +5 -2
- package/node_modules/@noodle-borg/assistant-gateway/dist/model-request.js +37 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/model-runtime.js +4 -0
- package/node_modules/@noodle-borg/{service/dist/assistant-model-stream.js → assistant-gateway/dist/model-stream.js} +34 -2
- package/node_modules/@noodle-borg/assistant-gateway/dist/public-session.d.ts +3 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/public-session.js +2 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/public-turn.d.ts +4 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/public-turn.js +2 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/surface-budget.d.ts +6 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/surface-budget.js +11 -5
- package/node_modules/@noodle-borg/assistant-gateway/package.json +5 -1
- package/node_modules/@noodle-borg/authoring/dist/assistant.d.ts +10 -2
- package/node_modules/@noodle-borg/authoring/dist/assistant.js +4 -0
- package/node_modules/@noodle-borg/authoring/dist/index.d.ts +1 -1
- package/node_modules/@noodle-borg/authoring/dist/index.js +1 -1
- package/node_modules/@noodle-borg/authoring/dist/load-authored.js +1 -1
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-assistant.js +17 -0
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-hosted-deployment.js +14 -0
- package/node_modules/@noodle-borg/compiler/dist/artifact/types.d.ts +1 -7
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +20 -8
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js +12 -8
- package/node_modules/@noodle-borg/control-plane/dist/portable.d.ts +2 -0
- package/node_modules/@noodle-borg/control-plane/dist/portable.js +1 -0
- package/node_modules/@noodle-borg/control-plane/dist/rollback-deployment.d.ts +61 -0
- package/node_modules/@noodle-borg/{service/dist/operations → control-plane/dist}/rollback-deployment.js +3 -2
- package/node_modules/@noodle-borg/control-plane/dist/rollback-result.d.ts +19 -0
- package/node_modules/@noodle-borg/control-plane/package.json +3 -1
- package/node_modules/@noodle-borg/developer-mcp/dist/contracts.js +4 -0
- package/node_modules/@noodle-borg/developer-mcp/dist/widgets/app-overview.js +1 -1
- package/node_modules/@noodle-borg/developer-mcp/dist/widgets/deployment-detail.js +1 -1
- package/node_modules/@noodle-borg/module/dist/contract.d.ts +1 -0
- package/node_modules/@noodle-borg/module/dist/deployment-automation.d.ts +1 -1
- package/node_modules/@noodle-borg/module/dist/endpoint-url.d.ts +11 -0
- package/node_modules/@noodle-borg/module/dist/endpoint-url.js +20 -0
- package/node_modules/@noodle-borg/module/dist/index.d.ts +1 -0
- package/node_modules/@noodle-borg/module/dist/index.js +1 -0
- package/node_modules/@noodle-borg/observability/dist/assistant-usage.js +217 -0
- package/node_modules/@noodle-borg/observability/dist/index.js +2 -0
- package/node_modules/@noodle-borg/{service → observability}/dist/request-event-metrics.js +5 -2
- package/node_modules/@noodle-borg/observability/dist/request-events-postgres.js +6 -0
- package/node_modules/@noodle-borg/observability/dist/request-events.js +2 -0
- package/node_modules/@noodle-borg/service/dist/assistant-bindings.js +3 -1
- package/node_modules/@noodle-borg/service/dist/developer-mcp/control-plane-adapter.js +3 -3
- package/node_modules/@noodle-borg/service/dist/developer-mcp/inspection.js +2 -1
- package/node_modules/@noodle-borg/service/dist/registry-access.js +73 -24
- package/node_modules/@noodle-borg/service/dist/registry-deploy-transaction.js +5 -2
- package/node_modules/@noodle-borg/service/dist/registry-helpers.d.ts +5 -9
- package/node_modules/@noodle-borg/service/dist/registry-helpers.js +4 -18
- package/node_modules/@noodle-borg/service/dist/registry-rollback.js +3 -1
- package/node_modules/@noodle-borg/service/dist/registry-status.js +4 -1
- package/node_modules/@noodle-borg/service/dist/registry-targets.js +4 -4
- package/node_modules/@noodle-borg/service/dist/registry-types.d.ts +11 -16
- package/node_modules/@noodle-borg/service/dist/registry.d.ts +8 -5
- package/node_modules/@noodle-borg/service/dist/registry.js +8 -5
- package/node_modules/@noodle-borg/service/dist/routes/access.js +19 -1
- package/node_modules/@noodle-borg/service/dist/routes/analytics-dispatch.js +17 -1
- package/node_modules/@noodle-borg/service/dist/routes/analytics.js +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-agent.js +73 -59
- package/node_modules/@noodle-borg/service/dist/routes/assistant-doctor.js +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-model-binding.js +28 -0
- package/node_modules/@noodle-borg/service/dist/routes/assistant-public-session.js +18 -0
- package/node_modules/@noodle-borg/service/dist/routes/assistant-public-turn.js +6 -0
- package/node_modules/@noodle-borg/service/dist/routes/assistant-usage.js +42 -0
- package/node_modules/@noodle-borg/service/dist/routes/assistant.js +20 -3
- package/node_modules/@noodle-borg/service/dist/routes/auth-doctor-live.js +1 -2
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.js +49 -4
- package/node_modules/@noodle-borg/service/dist/routes/deploy-preflight.js +11 -1
- package/node_modules/@noodle-borg/service/dist/routes/endpoint-enrichment.js +2 -1
- package/node_modules/@noodle-borg/service/dist/routes/paths.js +4 -0
- package/node_modules/@noodle-borg/service/dist/routes/rollback.js +1 -1
- package/node_modules/@noodle-borg/service/dist/service.js +6 -0
- package/node_modules/@noodle-borg/service/dist/store/in-memory.d.ts +2 -5
- package/node_modules/@noodle-borg/service/dist/store/in-memory.js +9 -21
- package/node_modules/@noodle-borg/service/dist/store/json-file.d.ts +2 -5
- package/node_modules/@noodle-borg/service/dist/store/json-file.js +8 -20
- package/node_modules/@noodle-borg/service/dist/store/records.js +39 -0
- package/node_modules/@noodle-borg/service/dist/store.d.ts +21 -10
- package/node_modules/@noodle-borg/service/package.json +5 -1
- package/node_modules/@noodle-borg/wire-contracts/dist/control-plane.d.ts +120 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/control-plane.js +123 -1
- package/node_modules/@noodle-borg/wire-contracts/dist/index.d.ts +4 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/index.js +15 -1
- package/node_modules/@noodleseed/assistant/README.md +43 -8
- package/node_modules/@noodleseed/assistant/package.json +16 -2
- package/package.json +2 -2
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/** Strict service-output contracts for control-plane reads and mutations (ADR 0128). */
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
+
/** Exact OAuth subject bound by an operator to an owner-only deployment. */
|
|
4
|
+
export declare const deploymentOwnerSubjectSchema: z.ZodString;
|
|
3
5
|
export declare const accessUpdateRequestSchema: z.ZodObject<{
|
|
4
6
|
accessMode: z.ZodEnum<{
|
|
5
7
|
"owner-only": "owner-only";
|
|
@@ -9,8 +11,118 @@ export declare const accessUpdateRequestSchema: z.ZodObject<{
|
|
|
9
11
|
mixed: "mixed";
|
|
10
12
|
customers: "customers";
|
|
11
13
|
}>;
|
|
14
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
12
15
|
serverVersion: z.ZodOptional<z.ZodString>;
|
|
13
16
|
}, z.core.$strict>;
|
|
17
|
+
export declare const accessUpdateResponseSchema: z.ZodObject<{
|
|
18
|
+
ok: z.ZodLiteral<true>;
|
|
19
|
+
target: z.ZodObject<{
|
|
20
|
+
org: z.ZodString;
|
|
21
|
+
app: z.ZodString;
|
|
22
|
+
env: z.ZodString;
|
|
23
|
+
}, z.core.$strict>;
|
|
24
|
+
deployment: z.ZodObject<{
|
|
25
|
+
deploymentId: z.ZodString;
|
|
26
|
+
serverVersion: z.ZodOptional<z.ZodString>;
|
|
27
|
+
accessMode: z.ZodEnum<{
|
|
28
|
+
"owner-only": "owner-only";
|
|
29
|
+
"org-members": "org-members";
|
|
30
|
+
authenticated: "authenticated";
|
|
31
|
+
public: "public";
|
|
32
|
+
mixed: "mixed";
|
|
33
|
+
customers: "customers";
|
|
34
|
+
}>;
|
|
35
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
36
|
+
}, z.core.$strict>;
|
|
37
|
+
previousAccessMode: z.ZodEnum<{
|
|
38
|
+
"owner-only": "owner-only";
|
|
39
|
+
"org-members": "org-members";
|
|
40
|
+
authenticated: "authenticated";
|
|
41
|
+
public: "public";
|
|
42
|
+
mixed: "mixed";
|
|
43
|
+
customers: "customers";
|
|
44
|
+
}>;
|
|
45
|
+
previousOwnerSubject: z.ZodOptional<z.ZodString>;
|
|
46
|
+
accessChanged: z.ZodBoolean;
|
|
47
|
+
ownerChanged: z.ZodBoolean;
|
|
48
|
+
changed: z.ZodBoolean;
|
|
49
|
+
}, z.core.$strict>;
|
|
50
|
+
export type AccessUpdateResponse = z.output<typeof accessUpdateResponseSchema>;
|
|
51
|
+
/**
|
|
52
|
+
* Additive client reader for the access mutation response. Older services emitted only the aggregate
|
|
53
|
+
* `changed` bit, so the mode component is derived from the authoritative previous/current modes while an
|
|
54
|
+
* unobservable owner component remains omitted. Modern component bits retain the strict cross-field check.
|
|
55
|
+
*/
|
|
56
|
+
export declare const accessUpdateClientResponseSchema: z.ZodPipe<z.ZodObject<{
|
|
57
|
+
ok: z.ZodLiteral<true>;
|
|
58
|
+
target: z.ZodObject<{
|
|
59
|
+
org: z.ZodString;
|
|
60
|
+
app: z.ZodString;
|
|
61
|
+
env: z.ZodString;
|
|
62
|
+
}, z.core.$strip>;
|
|
63
|
+
deployment: z.ZodObject<{
|
|
64
|
+
deploymentId: z.ZodString;
|
|
65
|
+
serverVersion: z.ZodOptional<z.ZodString>;
|
|
66
|
+
accessMode: z.ZodEnum<{
|
|
67
|
+
"owner-only": "owner-only";
|
|
68
|
+
"org-members": "org-members";
|
|
69
|
+
authenticated: "authenticated";
|
|
70
|
+
public: "public";
|
|
71
|
+
mixed: "mixed";
|
|
72
|
+
customers: "customers";
|
|
73
|
+
}>;
|
|
74
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
75
|
+
}, z.core.$strip>;
|
|
76
|
+
previousAccessMode: z.ZodEnum<{
|
|
77
|
+
"owner-only": "owner-only";
|
|
78
|
+
"org-members": "org-members";
|
|
79
|
+
authenticated: "authenticated";
|
|
80
|
+
public: "public";
|
|
81
|
+
mixed: "mixed";
|
|
82
|
+
customers: "customers";
|
|
83
|
+
}>;
|
|
84
|
+
previousOwnerSubject: z.ZodOptional<z.ZodString>;
|
|
85
|
+
accessChanged: z.ZodOptional<z.ZodBoolean>;
|
|
86
|
+
ownerChanged: z.ZodOptional<z.ZodBoolean>;
|
|
87
|
+
changed: z.ZodBoolean;
|
|
88
|
+
}, z.core.$strip>, z.ZodTransform<{
|
|
89
|
+
accessChanged: boolean;
|
|
90
|
+
ok: true;
|
|
91
|
+
target: {
|
|
92
|
+
org: string;
|
|
93
|
+
app: string;
|
|
94
|
+
env: string;
|
|
95
|
+
};
|
|
96
|
+
deployment: {
|
|
97
|
+
deploymentId: string;
|
|
98
|
+
accessMode: "owner-only" | "org-members" | "authenticated" | "public" | "mixed" | "customers";
|
|
99
|
+
serverVersion?: string | undefined;
|
|
100
|
+
ownerSubject?: string | undefined;
|
|
101
|
+
};
|
|
102
|
+
previousAccessMode: "owner-only" | "org-members" | "authenticated" | "public" | "mixed" | "customers";
|
|
103
|
+
changed: boolean;
|
|
104
|
+
previousOwnerSubject?: string | undefined;
|
|
105
|
+
ownerChanged?: boolean | undefined;
|
|
106
|
+
}, {
|
|
107
|
+
ok: true;
|
|
108
|
+
target: {
|
|
109
|
+
org: string;
|
|
110
|
+
app: string;
|
|
111
|
+
env: string;
|
|
112
|
+
};
|
|
113
|
+
deployment: {
|
|
114
|
+
deploymentId: string;
|
|
115
|
+
accessMode: "owner-only" | "org-members" | "authenticated" | "public" | "mixed" | "customers";
|
|
116
|
+
serverVersion?: string | undefined;
|
|
117
|
+
ownerSubject?: string | undefined;
|
|
118
|
+
};
|
|
119
|
+
previousAccessMode: "owner-only" | "org-members" | "authenticated" | "public" | "mixed" | "customers";
|
|
120
|
+
changed: boolean;
|
|
121
|
+
previousOwnerSubject?: string | undefined;
|
|
122
|
+
accessChanged?: boolean | undefined;
|
|
123
|
+
ownerChanged?: boolean | undefined;
|
|
124
|
+
}>>;
|
|
125
|
+
export type AccessUpdateClientResponse = z.output<typeof accessUpdateClientResponseSchema>;
|
|
14
126
|
export declare const deploymentLockRequestSchema: z.ZodObject<{
|
|
15
127
|
serverVersion: z.ZodString;
|
|
16
128
|
expectedDeploymentId: z.ZodString;
|
|
@@ -27,6 +139,7 @@ export declare const DeploymentSummarySchema: z.ZodObject<{
|
|
|
27
139
|
serverName: z.ZodString;
|
|
28
140
|
createdAt: z.ZodString;
|
|
29
141
|
createdByEmail: z.ZodOptional<z.ZodString>;
|
|
142
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
30
143
|
deploymentSource: z.ZodOptional<z.ZodString>;
|
|
31
144
|
accessMode: z.ZodEnum<{
|
|
32
145
|
"owner-only": "owner-only";
|
|
@@ -66,6 +179,7 @@ export declare const AppSummarySchema: z.ZodObject<{
|
|
|
66
179
|
serverName: z.ZodString;
|
|
67
180
|
createdAt: z.ZodString;
|
|
68
181
|
createdByEmail: z.ZodOptional<z.ZodString>;
|
|
182
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
69
183
|
deploymentSource: z.ZodOptional<z.ZodString>;
|
|
70
184
|
accessMode: z.ZodEnum<{
|
|
71
185
|
"owner-only": "owner-only";
|
|
@@ -107,6 +221,7 @@ export declare const AppsListResponseSchema: z.ZodObject<{
|
|
|
107
221
|
serverName: z.ZodString;
|
|
108
222
|
createdAt: z.ZodString;
|
|
109
223
|
createdByEmail: z.ZodOptional<z.ZodString>;
|
|
224
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
110
225
|
deploymentSource: z.ZodOptional<z.ZodString>;
|
|
111
226
|
accessMode: z.ZodEnum<{
|
|
112
227
|
"owner-only": "owner-only";
|
|
@@ -150,6 +265,7 @@ export declare const AppResponseSchema: z.ZodObject<{
|
|
|
150
265
|
serverName: z.ZodString;
|
|
151
266
|
createdAt: z.ZodString;
|
|
152
267
|
createdByEmail: z.ZodOptional<z.ZodString>;
|
|
268
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
153
269
|
deploymentSource: z.ZodOptional<z.ZodString>;
|
|
154
270
|
accessMode: z.ZodEnum<{
|
|
155
271
|
"owner-only": "owner-only";
|
|
@@ -190,6 +306,7 @@ export declare const EnvSummarySchema: z.ZodObject<{
|
|
|
190
306
|
serverName: z.ZodString;
|
|
191
307
|
createdAt: z.ZodString;
|
|
192
308
|
createdByEmail: z.ZodOptional<z.ZodString>;
|
|
309
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
193
310
|
deploymentSource: z.ZodOptional<z.ZodString>;
|
|
194
311
|
accessMode: z.ZodEnum<{
|
|
195
312
|
"owner-only": "owner-only";
|
|
@@ -233,6 +350,7 @@ export declare const EnvsListResponseSchema: z.ZodObject<{
|
|
|
233
350
|
serverName: z.ZodString;
|
|
234
351
|
createdAt: z.ZodString;
|
|
235
352
|
createdByEmail: z.ZodOptional<z.ZodString>;
|
|
353
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
236
354
|
deploymentSource: z.ZodOptional<z.ZodString>;
|
|
237
355
|
accessMode: z.ZodEnum<{
|
|
238
356
|
"owner-only": "owner-only";
|
|
@@ -277,6 +395,7 @@ export declare const EnvResponseSchema: z.ZodObject<{
|
|
|
277
395
|
serverName: z.ZodString;
|
|
278
396
|
createdAt: z.ZodString;
|
|
279
397
|
createdByEmail: z.ZodOptional<z.ZodString>;
|
|
398
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
280
399
|
deploymentSource: z.ZodOptional<z.ZodString>;
|
|
281
400
|
accessMode: z.ZodEnum<{
|
|
282
401
|
"owner-only": "owner-only";
|
|
@@ -358,6 +477,7 @@ export declare const DeploymentResponseSchema: z.ZodObject<{
|
|
|
358
477
|
serverName: z.ZodString;
|
|
359
478
|
createdAt: z.ZodString;
|
|
360
479
|
createdByEmail: z.ZodOptional<z.ZodString>;
|
|
480
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
361
481
|
deploymentSource: z.ZodOptional<z.ZodString>;
|
|
362
482
|
accessMode: z.ZodEnum<{
|
|
363
483
|
"owner-only": "owner-only";
|
|
@@ -1,12 +1,133 @@
|
|
|
1
1
|
/** Strict service-output contracts for control-plane reads and mutations (ADR 0128). */
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { accessModeSchema } from './access-mode.js';
|
|
4
|
+
function containsC0OrDel(value) {
|
|
5
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
6
|
+
const codeUnit = value.charCodeAt(index);
|
|
7
|
+
if (codeUnit <= 0x1f || codeUnit === 0x7f)
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
/** Exact OAuth subject bound by an operator to an owner-only deployment. */
|
|
13
|
+
export const deploymentOwnerSubjectSchema = z
|
|
14
|
+
.string()
|
|
15
|
+
.min(1)
|
|
16
|
+
.max(512)
|
|
17
|
+
.refine((value) => value.trim() === value && !containsC0OrDel(value), 'owner subject must not contain outer whitespace or C0/DEL control characters');
|
|
4
18
|
export const accessUpdateRequestSchema = z
|
|
5
19
|
.object({
|
|
6
20
|
accessMode: accessModeSchema,
|
|
21
|
+
ownerSubject: deploymentOwnerSubjectSchema.optional(),
|
|
7
22
|
serverVersion: z.string().min(1).optional(),
|
|
8
23
|
})
|
|
9
|
-
.strict()
|
|
24
|
+
.strict()
|
|
25
|
+
.superRefine((value, context) => {
|
|
26
|
+
if (value.ownerSubject !== undefined && value.accessMode !== 'owner-only') {
|
|
27
|
+
context.addIssue({
|
|
28
|
+
code: 'custom',
|
|
29
|
+
path: ['ownerSubject'],
|
|
30
|
+
message: 'ownerSubject is valid only with owner-only access',
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
export const accessUpdateResponseSchema = z
|
|
35
|
+
.object({
|
|
36
|
+
ok: z.literal(true),
|
|
37
|
+
target: z
|
|
38
|
+
.object({
|
|
39
|
+
org: z.string().min(1),
|
|
40
|
+
app: z.string().min(1),
|
|
41
|
+
env: z.string().min(1),
|
|
42
|
+
})
|
|
43
|
+
.strict(),
|
|
44
|
+
deployment: z
|
|
45
|
+
.object({
|
|
46
|
+
deploymentId: z.string().min(1),
|
|
47
|
+
serverVersion: z.string().min(1).optional(),
|
|
48
|
+
accessMode: accessModeSchema,
|
|
49
|
+
ownerSubject: deploymentOwnerSubjectSchema.optional(),
|
|
50
|
+
})
|
|
51
|
+
.strict(),
|
|
52
|
+
previousAccessMode: accessModeSchema,
|
|
53
|
+
previousOwnerSubject: deploymentOwnerSubjectSchema.optional(),
|
|
54
|
+
accessChanged: z.boolean(),
|
|
55
|
+
ownerChanged: z.boolean(),
|
|
56
|
+
changed: z.boolean(),
|
|
57
|
+
})
|
|
58
|
+
.strict()
|
|
59
|
+
.superRefine((value, context) => {
|
|
60
|
+
if (value.deployment.accessMode === 'owner-only' &&
|
|
61
|
+
value.deployment.ownerSubject === undefined) {
|
|
62
|
+
context.addIssue({
|
|
63
|
+
code: 'custom',
|
|
64
|
+
path: ['deployment', 'ownerSubject'],
|
|
65
|
+
message: 'owner-only access requires a current owner subject',
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
if (value.changed !== (value.accessChanged || value.ownerChanged)) {
|
|
69
|
+
context.addIssue({
|
|
70
|
+
code: 'custom',
|
|
71
|
+
path: ['changed'],
|
|
72
|
+
message: 'changed must equal accessChanged || ownerChanged',
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
/**
|
|
77
|
+
* Additive client reader for the access mutation response. Older services emitted only the aggregate
|
|
78
|
+
* `changed` bit, so the mode component is derived from the authoritative previous/current modes while an
|
|
79
|
+
* unobservable owner component remains omitted. Modern component bits retain the strict cross-field check.
|
|
80
|
+
*/
|
|
81
|
+
export const accessUpdateClientResponseSchema = z
|
|
82
|
+
.object({
|
|
83
|
+
ok: z.literal(true),
|
|
84
|
+
target: z.object({
|
|
85
|
+
org: z.string().min(1),
|
|
86
|
+
app: z.string().min(1),
|
|
87
|
+
env: z.string().min(1),
|
|
88
|
+
}),
|
|
89
|
+
deployment: z.object({
|
|
90
|
+
deploymentId: z.string().min(1),
|
|
91
|
+
serverVersion: z.string().min(1).optional(),
|
|
92
|
+
accessMode: accessModeSchema,
|
|
93
|
+
ownerSubject: deploymentOwnerSubjectSchema.optional(),
|
|
94
|
+
}),
|
|
95
|
+
previousAccessMode: accessModeSchema,
|
|
96
|
+
previousOwnerSubject: deploymentOwnerSubjectSchema.optional(),
|
|
97
|
+
accessChanged: z.boolean().optional(),
|
|
98
|
+
ownerChanged: z.boolean().optional(),
|
|
99
|
+
changed: z.boolean(),
|
|
100
|
+
})
|
|
101
|
+
.superRefine((value, context) => {
|
|
102
|
+
const modernComponents = value.accessChanged !== undefined && value.ownerChanged !== undefined;
|
|
103
|
+
if ((value.accessChanged === undefined) !== (value.ownerChanged === undefined)) {
|
|
104
|
+
context.addIssue({
|
|
105
|
+
code: 'custom',
|
|
106
|
+
path: ['accessChanged'],
|
|
107
|
+
message: 'accessChanged and ownerChanged must be present together',
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
if (modernComponents &&
|
|
111
|
+
value.deployment.accessMode === 'owner-only' &&
|
|
112
|
+
value.deployment.ownerSubject === undefined) {
|
|
113
|
+
context.addIssue({
|
|
114
|
+
code: 'custom',
|
|
115
|
+
path: ['deployment', 'ownerSubject'],
|
|
116
|
+
message: 'owner-only access requires a current owner subject',
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
if (modernComponents && value.changed !== (value.accessChanged || value.ownerChanged)) {
|
|
120
|
+
context.addIssue({
|
|
121
|
+
code: 'custom',
|
|
122
|
+
path: ['changed'],
|
|
123
|
+
message: 'changed must equal accessChanged || ownerChanged',
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
.transform((value) => ({
|
|
128
|
+
...value,
|
|
129
|
+
accessChanged: value.accessChanged ?? value.previousAccessMode !== value.deployment.accessMode,
|
|
130
|
+
}));
|
|
10
131
|
export const deploymentLockRequestSchema = z
|
|
11
132
|
.object({
|
|
12
133
|
serverVersion: z.string().min(1),
|
|
@@ -32,6 +153,7 @@ export const DeploymentSummarySchema = z
|
|
|
32
153
|
serverName: z.string(),
|
|
33
154
|
createdAt: z.string(),
|
|
34
155
|
createdByEmail: z.string().optional(),
|
|
156
|
+
ownerSubject: deploymentOwnerSubjectSchema.optional(),
|
|
35
157
|
deploymentSource: z.string().optional(),
|
|
36
158
|
accessMode: accessModeSchema,
|
|
37
159
|
deploymentLock: DeploymentLockMetadataSchema.optional(),
|
|
@@ -80,6 +80,7 @@ export declare const deployRequestSchema: z.ZodObject<{
|
|
|
80
80
|
mixed: "mixed";
|
|
81
81
|
customers: "customers";
|
|
82
82
|
}>>;
|
|
83
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
83
84
|
orgMembershipSources: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
84
85
|
explicit: "explicit";
|
|
85
86
|
domain: "domain";
|
|
@@ -115,6 +116,7 @@ export declare const deploySuccessResponseSchema: z.ZodObject<{
|
|
|
115
116
|
mixed: "mixed";
|
|
116
117
|
customers: "customers";
|
|
117
118
|
}>;
|
|
119
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
118
120
|
url: z.ZodString;
|
|
119
121
|
defaultUrl: z.ZodString;
|
|
120
122
|
embedId: z.ZodOptional<z.ZodString>;
|
|
@@ -158,6 +160,7 @@ export declare const deployPreflightRequestSchema: z.ZodObject<{
|
|
|
158
160
|
mixed: "mixed";
|
|
159
161
|
customers: "customers";
|
|
160
162
|
}>>;
|
|
163
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
161
164
|
orgMembershipSources: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
162
165
|
explicit: "explicit";
|
|
163
166
|
domain: "domain";
|
|
@@ -183,6 +186,7 @@ export type DeployTargetState = z.infer<typeof deployTargetStateSchema>;
|
|
|
183
186
|
export declare const deployPreflightResponseSchema: z.ZodObject<{
|
|
184
187
|
ok: z.ZodLiteral<true>;
|
|
185
188
|
ready: z.ZodBoolean;
|
|
189
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
186
190
|
target: z.ZodObject<{
|
|
187
191
|
org: z.ZodString;
|
|
188
192
|
app: z.ZodString;
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { z } from 'zod';
|
|
11
11
|
import { accessModeSchema } from './access-mode.js';
|
|
12
|
+
import { deploymentOwnerSubjectSchema } from './control-plane.js';
|
|
12
13
|
export * from './access-mode.js';
|
|
13
14
|
export * from './assistant.js';
|
|
14
15
|
export * from './billing-operations.js';
|
|
@@ -50,14 +51,25 @@ export const hostedAssetSchema = z.object({
|
|
|
50
51
|
*/
|
|
51
52
|
export const ORG_MEMBERSHIP_SOURCES = ['explicit', 'domain'];
|
|
52
53
|
export const orgMembershipSourceSchema = z.enum(ORG_MEMBERSHIP_SOURCES);
|
|
53
|
-
export const deployRequestSchema = z
|
|
54
|
+
export const deployRequestSchema = z
|
|
55
|
+
.object({
|
|
54
56
|
manifest: z.string().min(1),
|
|
55
57
|
connectors: z.string().min(1).optional(),
|
|
56
58
|
hostedAssets: z.array(hostedAssetSchema).optional(),
|
|
57
59
|
accessMode: accessModeSchema.optional(),
|
|
60
|
+
ownerSubject: deploymentOwnerSubjectSchema.optional(),
|
|
58
61
|
orgMembershipSources: z.array(orgMembershipSourceSchema).min(1).optional(),
|
|
59
62
|
serverVersion: z.string().min(1).optional(),
|
|
60
63
|
deploymentSource: deploymentSourceSchema.optional(),
|
|
64
|
+
})
|
|
65
|
+
.superRefine((value, context) => {
|
|
66
|
+
if (value.ownerSubject !== undefined && (value.accessMode ?? 'owner-only') !== 'owner-only') {
|
|
67
|
+
context.addIssue({
|
|
68
|
+
code: 'custom',
|
|
69
|
+
path: ['ownerSubject'],
|
|
70
|
+
message: 'ownerSubject is valid only with owner-only access',
|
|
71
|
+
});
|
|
72
|
+
}
|
|
61
73
|
});
|
|
62
74
|
/** Exact bytes both sides bind when deriving a retry-safe deploy key. */
|
|
63
75
|
export function deployIdempotencyMaterial(target, requestBody) {
|
|
@@ -72,6 +84,7 @@ export const deploySuccessResponseSchema = z.object({
|
|
|
72
84
|
deploymentId: z.string().min(1),
|
|
73
85
|
serverVersion: z.string().min(1),
|
|
74
86
|
accessMode: accessModeSchema,
|
|
87
|
+
ownerSubject: deploymentOwnerSubjectSchema.optional(),
|
|
75
88
|
url: z.string().min(1),
|
|
76
89
|
defaultUrl: z.string().min(1),
|
|
77
90
|
/**
|
|
@@ -111,6 +124,7 @@ const deployPreflightErrorSchema = z.object({
|
|
|
111
124
|
export const deployPreflightResponseSchema = z.object({
|
|
112
125
|
ok: z.literal(true),
|
|
113
126
|
ready: z.boolean(),
|
|
127
|
+
ownerSubject: deploymentOwnerSubjectSchema.optional(),
|
|
114
128
|
target: z.object({
|
|
115
129
|
org: z.string().min(1),
|
|
116
130
|
app: z.string().min(1),
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Customer-branded embedded assistant surfaces for Noodle Seed deployments.
|
|
4
4
|
|
|
5
|
-
The package exports the canonical `<noodle-assistant>` Web Component,
|
|
6
|
-
|
|
5
|
+
The package exports the canonical `<noodle-assistant>` managed Web Component, the framework-neutral
|
|
6
|
+
`<noodle-app-view>` MCP App host from `@noodleseed/assistant/app-view`, a managed React wrapper and
|
|
7
|
+
`NoodleAppView` adapter from `@noodleseed/assistant/react`, a renderer-free React hook from
|
|
7
8
|
`@noodleseed/assistant/react/client`, a DOM-free client from `@noodleseed/assistant/client`, and the
|
|
8
9
|
backend-only `createAssistantSession` helper from `@noodleseed/assistant/server`. Light, dark, and automatic
|
|
9
10
|
themes work without configuration; the component inherits the deployed MCP server's brand kit while slots,
|
|
@@ -376,20 +377,54 @@ if (part.type === "data-view") {
|
|
|
376
377
|
}
|
|
377
378
|
```
|
|
378
379
|
|
|
379
|
-
|
|
380
|
+
`<noodle-app-view>` owns the double iframe and AppBridge; `NoodleAppView` delegates to it. Its lifecycle identity is the supplied client plus
|
|
380
381
|
`view.id` plus `view.resourceUri`: ordinary parent rerenders and fresh view/callback objects retain the
|
|
381
382
|
iframe, while a semantic view replacement or unmount requests standard App teardown and closes the bridge.
|
|
382
383
|
Do not also key an ancestor by the whole view object or a callback. Pass the embedding application's
|
|
383
384
|
resolved `"light"` or `"dark"` theme; later changes are published through MCP Apps host context without
|
|
384
385
|
replacing the iframe.
|
|
385
386
|
|
|
387
|
+
App views stay inline by default. The host advertises only inline presentation and rejects an untrusted
|
|
388
|
+
App's fullscreen request, so stale or third-party widget code cannot take over the embedding application's
|
|
389
|
+
viewport. If fullscreen is an intentional part of the customer-owned experience, opt in explicitly with
|
|
390
|
+
`allowFullscreen` on `NoodleAppView` or `allow-fullscreen` on `<noodle-app-view>`; do not enable it merely
|
|
391
|
+
because a widget requests it. After an accepted fullscreen request, the host displays an accessible exit
|
|
392
|
+
control in the top-right corner. It returns the same mounted App to inline mode without resetting its state.
|
|
393
|
+
|
|
394
|
+
Vue, Angular, and plain DOM renderers use the same host without installing React. Import its dedicated entry
|
|
395
|
+
once, then assign the complex values as element properties. In Vue, the explicit `.prop` modifier makes that
|
|
396
|
+
boundary unambiguous:
|
|
397
|
+
|
|
398
|
+
```vue
|
|
399
|
+
<script setup lang="ts">
|
|
400
|
+
import "@noodleseed/assistant/app-view";
|
|
401
|
+
</script>
|
|
402
|
+
|
|
403
|
+
<template>
|
|
404
|
+
<noodle-app-view
|
|
405
|
+
:client.prop="assistant"
|
|
406
|
+
:view.prop="part.data"
|
|
407
|
+
:theme="resolvedTheme"
|
|
408
|
+
@assistant-error="reportAssistantError"
|
|
409
|
+
/>
|
|
410
|
+
</template>
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
Configure Vue's `isCustomElement` for `noodle-app-view`. Angular uses the same element with `[client]`,
|
|
414
|
+
`[view]`, and `[theme]` property bindings. Do not serialize `client` or `view` into attributes.
|
|
415
|
+
|
|
416
|
+
`<noodle-app-view>` is the canonical host; `NoodleAppView` delegates to it. Both use the
|
|
417
|
+
service-advertised sandbox URL, route App calls through the supplied client, publish theme changes without
|
|
418
|
+
replacing the iframe, and request standard teardown on semantic replacement, disconnect, or an App teardown
|
|
419
|
+
request.
|
|
420
|
+
|
|
386
421
|
The App document owns its action intent: it calls standard `tools/call` after connecting and never relies on
|
|
387
422
|
native form navigation. If that call needs input or confirmation, the same `client` publishes the normal
|
|
388
423
|
pending interaction part for either managed or customer-owned rendering. The original App call stays pending
|
|
389
424
|
and receives its MCP result after `client.respond(...)`; applications must not retry or translate the click.
|
|
390
425
|
|
|
391
|
-
Outside React, subscribe to the DOM-free AI SDK `UIMessage` state without
|
|
392
|
-
|
|
426
|
+
Outside React, subscribe to the DOM-free AI SDK `UIMessage` state without touching browser storage. The
|
|
427
|
+
client itself registers no element; import `/app-view` only when the transcript renders linked MCP Apps:
|
|
393
428
|
|
|
394
429
|
```ts
|
|
395
430
|
import { createAssistantClient } from "@noodleseed/assistant/client";
|
|
@@ -491,8 +526,8 @@ flow collects all elicited input before its first connector operation.
|
|
|
491
526
|
|
|
492
527
|
A completed widget-linked tool emits typed `view_available` data with its call/interaction id, tool,
|
|
493
528
|
`ui://` resource identity, optional title, bounded/redacted public result, and—on current services—the
|
|
494
|
-
self-contained App document. This is an availability signal, not proof of rendering. A customer-owned
|
|
495
|
-
renderer either mounts the actual App with `NoodleAppView` or deliberately substitutes a component already
|
|
529
|
+
self-contained App document. This is an availability signal, not proof of rendering. A customer-owned
|
|
530
|
+
renderer either mounts the actual App with `<noodle-app-view>` (or its React `NoodleAppView` adapter) or deliberately substitutes a component already
|
|
496
531
|
trusted by the application and selected by `resourceUri`/tool. The JSON `result` is data for a native
|
|
497
532
|
component; serializing it is not a rendering of the linked App. Never fetch the `ui://` URI, inject
|
|
498
533
|
`part.data.html`, or assign it to `srcdoc` yourself. The standard element also forwards the same detail as a
|
|
@@ -615,7 +650,7 @@ shadow-DOM selectors and classes are not public API.
|
|
|
615
650
|
|
|
616
651
|
`theme="auto"` follows the browser's operating-system color preference. When the embedding application has
|
|
617
652
|
its own theme toggle, pass its resolved `"light"` or `"dark"` value to `NoodleAssistant` and every
|
|
618
|
-
|
|
653
|
+
`<noodle-app-view>`/`NoodleAppView`. Updates change the assistant in place and notify mounted MCP Apps through standard host
|
|
619
654
|
context.
|
|
620
655
|
|
|
621
656
|
Server branding controls customer name, themed logo/mark/avatar assets, semantic light/dark colors, density,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noodleseed/assistant",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Embed the Noodle Seed customer-branded assistant in your web app with
|
|
3
|
+
"version": "1.23.0",
|
|
4
|
+
"description": "Embed the Noodle Seed customer-branded assistant in your web app with managed or framework-owned UI, a framework-neutral MCP App host, a DOM-free client, and a backend session helper. Authoring and deploying the server is @noodleseed/one.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -26,6 +26,17 @@
|
|
|
26
26
|
},
|
|
27
27
|
"default": "./dist/index.js"
|
|
28
28
|
},
|
|
29
|
+
"./app-view": {
|
|
30
|
+
"import": {
|
|
31
|
+
"types": "./dist/app-view.d.ts",
|
|
32
|
+
"default": "./dist/app-view.js"
|
|
33
|
+
},
|
|
34
|
+
"require": {
|
|
35
|
+
"types": "./dist/app-view.d.cts",
|
|
36
|
+
"default": "./dist/app-view.cjs"
|
|
37
|
+
},
|
|
38
|
+
"default": "./dist/app-view.js"
|
|
39
|
+
},
|
|
29
40
|
"./client": {
|
|
30
41
|
"import": {
|
|
31
42
|
"types": "./dist/client.d.ts",
|
|
@@ -103,6 +114,9 @@
|
|
|
103
114
|
"module": "./dist/index.js",
|
|
104
115
|
"typesVersions": {
|
|
105
116
|
"*": {
|
|
117
|
+
"app-view": [
|
|
118
|
+
"./dist/app-view.d.ts"
|
|
119
|
+
],
|
|
106
120
|
"react": [
|
|
107
121
|
"./dist/react.d.ts"
|
|
108
122
|
],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noodleseed/one",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.138.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Noodle CLI by Noodle Seed — author, run, and deploy declarative MCP servers. Embedding the assistant in your own web app is @noodleseed/assistant.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -236,7 +236,7 @@
|
|
|
236
236
|
"@modelcontextprotocol/client": "2.0.0",
|
|
237
237
|
"@modelcontextprotocol/server": "2.0.0",
|
|
238
238
|
"@noodle-borg/admission-limits": "0.0.0",
|
|
239
|
-
"@noodle-borg/agent-kit": "0.
|
|
239
|
+
"@noodle-borg/agent-kit": "0.82.0",
|
|
240
240
|
"@noodle-borg/app-audit": "0.0.0",
|
|
241
241
|
"@noodle-borg/app-package": "0.0.0",
|
|
242
242
|
"@noodle-borg/assistant-gateway": "0.0.0",
|