@noodleseed/one 0.167.0 → 0.169.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/deployment-delete-ops.d.ts +12 -0
- package/dist/commands/deployment-delete-ops.d.ts.map +1 -0
- package/dist/commands/deployment-delete-ops.js +230 -0
- package/dist/commands/deployment-delete-ops.js.map +1 -0
- package/dist/commands/deployment-delete-recovery.d.ts +35 -0
- package/dist/commands/deployment-delete-recovery.d.ts.map +1 -0
- package/dist/commands/deployment-delete-recovery.js +99 -0
- package/dist/commands/deployment-delete-recovery.js.map +1 -0
- package/dist/commands/deployments-ops.d.ts +2 -1
- package/dist/commands/deployments-ops.d.ts.map +1 -1
- package/dist/commands/deployments-ops.js +5 -1
- package/dist/commands/deployments-ops.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/behavior-skills.js +4 -2
- package/node_modules/@noodle-borg/agent-kit/dist/plugin-bootstrap-skill.js +8 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js +20 -0
- package/node_modules/@noodle-borg/agent-kit/dist/skill-router.js +9 -2
- package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-tenant-resources.js +27 -1
- package/node_modules/@noodle-borg/control-plane/dist/delete-deployment.d.ts +44 -0
- package/node_modules/@noodle-borg/control-plane/dist/delete-deployment.js +105 -0
- package/node_modules/@noodle-borg/control-plane/dist/deployment-deletion-contracts.d.ts +20 -0
- 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/service/dist/deployment-deletion.js +40 -0
- package/node_modules/@noodle-borg/service/dist/registry-compile.js +6 -0
- package/node_modules/@noodle-borg/service/dist/registry-deletion.js +75 -0
- package/node_modules/@noodle-borg/service/dist/registry-state.js +4 -2
- package/node_modules/@noodle-borg/service/dist/registry-targets.js +4 -0
- package/node_modules/@noodle-borg/service/dist/registry.d.ts +2 -0
- package/node_modules/@noodle-borg/service/dist/registry.js +7 -23
- package/node_modules/@noodle-borg/service/dist/routes/deploy-dispatch.js +15 -1
- package/node_modules/@noodle-borg/service/dist/routes/deployment-delete.js +53 -0
- package/node_modules/@noodle-borg/service/dist/store/in-memory.d.ts +2 -1
- package/node_modules/@noodle-borg/service/dist/store/in-memory.js +8 -0
- package/node_modules/@noodle-borg/service/dist/store/json-file-deletion.js +64 -0
- package/node_modules/@noodle-borg/service/dist/store/json-file.d.ts +2 -1
- package/node_modules/@noodle-borg/service/dist/store/json-file.js +23 -5
- package/node_modules/@noodle-borg/service/dist/store.d.ts +5 -1
- package/node_modules/@noodle-borg/service/package.json +1 -1
- package/node_modules/@noodle-borg/wire-contracts/dist/deployment-deletion.d.ts +29 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/deployment-deletion.js +33 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/index.d.ts +1 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/index.js +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdir, open, readFile, rename } from 'node:fs/promises';
|
|
3
|
+
import { dirname, join, resolve } from 'node:path';
|
|
4
|
+
import { DEPLOYMENT_ID_PATTERN } from './validate.js';
|
|
5
|
+
const lifecycleTails = new Map();
|
|
6
|
+
/** All adapters for one local directory join the same process-local lifecycle ordering. */
|
|
7
|
+
export function serializeFileLifecycle(directory, operation) {
|
|
8
|
+
const key = resolve(directory);
|
|
9
|
+
const result = (lifecycleTails.get(key) ?? Promise.resolve()).then(operation, operation);
|
|
10
|
+
const tail = result.then(() => undefined, () => undefined);
|
|
11
|
+
lifecycleTails.set(key, tail);
|
|
12
|
+
void tail.then(() => {
|
|
13
|
+
if (lifecycleTails.get(key) === tail)
|
|
14
|
+
lifecycleTails.delete(key);
|
|
15
|
+
});
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
/** Fail closed on an unreadable deletion journal; missing means no deletions have committed. */
|
|
19
|
+
export async function readDeletedDeploymentIds(directory) {
|
|
20
|
+
let text;
|
|
21
|
+
try {
|
|
22
|
+
text = await readFile(join(directory, 'deleted-deployments.json'), 'utf8');
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
if (error.code === 'ENOENT')
|
|
26
|
+
return new Set();
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
const ids = JSON.parse(text);
|
|
30
|
+
if (!Array.isArray(ids) ||
|
|
31
|
+
ids.some((id) => typeof id !== 'string' || !DEPLOYMENT_ID_PATTERN.test(id))) {
|
|
32
|
+
throw new Error('Invalid deployment deletion journal');
|
|
33
|
+
}
|
|
34
|
+
return new Set(ids);
|
|
35
|
+
}
|
|
36
|
+
/** Rename is the logical commit; retained ID tombstones also reject retries that would resurrect records. */
|
|
37
|
+
export async function commitDeletedDeploymentIds(directory, ids) {
|
|
38
|
+
const deleted = new Set(await readDeletedDeploymentIds(directory));
|
|
39
|
+
for (const id of ids)
|
|
40
|
+
deleted.add(id);
|
|
41
|
+
await mkdir(directory, { recursive: true });
|
|
42
|
+
const path = join(directory, 'deleted-deployments.json');
|
|
43
|
+
const temporary = `${path}.${randomUUID()}.tmp`;
|
|
44
|
+
const file = await open(temporary, 'wx', 0o600);
|
|
45
|
+
try {
|
|
46
|
+
await file.writeFile(JSON.stringify([...deleted].sort()));
|
|
47
|
+
await file.sync();
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
await file.close();
|
|
51
|
+
}
|
|
52
|
+
await rename(temporary, path);
|
|
53
|
+
// Persist both the commit rename and the metadata directory before removing any deployment files.
|
|
54
|
+
for (const parent of [directory, dirname(directory)]) {
|
|
55
|
+
const handle = await open(parent, 'r');
|
|
56
|
+
try {
|
|
57
|
+
await handle.sync();
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
await handle.close();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=json-file-deletion.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ActiveAccessUpdateInput, AppArchiveResult, AppRestorePrecondition, AppRestoreResult, AppSummary, ArtifactStore, DeploymentActivationPrecondition, DeploymentActivationResult, DeploymentListFilter, DeploymentLock, DeploymentLockUpdateResult, DeploymentPolicyPrecondition, DeploymentSummary, DeployRecord, EnvSummary, ProductionEnvironmentChange, TenantAuthConfig, TenantRef } from '../store.js';
|
|
1
|
+
import type { ActiveAccessUpdateInput, AppArchiveResult, AppRestorePrecondition, AppRestoreResult, AppSummary, ArtifactStore, DeploymentActivationPrecondition, DeploymentActivationResult, DeploymentDeleteResult, DeploymentDeleteSelection, DeploymentListFilter, DeploymentLock, DeploymentLockUpdateResult, DeploymentPolicyPrecondition, DeploymentSummary, DeployRecord, EnvSummary, ProductionEnvironmentChange, TenantAuthConfig, TenantRef } from '../store.js';
|
|
2
2
|
/**
|
|
3
3
|
* JSON-file store: one file per deployment at `<dataDir>/deployments/<deploymentId>.json`, written atomically
|
|
4
4
|
* (write a temp file, then `rename` over the target — no partial file is ever read). `deploymentId` is a
|
|
@@ -8,6 +8,7 @@ import type { ActiveAccessUpdateInput, AppArchiveResult, AppRestorePrecondition,
|
|
|
8
8
|
export declare class JsonFileArtifactStore implements ArtifactStore {
|
|
9
9
|
#private;
|
|
10
10
|
constructor(dataDir: string);
|
|
11
|
+
deleteDeployments(ref: TenantRef, selection: DeploymentDeleteSelection): Promise<DeploymentDeleteResult>;
|
|
11
12
|
append(record: DeployRecord, precondition?: DeploymentPolicyPrecondition): Promise<void>;
|
|
12
13
|
get(deploymentId: string): Promise<DeployRecord | undefined>;
|
|
13
14
|
getActiveByTenant(ref: TenantRef): Promise<DeployRecord | undefined>;
|
|
@@ -5,9 +5,11 @@ import { normalizeServerVersion } from '@noodle-borg/module';
|
|
|
5
5
|
import { assertSameAppPackageSnapshot, sanitizeDeployRecordAppPackageSnapshot, } from '../app-package-snapshot.js';
|
|
6
6
|
import { assertCustomerAuthRestorePrecondition, assertUniqueActiveCustomerAuthAudienceBindings, findActiveCustomerAuthAudienceConflict, requiresCustomerAuthProjection, } from '../customer-auth-audience-binding.js';
|
|
7
7
|
import { matchesDeploymentActivation } from '../deployment-activation-precondition.js';
|
|
8
|
+
import { planDeploymentDeletion } from '../deployment-deletion.js';
|
|
8
9
|
import { assertDeploymentActivationUnlocked, assertDeploymentAppendUnlocked, } from '../deployment-lock.js';
|
|
9
10
|
import { assertDeploymentAppendPolicy, assertDeploymentAppendVersion, } from '../deployment-record-version.js';
|
|
10
11
|
import { defaultActiveRecord, sameDeploymentScope, sameTenantRecord, } from '../deployment-versioning.js';
|
|
12
|
+
import { commitDeletedDeploymentIds, readDeletedDeploymentIds, serializeFileLifecycle, } from './json-file-deletion.js';
|
|
11
13
|
import { appArchivedAt, deploymentSummary, matchesDeploymentFilter, paginateAppSummaries, planAppArchive, planAppRestore, planArchivedAppSweep, preserveDeploymentOwnerState, resolveActiveAccessUpdate, resolveProductionEnvironment, summarizeApps, summarizeEnvs, validateDeploymentListFilter, withoutArchiveStamp, } from './records.js';
|
|
12
14
|
import { DEPLOYMENT_ID_PATTERN, validateSlug, validateTenantRef } from './validate.js';
|
|
13
15
|
/**
|
|
@@ -19,11 +21,23 @@ import { DEPLOYMENT_ID_PATTERN, validateSlug, validateTenantRef } from './valida
|
|
|
19
21
|
export class JsonFileArtifactStore {
|
|
20
22
|
#dir;
|
|
21
23
|
#environmentMetadataDir;
|
|
22
|
-
#
|
|
24
|
+
#deletionMetadataDir;
|
|
23
25
|
constructor(dataDir) {
|
|
24
26
|
this.#dir = join(dataDir, 'deployments');
|
|
27
|
+
this.#deletionMetadataDir = join(dataDir, 'deployment-metadata');
|
|
25
28
|
this.#environmentMetadataDir = join(dataDir, 'environment-metadata');
|
|
26
29
|
}
|
|
30
|
+
deleteDeployments(ref, selection) {
|
|
31
|
+
return this.#serializeLifecycle(async () => {
|
|
32
|
+
const result = planDeploymentDeletion(await this.loadAll(), ref, selection);
|
|
33
|
+
if (!result.ok)
|
|
34
|
+
return result;
|
|
35
|
+
await commitDeletedDeploymentIds(this.#deletionMetadataDir, result.deleted.map((record) => record.deploymentId));
|
|
36
|
+
// Logical deletion has committed. Failed physical cleanup remains hidden by the journal on restart.
|
|
37
|
+
await Promise.all(result.deleted.map((record) => rm(join(this.#dir, `${record.deploymentId}.json`), { force: true }).catch(() => undefined)));
|
|
38
|
+
return result;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
27
41
|
append(record, precondition) {
|
|
28
42
|
return this.#serializeLifecycle(() => this.#appendUnlocked(record, precondition));
|
|
29
43
|
}
|
|
@@ -35,6 +49,9 @@ export class JsonFileArtifactStore {
|
|
|
35
49
|
if (!DEPLOYMENT_ID_PATTERN.test(record.deploymentId)) {
|
|
36
50
|
throw new Error(`invalid deploymentId for persistence: "${record.deploymentId}"`);
|
|
37
51
|
}
|
|
52
|
+
if ((await readDeletedDeploymentIds(this.#deletionMetadataDir)).has(record.deploymentId)) {
|
|
53
|
+
throw new Error('Deployment ID has been deleted');
|
|
54
|
+
}
|
|
38
55
|
const records = await this.loadAll();
|
|
39
56
|
assertDeploymentAppendVersion(records, record);
|
|
40
57
|
assertDeploymentAppendPolicy(records, record, precondition);
|
|
@@ -63,6 +80,8 @@ export class JsonFileArtifactStore {
|
|
|
63
80
|
// An invalid id can never be a file we wrote; treat as absent (also closes off any traversal).
|
|
64
81
|
if (!DEPLOYMENT_ID_PATTERN.test(deploymentId))
|
|
65
82
|
return undefined;
|
|
83
|
+
if ((await readDeletedDeploymentIds(this.#deletionMetadataDir)).has(deploymentId))
|
|
84
|
+
return undefined;
|
|
66
85
|
try {
|
|
67
86
|
const text = await readFile(join(this.#dir, `${deploymentId}.json`), 'utf8');
|
|
68
87
|
return sanitizeDeployRecordAppPackageSnapshot(JSON.parse(text));
|
|
@@ -172,9 +191,7 @@ export class JsonFileArtifactStore {
|
|
|
172
191
|
});
|
|
173
192
|
}
|
|
174
193
|
#serializeLifecycle(operation) {
|
|
175
|
-
|
|
176
|
-
this.#lifecycleTail = result.then(() => undefined, () => undefined);
|
|
177
|
-
return result;
|
|
194
|
+
return serializeFileLifecycle(this.#dir, operation);
|
|
178
195
|
}
|
|
179
196
|
async loadAll() {
|
|
180
197
|
let names;
|
|
@@ -199,7 +216,8 @@ export class JsonFileArtifactStore {
|
|
|
199
216
|
// other servers recover. (Visibility of skipped files lands with structured logging, Slice 27.)
|
|
200
217
|
}
|
|
201
218
|
}
|
|
202
|
-
|
|
219
|
+
const deleted = await readDeletedDeploymentIds(this.#deletionMetadataDir);
|
|
220
|
+
return records.filter((record) => !deleted.has(record.deploymentId));
|
|
203
221
|
}
|
|
204
222
|
async listDeployments(filter) {
|
|
205
223
|
const safe = validateDeploymentListFilter(filter);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ArtifactCustomerAuthRouting, HostedPackagedAsset } from '@noodle-borg/compiler';
|
|
2
|
-
import type { OrganizationStore } from '@noodle-borg/control-plane/portable';
|
|
2
|
+
import type { DeploymentDeleteSelection, OrganizationStore, DeploymentDeleteResult as PortableDeploymentDeleteResult } from '@noodle-borg/control-plane/portable';
|
|
3
|
+
export type { DeploymentDeleteSelection } from '@noodle-borg/control-plane/portable';
|
|
3
4
|
import type { OrgMembershipSource } from '@noodle-borg/module';
|
|
4
5
|
import type { SealedSecret } from '@noodle-borg/runtime';
|
|
5
6
|
import type { AccessMode } from '@noodle-borg/transport-http';
|
|
@@ -76,6 +77,7 @@ export interface DeployRecord {
|
|
|
76
77
|
/** Immutable rendered package bytes bound to this exact deployment, when the manifest has a guide. */
|
|
77
78
|
readonly appPackageSnapshot?: AppPackageSnapshotV1;
|
|
78
79
|
}
|
|
80
|
+
export type DeploymentDeleteResult = PortableDeploymentDeleteResult<DeployRecord>;
|
|
79
81
|
export interface DeploymentLockMetadata {
|
|
80
82
|
/** ISO-8601 time the version pointer was locked. */
|
|
81
83
|
readonly lockedAt: string;
|
|
@@ -302,6 +304,8 @@ export interface ControlPlaneStore extends OrganizationStore {
|
|
|
302
304
|
* an earlier deployment without changing the tenant-facing URL.
|
|
303
305
|
*/
|
|
304
306
|
export interface ArtifactStore {
|
|
307
|
+
/** Atomically remove exact deployment history or an inventory-guarded whole version. */
|
|
308
|
+
deleteDeployments(ref: TenantRef, selection: DeploymentDeleteSelection): Promise<DeploymentDeleteResult>;
|
|
305
309
|
append(record: DeployRecord, precondition?: DeploymentPolicyPrecondition): Promise<void>;
|
|
306
310
|
loadAll(): Promise<readonly DeployRecord[]>;
|
|
307
311
|
/**
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
41
41
|
"@noodle-borg/admission-limits": "0.0.0",
|
|
42
|
-
"@noodle-borg/agent-kit": "0.
|
|
42
|
+
"@noodle-borg/agent-kit": "0.104.0",
|
|
43
43
|
"@noodle-borg/app-package": "0.0.0",
|
|
44
44
|
"@noodle-borg/assistant-gateway": "0.0.0",
|
|
45
45
|
"@noodle-borg/auth": "0.0.0",
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** Bind destructive version deletion to the complete inventory the operator confirmed. */
|
|
3
|
+
export declare const deploymentVersionDeleteRequestSchema: z.ZodObject<{
|
|
4
|
+
expectedDeploymentIds: z.ZodArray<z.ZodString>;
|
|
5
|
+
}, z.core.$strict>;
|
|
6
|
+
export type DeploymentVersionDeleteRequest = z.infer<typeof deploymentVersionDeleteRequestSchema>;
|
|
7
|
+
export declare const deploymentDeleteResponseSchema: z.ZodObject<{
|
|
8
|
+
target: z.ZodObject<{
|
|
9
|
+
org: z.ZodString;
|
|
10
|
+
app: z.ZodString;
|
|
11
|
+
env: z.ZodString;
|
|
12
|
+
}, z.core.$strict>;
|
|
13
|
+
ok: z.ZodLiteral<true>;
|
|
14
|
+
deletedDeploymentIds: z.ZodArray<z.ZodString>;
|
|
15
|
+
auditRecorded: z.ZodBoolean;
|
|
16
|
+
}, z.core.$strict>;
|
|
17
|
+
/** Additive response reader for clients that can outlive a service revision. */
|
|
18
|
+
export declare const deploymentDeleteClientResponseSchema: z.ZodObject<{
|
|
19
|
+
target: z.ZodObject<{
|
|
20
|
+
org: z.ZodString;
|
|
21
|
+
app: z.ZodString;
|
|
22
|
+
env: z.ZodString;
|
|
23
|
+
}, z.core.$strip>;
|
|
24
|
+
ok: z.ZodLiteral<true>;
|
|
25
|
+
deletedDeploymentIds: z.ZodArray<z.ZodString>;
|
|
26
|
+
auditRecorded: z.ZodBoolean;
|
|
27
|
+
}, z.core.$strip>;
|
|
28
|
+
export type DeploymentDeleteResponse = z.infer<typeof deploymentDeleteResponseSchema>;
|
|
29
|
+
//# sourceMappingURL=deployment-deletion.d.ts.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const deploymentId = z
|
|
3
|
+
.string()
|
|
4
|
+
.min(1)
|
|
5
|
+
.max(256)
|
|
6
|
+
.regex(/^[a-z0-9-]+$/);
|
|
7
|
+
const ids = z
|
|
8
|
+
.array(deploymentId)
|
|
9
|
+
.min(1)
|
|
10
|
+
.max(10000)
|
|
11
|
+
.refine((values) => new Set(values).size === values.length, 'deployment IDs must be unique');
|
|
12
|
+
const target = {
|
|
13
|
+
org: z.string().min(1),
|
|
14
|
+
app: z.string().min(1),
|
|
15
|
+
env: z.string().min(1),
|
|
16
|
+
};
|
|
17
|
+
/** Bind destructive version deletion to the complete inventory the operator confirmed. */
|
|
18
|
+
export const deploymentVersionDeleteRequestSchema = z.strictObject({ expectedDeploymentIds: ids });
|
|
19
|
+
const result = {
|
|
20
|
+
ok: z.literal(true),
|
|
21
|
+
deletedDeploymentIds: ids,
|
|
22
|
+
auditRecorded: z.boolean(),
|
|
23
|
+
};
|
|
24
|
+
export const deploymentDeleteResponseSchema = z.strictObject({
|
|
25
|
+
...result,
|
|
26
|
+
target: z.strictObject(target),
|
|
27
|
+
});
|
|
28
|
+
/** Additive response reader for clients that can outlive a service revision. */
|
|
29
|
+
export const deploymentDeleteClientResponseSchema = z.object({
|
|
30
|
+
...result,
|
|
31
|
+
target: z.object(target),
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=deployment-deletion.js.map
|
|
@@ -389,6 +389,7 @@ export * from './application-activity.js';
|
|
|
389
389
|
export * from './application-connections.js';
|
|
390
390
|
export * from './application-onboarding.js';
|
|
391
391
|
export * from './billing-catalog.js';
|
|
392
|
+
export * from './deployment-deletion.js';
|
|
392
393
|
export * from './operation-coordination.js';
|
|
393
394
|
export { MIXED_CUSTOMER_AUTH_FEATURE_VERSION, type ServiceInfoClientResponse, type ServiceInfoResponse, serviceInfoClientResponseSchema, serviceInfoResponseSchema, } from './service-info.js';
|
|
394
395
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -228,6 +228,7 @@ export * from './application-activity.js';
|
|
|
228
228
|
export * from './application-connections.js';
|
|
229
229
|
export * from './application-onboarding.js';
|
|
230
230
|
export * from './billing-catalog.js';
|
|
231
|
+
export * from './deployment-deletion.js';
|
|
231
232
|
export * from './operation-coordination.js';
|
|
232
233
|
export { MIXED_CUSTOMER_AUTH_FEATURE_VERSION, serviceInfoClientResponseSchema, serviceInfoResponseSchema, } from './service-info.js';
|
|
233
234
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noodleseed/one",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.169.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",
|
|
@@ -235,7 +235,7 @@
|
|
|
235
235
|
"@modelcontextprotocol/client": "2.0.0",
|
|
236
236
|
"@modelcontextprotocol/server": "2.0.0",
|
|
237
237
|
"@noodle-borg/admission-limits": "0.0.0",
|
|
238
|
-
"@noodle-borg/agent-kit": "0.
|
|
238
|
+
"@noodle-borg/agent-kit": "0.104.0",
|
|
239
239
|
"@noodle-borg/app-audit": "0.0.0",
|
|
240
240
|
"@noodle-borg/app-package": "0.0.0",
|
|
241
241
|
"@noodle-borg/assistant-gateway": "0.0.0",
|