@jini-ai/cms 0.3.11 → 0.4.1
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/CHANGELOG.md +59 -0
- package/README.md +47 -19
- package/dist/content-types/agent-tools.d.ts +3 -56
- package/dist/content-types/agent-tools.js +22 -6
- package/dist/content-types/cleanup.d.ts +18 -13
- package/dist/content-types/cleanup.js +16 -11
- package/dist/content-types/errors.d.ts +57 -24
- package/dist/content-types/errors.js +56 -39
- package/dist/content-types/field-defs.d.ts +8 -4
- package/dist/content-types/field-defs.js +19 -14
- package/dist/content-types/index-provisioning.d.ts +61 -47
- package/dist/content-types/index-provisioning.js +90 -66
- package/dist/content-types/index.d.ts +4 -3
- package/dist/content-types/lifecycle-dispatch.d.ts +11 -5
- package/dist/content-types/lifecycle-dispatch.js +5 -4
- package/dist/content-types/lifecycle.d.ts +23 -18
- package/dist/content-types/lifecycle.js +71 -64
- package/dist/content-types/repo.memory.d.ts +5 -4
- package/dist/content-types/repo.memory.js +3 -2
- package/dist/content-types/tool-registrations.d.ts +6 -8
- package/dist/content-types/tool-registrations.js +24 -28
- package/dist/content-types/types.d.ts +17 -13
- package/dist/content-types/types.js +11 -5
- package/dist/content-types/write-service.d.ts +20 -22
- package/dist/content-types/write-service.js +78 -75
- package/dist/core/authorization.d.ts +15 -0
- package/dist/core/authorization.js +2 -0
- package/dist/core/commands/change-set.d.ts +15 -7
- package/dist/core/commands/command.d.ts +45 -26
- package/dist/core/commands/command.js +73 -63
- package/dist/core/entity-liveness.d.ts +11 -7
- package/dist/core/entity-liveness.js +5 -4
- package/dist/core/index.d.ts +12 -5
- package/dist/core/index.js +10 -4
- package/dist/core/ports.d.ts +25 -24
- package/dist/core/ports.js +1 -0
- package/dist/core/tools/args.d.ts +49 -0
- package/dist/core/tools/args.js +46 -0
- package/dist/core/tools/index.d.ts +3 -0
- package/dist/core/tools/index.js +3 -0
- package/dist/entries/agent-tools.d.ts +1 -73
- package/dist/entries/agent-tools.js +19 -13
- package/dist/entries/errors.d.ts +28 -14
- package/dist/entries/errors.js +17 -11
- package/dist/entries/field-validation.d.ts +5 -3
- package/dist/entries/field-validation.js +7 -5
- package/dist/entries/index.d.ts +2 -2
- package/dist/entries/lifecycle-dispatch.d.ts +5 -2
- package/dist/entries/lifecycle-dispatch.js +2 -1
- package/dist/entries/list.d.ts +4 -2
- package/dist/entries/list.js +4 -3
- package/dist/entries/repo.memory.d.ts +12 -10
- package/dist/entries/repo.memory.js +11 -10
- package/dist/entries/tool-registrations.d.ts +6 -8
- package/dist/entries/tool-registrations.js +42 -41
- package/dist/entries/types.d.ts +0 -7
- package/dist/entries/write-service.d.ts +28 -29
- package/dist/entries/write-service.js +114 -105
- package/dist/http/settings/cms-adapter.d.ts +20 -0
- package/dist/http/settings/cms-adapter.js +124 -0
- package/dist/http/settings/contracts.d.ts +135 -0
- package/dist/http/settings/contracts.js +2 -0
- package/dist/http/settings/http.d.ts +10 -0
- package/dist/http/settings/http.js +211 -0
- package/dist/http/settings/index.d.ts +5 -0
- package/dist/http/settings/index.js +4 -0
- package/dist/http/settings/shared.d.ts +68 -0
- package/dist/http/settings/shared.js +54 -0
- package/dist/http/settings/stream.d.ts +24 -0
- package/dist/http/settings/stream.js +147 -0
- package/dist/media/agent-tools.d.ts +1 -66
- package/dist/media/agent-tools.js +5 -1
- package/dist/media/blob-gc-lock.d.ts +6 -2
- package/dist/media/blob-gc-lock.js +4 -2
- package/dist/media/blob-gc.d.ts +64 -51
- package/dist/media/blob-gc.js +62 -52
- package/dist/media/blob-key.d.ts +1 -1
- package/dist/media/content-type-sniffer.d.ts +3 -1
- package/dist/media/content-type-sniffer.js +1 -1
- package/dist/media/html-attributes.d.ts +9 -5
- package/dist/media/html-attributes.js +8 -6
- package/dist/media/image-transformer.js +1 -1
- package/dist/media/image-transformer.sharp.d.ts +6 -0
- package/dist/media/image-transformer.sharp.js +12 -6
- package/dist/media/import/fetch-image.d.ts +24 -0
- package/dist/media/import/fetch-image.js +137 -0
- package/dist/media/import/index.d.ts +3 -0
- package/dist/media/import/index.js +3 -0
- package/dist/media/import/ports.d.ts +38 -0
- package/dist/media/index.d.ts +7 -1
- package/dist/media/index.js +1 -0
- package/dist/media/media-service.d.ts +14 -10
- package/dist/media/media-service.js +57 -52
- package/dist/media/ports.d.ts +3 -2
- package/dist/media/rendition-service.d.ts +3 -3
- package/dist/media/rendition-service.js +38 -37
- package/dist/media/repo.memory.d.ts +18 -7
- package/dist/media/repo.memory.js +12 -6
- package/dist/media/tool-registrations.d.ts +16 -15
- package/dist/media/tool-registrations.js +84 -72
- package/dist/media/transform-lock.d.ts +22 -12
- package/dist/media/transform-lock.js +14 -13
- package/dist/media/transform-registry.d.ts +3 -3
- package/dist/media/transform-registry.js +19 -18
- package/dist/media/transform-types.d.ts +8 -3
- package/dist/media/transform-types.js +10 -5
- package/dist/media/types.d.ts +21 -4
- package/dist/media/types.js +15 -2
- package/dist/navigation/agent-tools.d.ts +1 -80
- package/dist/navigation/agent-tools.js +15 -3
- package/dist/navigation/contracts.d.ts +1 -1
- package/dist/navigation/index.d.ts +2 -2
- package/dist/navigation/menu-service.d.ts +57 -40
- package/dist/navigation/menu-service.js +80 -69
- package/dist/navigation/ports.d.ts +1 -1
- package/dist/navigation/read-model.d.ts +3 -1
- package/dist/navigation/read-model.js +2 -2
- package/dist/navigation/reconcile.d.ts +2 -2
- package/dist/navigation/reconcile.js +2 -1
- package/dist/navigation/repo.memory.d.ts +7 -3
- package/dist/navigation/repo.memory.js +4 -2
- package/dist/navigation/resolver.d.ts +4 -1
- package/dist/navigation/resolver.js +1 -1
- package/dist/navigation/tool-registrations.d.ts +6 -8
- package/dist/navigation/tool-registrations.js +44 -42
- package/dist/navigation/types.d.ts +1 -1
- package/dist/presentation/presentation.d.ts +11 -3
- package/dist/presentation/presentation.js +13 -6
- package/dist/presentation/repo.memory.d.ts +6 -2
- package/dist/presentation/repo.memory.js +3 -2
- package/dist/settings/agent-tools.d.ts +2 -75
- package/dist/settings/agent-tools.js +49 -45
- package/dist/settings/agent-value-write-tools.d.ts +22 -0
- package/dist/settings/agent-value-write-tools.js +154 -0
- package/dist/settings/agent-writable-preferences.js +8 -20
- package/dist/settings/agent-write-denylist.d.ts +19 -0
- package/dist/settings/agent-write-denylist.js +15 -0
- package/dist/settings/change-feed.d.ts +11 -2
- package/dist/settings/change-feed.js +4 -4
- package/dist/settings/definitions-dispatch.d.ts +8 -3
- package/dist/settings/definitions-dispatch.js +5 -5
- package/dist/settings/dictionaries/index.d.ts +5 -2
- package/dist/settings/dictionaries/index.js +2 -2
- package/dist/settings/dictionaries/settings-dialog.ar.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.bn.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.de.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.es.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.fa.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.fr.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.hi.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.hu.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.id.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.it.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.ja.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.ko.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.pl.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.pt-BR.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.ru.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.th.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.tr.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.uk.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.ur.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.zh-CN.js +0 -1
- package/dist/settings/dictionaries/settings-dialog.zh-TW.js +0 -1
- package/dist/settings/ensure-definitions.d.ts +5 -5
- package/dist/settings/errors.d.ts +7 -1
- package/dist/settings/errors.js +7 -1
- package/dist/settings/index.d.ts +4 -1
- package/dist/settings/index.js +1 -0
- package/dist/settings/ports.d.ts +6 -5
- package/dist/settings/principal-lookup.d.ts +9 -0
- package/dist/settings/principal-lookup.js +2 -0
- package/dist/settings/purge-service.d.ts +5 -4
- package/dist/settings/purge-service.js +3 -2
- package/dist/settings/settings.d.ts +22 -7
- package/dist/settings/settings.js +47 -26
- package/dist/settings/tool-registrations.d.ts +27 -32
- package/dist/settings/tool-registrations.js +66 -56
- package/dist/settings/types.d.ts +1 -1
- package/dist/settings/ui-tab-definitions.d.ts +1 -1
- package/dist/settings/write-service.d.ts +32 -26
- package/dist/settings/write-service.js +26 -20
- package/dist/taxonomy/agent-tools.d.ts +1 -66
- package/dist/taxonomy/agent-tools.js +25 -15
- package/dist/taxonomy/content-lookup.js +1 -1
- package/dist/taxonomy/index.d.ts +2 -2
- package/dist/taxonomy/merge-term.d.ts +7 -4
- package/dist/taxonomy/merge-term.js +7 -5
- package/dist/taxonomy/repo.memory.d.ts +42 -19
- package/dist/taxonomy/repo.memory.js +14 -12
- package/dist/taxonomy/validation-chain.d.ts +39 -18
- package/dist/taxonomy/validation-chain.js +35 -25
- package/dist/taxonomy/write-service.d.ts +103 -44
- package/dist/taxonomy/write-service.js +221 -179
- package/dist/trash/adapters/record-store.d.ts +52 -0
- package/dist/trash/adapters/record-store.js +36 -0
- package/dist/trash/cursor.d.ts +20 -0
- package/dist/trash/cursor.js +36 -0
- package/dist/trash/follow-ups.d.ts +76 -0
- package/dist/trash/follow-ups.js +46 -0
- package/dist/trash/index.d.ts +8 -0
- package/dist/trash/index.js +8 -0
- package/dist/trash/ports.d.ts +308 -0
- package/dist/trash/ports.js +2 -0
- package/dist/trash/repo.memory.d.ts +50 -0
- package/dist/trash/repo.memory.js +114 -0
- package/dist/trash/sweeper.d.ts +77 -0
- package/dist/trash/sweeper.js +127 -0
- package/dist/trash/write-service.d.ts +100 -0
- package/dist/trash/write-service.js +242 -0
- package/dist/workspace/agent-tools.d.ts +1 -59
- package/dist/workspace/agent-tools.js +27 -12
- package/dist/workspace/create.d.ts +31 -6
- package/dist/workspace/create.js +18 -5
- package/dist/workspace/delete.d.ts +18 -13
- package/dist/workspace/delete.js +20 -12
- package/dist/workspace/index.d.ts +1 -1
- package/dist/workspace/repo.memory.d.ts +19 -4
- package/dist/workspace/repo.memory.js +26 -4
- package/dist/workspace/tool-registrations.d.ts +2 -2
- package/dist/workspace/tool-registrations.js +13 -13
- package/dist/workspace/update.d.ts +6 -5
- package/dist/workspace/update.js +9 -8
- package/package.json +44 -38
- package/dist/core/tools/registration-kit.d.ts +0 -346
- package/dist/core/tools/registration-kit.js +0 -426
- package/dist/identity/admin-crud-service.d.ts +0 -280
- package/dist/identity/admin-crud-service.js +0 -468
- package/dist/identity/agent-tool-input.d.ts +0 -58
- package/dist/identity/agent-tool-input.js +0 -126
- package/dist/identity/agent-tools.d.ts +0 -101
- package/dist/identity/agent-tools.js +0 -290
- package/dist/identity/auth-service.d.ts +0 -118
- package/dist/identity/auth-service.js +0 -170
- package/dist/identity/authorize.d.ts +0 -90
- package/dist/identity/authorize.js +0 -94
- package/dist/identity/grant-service.d.ts +0 -198
- package/dist/identity/grant-service.js +0 -361
- package/dist/identity/hasher.d.ts +0 -39
- package/dist/identity/hasher.js +0 -39
- package/dist/identity/index.d.ts +0 -62
- package/dist/identity/index.js +0 -54
- package/dist/identity/password-policy.d.ts +0 -57
- package/dist/identity/password-policy.js +0 -66
- package/dist/identity/permission-migrations.d.ts +0 -86
- package/dist/identity/permission-migrations.js +0 -67
- package/dist/identity/permissions.d.ts +0 -35
- package/dist/identity/permissions.js +0 -603
- package/dist/identity/ports.d.ts +0 -201
- package/dist/identity/repo.memory.d.ts +0 -164
- package/dist/identity/repo.memory.js +0 -224
- package/dist/identity/seed.d.ts +0 -54
- package/dist/identity/seed.js +0 -429
- package/dist/identity/tool-registrations.d.ts +0 -50
- package/dist/identity/tool-registrations.js +0 -419
- package/dist/identity/types.d.ts +0 -185
- package/dist/identity/types.js +0 -64
- package/dist/identity/username.d.ts +0 -12
- package/dist/identity/username.js +0 -14
- package/dist/server/index.d.ts +0 -28
- package/dist/server/index.js +0 -28
- /package/dist/{identity → media/import}/ports.js +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { adaptLegacyAuthorize } from "../core/tools/index.js";
|
|
1
2
|
/**
|
|
2
3
|
* @file Navigation's (Menus') half of the agent-tool authorization wiring: maps `agent-tools.ts`'s five
|
|
3
4
|
* catalog entries onto `menu-service.ts`'s read/create/update/assign operations, as
|
|
@@ -10,10 +11,11 @@
|
|
|
10
11
|
* single evaluation for these tools, located where the real route locates it.
|
|
11
12
|
*/
|
|
12
13
|
import { ToolInputError } from "@jini-ai/core";
|
|
13
|
-
import { buildDomainRegistrations, indexCatalogById, requireInputRecord, requireNumber, requireString,
|
|
14
|
+
import { buildDomainRegistrations, indexCatalogById, requireInputRecord, requireNumber, requireString, withSchemaOnRejection } from "@jini-ai/core";
|
|
15
|
+
import { requireToolPermission } from "../core/tools/index.js";
|
|
14
16
|
import { menusAgentToolCatalog } from "./agent-tools.js";
|
|
15
17
|
import { assignLocation, createMenu, MenuNotFoundError, MenuValidationError, updateMenuTree } from "./menu-service.js";
|
|
16
|
-
const CATALOG_BY_ID = indexCatalogById(menusAgentToolCatalog);
|
|
18
|
+
const CATALOG_BY_ID = indexCatalogById({ catalog: menusAgentToolCatalog });
|
|
17
19
|
/**
|
|
18
20
|
* This wiring layer's OWN risk classification, authored from what each handler below actually
|
|
19
21
|
* calls. See `DerivedRiskByToolId` in the kit for why it is independent of the catalog's own
|
|
@@ -62,65 +64,65 @@ function menusDeps(routeDeps) {
|
|
|
62
64
|
export function buildMenusRegistrations(routeDeps) {
|
|
63
65
|
const handlers = {
|
|
64
66
|
menus_list_menus: async (ctx) => {
|
|
65
|
-
await requireToolPermission(routeDeps,
|
|
67
|
+
await requireToolPermission({ authorize: adaptLegacyAuthorize({ authorize: routeDeps.authorize }), workspaceId: routeDeps.workspaceId, principalId: ctx.principal.id, permission: "admin.menus.read" }, { entityType: "menu" });
|
|
66
68
|
const menus = await routeDeps.menuRepo.list({ workspaceId: routeDeps.workspaceId });
|
|
67
69
|
return { menus: menus.map(toMenuToolView) };
|
|
68
70
|
},
|
|
69
71
|
menus_get_menu: async (ctx) => {
|
|
70
|
-
const menuId = requireString(requireInputRecord(ctx.input), "menuId");
|
|
71
|
-
await requireToolPermission(routeDeps,
|
|
72
|
+
const menuId = requireString({ input: requireInputRecord({ input: ctx.input }), key: "menuId" });
|
|
73
|
+
await requireToolPermission({ authorize: adaptLegacyAuthorize({ authorize: routeDeps.authorize }), workspaceId: routeDeps.workspaceId, principalId: ctx.principal.id, permission: "admin.menus.read" }, { entityType: "menu", entityId: menuId });
|
|
72
74
|
const menu = await routeDeps.menuRepo.findById({ workspaceId: routeDeps.workspaceId, id: menuId });
|
|
73
75
|
if (!menu)
|
|
74
|
-
throw new MenuNotFoundError(`menu '${menuId}' was not found`);
|
|
76
|
+
throw new MenuNotFoundError({ message: `menu '${menuId}' was not found` });
|
|
75
77
|
return { menu: toMenuToolView(menu) };
|
|
76
78
|
},
|
|
77
79
|
menus_create_menu: async (ctx) => {
|
|
78
|
-
const input = requireInputRecord(ctx.input);
|
|
79
|
-
await requireToolPermission(routeDeps,
|
|
80
|
+
const input = requireInputRecord({ input: ctx.input });
|
|
81
|
+
await requireToolPermission({ authorize: adaptLegacyAuthorize({ authorize: routeDeps.authorize }), workspaceId: routeDeps.workspaceId, principalId: ctx.principal.id, permission: "admin.menus.create" }, { entityType: "menu" });
|
|
80
82
|
if (input.items !== undefined && !Array.isArray(input.items)) {
|
|
81
|
-
throw new ToolInputError("'items' must be an array of nav items");
|
|
83
|
+
throw new ToolInputError({ message: "'items' must be an array of nav items" });
|
|
82
84
|
}
|
|
83
|
-
return withSchemaOnRejection({ toolId: "menus_create_menu", catalog: CATALOG_BY_ID, isShapeRejection:
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
85
|
+
return withSchemaOnRejection({ toolId: "menus_create_menu", catalog: CATALOG_BY_ID, isShapeRejection: ({ error }) => isMenusShapeRejection(error), fn: async () => {
|
|
86
|
+
const { menu } = await createMenu({
|
|
87
|
+
deps: menusDeps(routeDeps),
|
|
88
|
+
input: {
|
|
89
|
+
workspaceId: routeDeps.workspaceId,
|
|
90
|
+
title: requireString({ input: input, key: "title" }),
|
|
91
|
+
slug: requireString({ input: input, key: "slug" }),
|
|
92
|
+
items: Array.isArray(input.items) ? input.items : undefined,
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
return { menu: toMenuToolView(menu) };
|
|
96
|
+
} });
|
|
95
97
|
},
|
|
96
98
|
menus_update_menu_tree: async (ctx) => {
|
|
97
|
-
const input = requireInputRecord(ctx.input);
|
|
98
|
-
const menuId = requireString(input, "menuId");
|
|
99
|
-
await requireToolPermission(routeDeps,
|
|
99
|
+
const input = requireInputRecord({ input: ctx.input });
|
|
100
|
+
const menuId = requireString({ input: input, key: "menuId" });
|
|
101
|
+
await requireToolPermission({ authorize: adaptLegacyAuthorize({ authorize: routeDeps.authorize }), workspaceId: routeDeps.workspaceId, principalId: ctx.principal.id, permission: "admin.menus.update" }, { entityType: "menu", entityId: menuId });
|
|
100
102
|
if (!Array.isArray(input.items))
|
|
101
103
|
throw new Error("'items' (array) is required");
|
|
102
|
-
return withSchemaOnRejection({ toolId: "menus_update_menu_tree", catalog: CATALOG_BY_ID, isShapeRejection:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
104
|
+
return withSchemaOnRejection({ toolId: "menus_update_menu_tree", catalog: CATALOG_BY_ID, isShapeRejection: ({ error }) => isMenusShapeRejection(error), fn: async () => {
|
|
105
|
+
const { menu } = await updateMenuTree({
|
|
106
|
+
deps: menusDeps(routeDeps),
|
|
107
|
+
input: {
|
|
108
|
+
workspaceId: routeDeps.workspaceId,
|
|
109
|
+
id: menuId,
|
|
110
|
+
expectedVersion: requireNumber({ input: input, key: "expectedVersion" }),
|
|
111
|
+
title: typeof input.title === "string" ? input.title : undefined,
|
|
112
|
+
slug: typeof input.slug === "string" ? input.slug : undefined,
|
|
113
|
+
items: input.items,
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
return { menu: toMenuToolView(menu) };
|
|
117
|
+
} });
|
|
116
118
|
},
|
|
117
119
|
menus_assign_location: async (ctx) => {
|
|
118
|
-
const input = requireInputRecord(ctx.input);
|
|
119
|
-
const menuId = requireString(input, "menuId");
|
|
120
|
-
await requireToolPermission(routeDeps,
|
|
120
|
+
const input = requireInputRecord({ input: ctx.input });
|
|
121
|
+
const menuId = requireString({ input: input, key: "menuId" });
|
|
122
|
+
await requireToolPermission({ authorize: adaptLegacyAuthorize({ authorize: routeDeps.authorize }), workspaceId: routeDeps.workspaceId, principalId: ctx.principal.id, permission: "admin.menus.assign" }, { entityType: "menu", entityId: menuId });
|
|
121
123
|
const { menu, binding, displacedMenu } = await assignLocation({
|
|
122
124
|
deps: { ...menusDeps(routeDeps), bindingRepo: routeDeps.navLocationBindingRepo },
|
|
123
|
-
input: { workspaceId: routeDeps.workspaceId, menuId, locationKey: requireString(input, "locationKey") },
|
|
125
|
+
input: { workspaceId: routeDeps.workspaceId, menuId, locationKey: requireString({ input: input, key: "locationKey" }) },
|
|
124
126
|
});
|
|
125
127
|
return {
|
|
126
128
|
menu: toMenuToolView(menu),
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* this library introduces; the entries repo, revisions, `entry_refs`, and the command
|
|
23
23
|
* gateway are reused unchanged from the generic entries model.
|
|
24
24
|
*/
|
|
25
|
-
import type { ISODateTime, JsonObject, UUID } from "
|
|
25
|
+
import type { ISODateTime, JsonObject, UUID } from "@jini-ai/core/primitives";
|
|
26
26
|
/**
|
|
27
27
|
* `menu` ships as a **seeded content-type registry row**, like
|
|
28
28
|
* `post`/`page`/`media`. Core may special-case it in admin UI/rendering, never
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Clock, UUID } from "@jini-ai/core/primitives";
|
|
2
2
|
/**
|
|
3
3
|
* @file Presentation settings — the active-theme identity of a workspace.
|
|
4
4
|
*
|
|
@@ -22,7 +22,9 @@ export interface PresentationSettingsRecord {
|
|
|
22
22
|
updatedAt: string;
|
|
23
23
|
}
|
|
24
24
|
export interface PresentationSettingsRepoPort {
|
|
25
|
-
findByWorkspaceId(workspaceId
|
|
25
|
+
findByWorkspaceId({ workspaceId }: {
|
|
26
|
+
workspaceId: UUID;
|
|
27
|
+
}): Promise<PresentationSettingsRecord | null>;
|
|
26
28
|
save(record: PresentationSettingsRecord): Promise<void>;
|
|
27
29
|
/**
|
|
28
30
|
* Every row across every workspace, for the one-time
|
|
@@ -43,7 +45,7 @@ export interface GetPresentationSettingsRequired {
|
|
|
43
45
|
};
|
|
44
46
|
}
|
|
45
47
|
export interface SetActiveThemeDeps {
|
|
46
|
-
clock:
|
|
48
|
+
clock: Clock;
|
|
47
49
|
repo: PresentationSettingsRepoPort;
|
|
48
50
|
/** Discovered valid theme ids; falls back to ALLOWED_THEME_IDS when absent. */
|
|
49
51
|
availableThemeIds?: readonly string[] | undefined;
|
|
@@ -58,8 +60,14 @@ export interface SetActiveThemeRequired {
|
|
|
58
60
|
export interface PresentationOptional {
|
|
59
61
|
}
|
|
60
62
|
export declare class PresentationSettingsNotFoundError extends Error {
|
|
63
|
+
constructor({ message }: {
|
|
64
|
+
message: string;
|
|
65
|
+
}, optionalArgs?: ErrorOptions);
|
|
61
66
|
}
|
|
62
67
|
export declare class PresentationSettingsValidationError extends Error {
|
|
68
|
+
constructor({ message }: {
|
|
69
|
+
message: string;
|
|
70
|
+
}, optionalArgs?: ErrorOptions);
|
|
63
71
|
}
|
|
64
72
|
export declare function getPresentationSettings(required: GetPresentationSettingsRequired, _optional?: PresentationOptional): Promise<{
|
|
65
73
|
settings: PresentationSettingsRecord;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { nowIso as kernelNowIso } from "@jini-ai/core/primitives";
|
|
1
2
|
/**
|
|
2
3
|
* @file Presentation settings — the active-theme identity of a workspace.
|
|
3
4
|
*
|
|
@@ -14,13 +15,19 @@
|
|
|
14
15
|
*/
|
|
15
16
|
export const ALLOWED_THEME_IDS = ["paper", "atlas", "glassmorphic"];
|
|
16
17
|
export class PresentationSettingsNotFoundError extends Error {
|
|
18
|
+
constructor({ message }, optionalArgs = {}) {
|
|
19
|
+
super(message, optionalArgs);
|
|
20
|
+
}
|
|
17
21
|
}
|
|
18
22
|
export class PresentationSettingsValidationError extends Error {
|
|
23
|
+
constructor({ message }, optionalArgs = {}) {
|
|
24
|
+
super(message, optionalArgs);
|
|
25
|
+
}
|
|
19
26
|
}
|
|
20
27
|
export async function getPresentationSettings(required, _optional = {}) {
|
|
21
|
-
const settings = await required.deps.repo.findByWorkspaceId(required.input.workspaceId);
|
|
28
|
+
const settings = await required.deps.repo.findByWorkspaceId({ workspaceId: required.input.workspaceId });
|
|
22
29
|
if (!settings) {
|
|
23
|
-
throw new PresentationSettingsNotFoundError(`presentation settings for workspace '${required.input.workspaceId}' were not found`);
|
|
30
|
+
throw new PresentationSettingsNotFoundError({ message: `presentation settings for workspace '${required.input.workspaceId}' were not found` });
|
|
24
31
|
}
|
|
25
32
|
return {
|
|
26
33
|
settings,
|
|
@@ -31,16 +38,16 @@ export async function setActiveTheme(required, _optional = {}) {
|
|
|
31
38
|
const { deps, input } = required;
|
|
32
39
|
const allowed = deps.availableThemeIds ?? ALLOWED_THEME_IDS;
|
|
33
40
|
if (!allowed.includes(input.activeThemeId)) {
|
|
34
|
-
throw new PresentationSettingsValidationError(`theme '${input.activeThemeId}' is not supported`);
|
|
41
|
+
throw new PresentationSettingsValidationError({ message: `theme '${input.activeThemeId}' is not supported` });
|
|
35
42
|
}
|
|
36
|
-
const existing = await deps.repo.findByWorkspaceId(input.workspaceId);
|
|
43
|
+
const existing = await deps.repo.findByWorkspaceId({ workspaceId: input.workspaceId });
|
|
37
44
|
if (!existing) {
|
|
38
|
-
throw new PresentationSettingsNotFoundError(`presentation settings for workspace '${input.workspaceId}' were not found`);
|
|
45
|
+
throw new PresentationSettingsNotFoundError({ message: `presentation settings for workspace '${input.workspaceId}' were not found` });
|
|
39
46
|
}
|
|
40
47
|
const settings = {
|
|
41
48
|
...existing,
|
|
42
49
|
activeThemeId: input.activeThemeId,
|
|
43
|
-
updatedAt: deps.clock
|
|
50
|
+
updatedAt: kernelNowIso({ clock: deps.clock }),
|
|
44
51
|
};
|
|
45
52
|
await deps.repo.save(settings);
|
|
46
53
|
return {
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import type { PresentationSettingsRecord, PresentationSettingsRepoPort } from "./presentation.js";
|
|
2
2
|
export declare class InMemoryPresentationSettingsRepo implements PresentationSettingsRepoPort {
|
|
3
3
|
private rows;
|
|
4
|
-
constructor(
|
|
5
|
-
|
|
4
|
+
constructor(requiredArgs: Record<string, never>, optionalArgs?: {
|
|
5
|
+
initialRows?: PresentationSettingsRecord[];
|
|
6
|
+
});
|
|
7
|
+
findByWorkspaceId({ workspaceId }: {
|
|
8
|
+
workspaceId: string;
|
|
9
|
+
}): Promise<PresentationSettingsRecord | null>;
|
|
6
10
|
save(record: PresentationSettingsRecord): Promise<void>;
|
|
7
11
|
listAll(): Promise<PresentationSettingsRecord[]>;
|
|
8
12
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
export class InMemoryPresentationSettingsRepo {
|
|
2
2
|
rows;
|
|
3
|
-
constructor(
|
|
3
|
+
constructor(requiredArgs, optionalArgs = {}) {
|
|
4
|
+
const { initialRows = [] } = optionalArgs;
|
|
4
5
|
this.rows = [...initialRows];
|
|
5
6
|
}
|
|
6
|
-
async findByWorkspaceId(workspaceId) {
|
|
7
|
+
async findByWorkspaceId({ workspaceId }) {
|
|
7
8
|
return this.rows.find((row) => row.workspaceId === workspaceId) ?? null;
|
|
8
9
|
}
|
|
9
10
|
async save(record) {
|
|
@@ -1,79 +1,6 @@
|
|
|
1
|
+
import type { AgentToolDefinition } from "@jini-ai/core";
|
|
1
2
|
/**
|
|
2
|
-
*
|
|
3
|
-
* convention every other domain catalog in this package already uses.
|
|
4
|
-
*
|
|
5
|
-
* Purpose:
|
|
6
|
-
* A static, in-process catalog describing every agent-callable tool this domain exposes. Settings
|
|
7
|
-
* is, by design, a broad key/value surface — a typical human admin screen for it is an uncurated,
|
|
8
|
-
* free-text editor: the operator types ANY namespace string to load it and edits values through a
|
|
9
|
-
* raw-JSON textarea, with no schema-exposing endpoint feeding a typed control. There is no fixed,
|
|
10
|
-
* curated list of named settings on that surface to wire tools against.
|
|
11
|
-
*
|
|
12
|
-
* That disqualifies every GENERIC write in this domain from being wired here:
|
|
13
|
-
* - `SETTINGS_SET`/`SETTINGS_CLEAR` let a caller write/clear the value of any registered
|
|
14
|
-
* namespace+key at any scope it can name — exactly the generic "set any setting key" tool this
|
|
15
|
-
* dispatch's brief prohibits outright, regardless of the write path's own schema validation
|
|
16
|
-
* (validation constrains VALUE shape, not WHICH key can be targeted).
|
|
17
|
-
*
|
|
18
|
-
* One curated write IS wired, and it is not a weaker `settings_set`: `ui-tab-definitions.ts`
|
|
19
|
-
* registers a fixed, statically-declared list, because the settings-dialog tabs need named keys to
|
|
20
|
-
* bind to. `SETTINGS_SET_UI_PREFERENCE` below wires a seven-key subset of that list
|
|
21
|
-
* (`agent-writable-preferences.ts`):
|
|
22
|
-
*
|
|
23
|
-
* - Its `setting` parameter is a JSON Schema `enum`, so WHICH key is targeted is constrained by
|
|
24
|
-
* the same mechanism as everything else — the exact gap the paragraph above identifies. The
|
|
25
|
-
* ledger's registered definition schema still bounds the VALUE, so both halves are covered.
|
|
26
|
-
* - It exposes no `scope` and no `principalId`. Every write is `scope: "user"` against the
|
|
27
|
-
* caller's own principal, which derives `settings.user.self.write` — the narrowest write grant
|
|
28
|
-
* in the system — and makes writing another operator's preferences unrepresentable rather than
|
|
29
|
-
* merely unauthorized.
|
|
30
|
-
* - The keys are per-operator display preferences (locale, theme, accent, notification sounds),
|
|
31
|
-
* each reversible in one call and visible in the admin UI the moment it changes.
|
|
32
|
-
*
|
|
33
|
-
* The generic setter stays excluded, permanently and for its original reason. Nothing above is
|
|
34
|
-
* evidence that the other three writes may now be wired:
|
|
35
|
-
* - `SETTINGS_RESET` is broader still: a single call clears every value in an operator-named
|
|
36
|
-
* namespace at a scope — typically described in a host's own confirmation dialog as
|
|
37
|
-
* irreversible.
|
|
38
|
-
* - `SETTINGS_REGISTER_DEFINITIONS` is schema-level, not value-level: it can rename/retype/
|
|
39
|
-
* deprecate/tombstone the DEFINITION a key resolves through, changing how every existing stored
|
|
40
|
-
* value for that key is interpreted platform-wide.
|
|
41
|
-
*
|
|
42
|
-
* Reads are a different risk class and are wired: `SETTINGS_LIST_DEFINITIONS`/
|
|
43
|
-
* `SETTINGS_GET_EFFECTIVE`/`SETTINGS_GET_RAW` cannot mutate anything, are gated by the same real
|
|
44
|
-
* `authorize()` permissions an admin UI's own reads use (including the cross-principal
|
|
45
|
-
* `settings.user.read` check), and cannot surface a secret value even in principle —
|
|
46
|
-
* `settings.ts`'s `validateDefinitionInput` unconditionally refuses `secret:true` at registration
|
|
47
|
-
* time (REQ-09/INV-08), so no secret setting can exist in this library's current state to leak.
|
|
48
|
-
*
|
|
49
|
-
* How it relates to a host:
|
|
50
|
-
* A host's tool-registration layer consumes this catalog to decide which tool names an agent
|
|
51
|
-
* session may even see; `authorize()` enforces the actual permission checks at call time — this
|
|
52
|
-
* module only declares the catalog shape, it performs no I/O and no enforcement itself.
|
|
53
|
-
*
|
|
54
|
-
* Architectural role:
|
|
55
|
-
* `settings` domain logic. Depends only on its own sibling `agent-writable-preferences.ts` (for
|
|
56
|
-
* the curated write's enum) — no I/O, no enforcement.
|
|
57
|
-
*/
|
|
58
|
-
export type AgentToolSideEffect = "none" | "mutates-durable-state" | "mints-token";
|
|
59
|
-
export interface AgentToolDefinition {
|
|
60
|
-
name: string;
|
|
61
|
-
description: string;
|
|
62
|
-
sideEffects: AgentToolSideEffect;
|
|
63
|
-
authorization: {
|
|
64
|
-
permission: string;
|
|
65
|
-
};
|
|
66
|
-
/**
|
|
67
|
-
* JSON Schema for this tool's `input`, published to the model via `ToolDescriptor.inputSchema`
|
|
68
|
-
* (a host's tool-registration layer refuses to wire any tool lacking one). Optional — the four
|
|
69
|
-
* write entries this file documents but never wires (see file header) carry no schema at all,
|
|
70
|
-
* since one is never published for a tool the model never sees.
|
|
71
|
-
*/
|
|
72
|
-
inputSchema?: Readonly<Record<string, unknown>>;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* The Settings domain's fixed agent-tool catalog — the three reads, one curated write
|
|
76
|
-
* (`settings_set_ui_preference`), and four generic writes documented but deliberately never
|
|
3
|
+
* The Settings domain's fixed agent-tool catalog — three reads, three bounded writes, and two bulk/schema writes documented but never
|
|
77
4
|
* wired. See file header.
|
|
78
5
|
*
|
|
79
6
|
* @complexity O(1) — a fixed, statically-defined list.
|
|
@@ -9,54 +9,47 @@
|
|
|
9
9
|
* raw-JSON textarea, with no schema-exposing endpoint feeding a typed control. There is no fixed,
|
|
10
10
|
* curated list of named settings on that surface to wire tools against.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
12
|
+
* The original generic-write exclusion correctly observed that schema validation bounds VALUE
|
|
13
|
+
* shape, not WHICH key may be targeted. The owner reversed permanent exclusion on 2026-10-01:
|
|
14
|
+
* settings_set_value/settings_clear_value now address one registered workspace or caller-owned
|
|
15
|
+
* user override. Explicit key policy bounds the target; privacy consent and the assistant's own
|
|
16
|
+
* instructions require a HUMAN confirmation port (the agent cannot self-confirm). Hosts add
|
|
17
|
+
* runtime/permission policies through the same seam. Headless protected writes fail closed.
|
|
18
|
+
* Ordinary settings apply directly and remain undoable using the returned previous override.
|
|
17
19
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* bind to. `SETTINGS_SET_UI_PREFERENCE` below wires a seven-key subset of that list
|
|
21
|
-
* (`agent-writable-preferences.ts`):
|
|
20
|
+
* settings_set_ui_preference remains the fixed seven-key, caller-only display-preference surface.
|
|
21
|
+
* It cannot reach consent or standing instructions; use the generic tools and a human card there.
|
|
22
22
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* -
|
|
27
|
-
* caller's own principal, which derives `settings.user.self.write` — the narrowest write grant
|
|
28
|
-
* in the system — and makes writing another operator's preferences unrepresentable rather than
|
|
29
|
-
* merely unauthorized.
|
|
30
|
-
* - The keys are per-operator display preferences (locale, theme, accent, notification sounds),
|
|
31
|
-
* each reversible in one call and visible in the admin UI the moment it changes.
|
|
32
|
-
*
|
|
33
|
-
* The generic setter stays excluded, permanently and for its original reason. Nothing above is
|
|
34
|
-
* evidence that the other three writes may now be wired:
|
|
35
|
-
* - `SETTINGS_RESET` is broader still: a single call clears every value in an operator-named
|
|
36
|
-
* namespace at a scope — typically described in a host's own confirmation dialog as
|
|
37
|
-
* irreversible.
|
|
38
|
-
* - `SETTINGS_REGISTER_DEFINITIONS` is schema-level, not value-level: it can rename/retype/
|
|
39
|
-
* deprecate/tombstone the DEFINITION a key resolves through, changing how every existing stored
|
|
40
|
-
* value for that key is interpreted platform-wide.
|
|
23
|
+
* The broader operations remain excluded:
|
|
24
|
+
* - SETTINGS_RESET clears every value in a namespace at once, an irreversible bulk operation.
|
|
25
|
+
* - SETTINGS_REGISTER_DEFINITIONS can retype/rename/tombstone definitions and reinterpret values
|
|
26
|
+
* platform-wide. Neither gets wired by the value-write decision.
|
|
41
27
|
*
|
|
42
28
|
* Reads are a different risk class and are wired: `SETTINGS_LIST_DEFINITIONS`/
|
|
43
29
|
* `SETTINGS_GET_EFFECTIVE`/`SETTINGS_GET_RAW` cannot mutate anything, are gated by the same real
|
|
44
|
-
* `authorize
|
|
30
|
+
* `authorize` permissions an admin UI's own reads use (including the cross-principal
|
|
45
31
|
* `settings.user.read` check), and cannot surface a secret value even in principle —
|
|
46
32
|
* `settings.ts`'s `validateDefinitionInput` unconditionally refuses `secret:true` at registration
|
|
47
|
-
* time
|
|
33
|
+
* time, so no secret setting can exist in this library's current state to leak.
|
|
48
34
|
*
|
|
49
35
|
* How it relates to a host:
|
|
50
36
|
* A host's tool-registration layer consumes this catalog to decide which tool names an agent
|
|
51
|
-
* session may even see; `authorize
|
|
37
|
+
* session may even see; `authorize` enforces the actual permission checks at call time — this
|
|
52
38
|
* module only declares the catalog shape, it performs no I/O and no enforcement itself.
|
|
53
39
|
*
|
|
54
40
|
* Architectural role:
|
|
55
41
|
* `settings` domain logic. Depends only on its own sibling `agent-writable-preferences.ts` (for
|
|
56
42
|
* the curated write's enum) — no I/O, no enforcement.
|
|
43
|
+
* See docs/decisions/DR-003-settings-ledger-invariants.md.
|
|
57
44
|
*/
|
|
58
45
|
import { AGENT_WRITABLE_PREFERENCE_IDS, AGENT_WRITABLE_PREFERENCES } from "./agent-writable-preferences.js";
|
|
59
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* JSON Schema for this tool's `input`, published to the model via `ToolDescriptor.inputSchema`
|
|
48
|
+
* (a host's tool-registration layer refuses to wire any tool lacking one). Optional — the two bulk/schema
|
|
49
|
+
* write entries this file documents but never wires (see file header) carry no schema at all,
|
|
50
|
+
* since one is never published for a tool the model never sees.
|
|
51
|
+
*
|
|
52
|
+
* No arguments — `settings_list_definitions` takes none; it always enumerates the caller's own
|
|
60
53
|
* (boot-wired) workspace's site-owned partition plus the shared platform partition. */
|
|
61
54
|
const NO_INPUT_SCHEMA = {
|
|
62
55
|
type: "object",
|
|
@@ -118,9 +111,24 @@ const SET_UI_PREFERENCE_SCHEMA = {
|
|
|
118
111
|
},
|
|
119
112
|
},
|
|
120
113
|
};
|
|
114
|
+
/** Both generic writes target only this workspace or the caller's own user layer. */
|
|
115
|
+
const CLEAR_VALUE_SCHEMA = {
|
|
116
|
+
type: "object",
|
|
117
|
+
additionalProperties: false,
|
|
118
|
+
required: ["namespace", "key"],
|
|
119
|
+
properties: {
|
|
120
|
+
namespace: { type: "string", minLength: 1, description: "A registered settings namespace; call settings_list_definitions first." },
|
|
121
|
+
key: { type: "string", minLength: 1, description: "A registered key inside the namespace." },
|
|
122
|
+
scope: { type: "string", enum: ["workspace", "user"], default: "workspace", description: "Workspace override, or only the calling operator's own user override." },
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
const SET_VALUE_SCHEMA = {
|
|
126
|
+
...CLEAR_VALUE_SCHEMA,
|
|
127
|
+
required: ["namespace", "key", "value"],
|
|
128
|
+
properties: { ...CLEAR_VALUE_SCHEMA.properties, value: { description: "Any JSON matching the definition schema returned by settings_list_definitions." } },
|
|
129
|
+
};
|
|
121
130
|
/**
|
|
122
|
-
* The Settings domain's fixed agent-tool catalog —
|
|
123
|
-
* (`settings_set_ui_preference`), and four generic writes documented but deliberately never
|
|
131
|
+
* The Settings domain's fixed agent-tool catalog — three reads, three bounded writes, and two bulk/schema writes documented but never
|
|
124
132
|
* wired. See file header.
|
|
125
133
|
*
|
|
126
134
|
* @complexity O(1) — a fixed, statically-defined list.
|
|
@@ -130,7 +138,7 @@ export function getSettingsAgentToolCatalog() {
|
|
|
130
138
|
return [
|
|
131
139
|
{
|
|
132
140
|
name: "settings_list_definitions",
|
|
133
|
-
description: "Lists every active setting definition visible to this workspace (platform core/theme definitions plus this workspace's own site-owned definitions): namespace, key, owner kind, scope bitmask, status, and
|
|
141
|
+
description: "Lists every active setting definition visible to this workspace (platform core/theme definitions plus this workspace's own site-owned definitions): namespace, key, owner kind, scope bitmask, status, version, schema, agentWritable and confirmationRequired. Use before writing a setting. Metadata only — never a value.",
|
|
134
142
|
sideEffects: "none",
|
|
135
143
|
authorization: { permission: "settings.read.definitions" },
|
|
136
144
|
inputSchema: NO_INPUT_SCHEMA,
|
|
@@ -161,25 +169,21 @@ export function getSettingsAgentToolCatalog() {
|
|
|
161
169
|
inputSchema: SET_UI_PREFERENCE_SCHEMA,
|
|
162
170
|
},
|
|
163
171
|
{
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
// fixed named list. `settings_set_ui_preference` above is the curated alternative and does
|
|
167
|
-
// NOT make this one wireable: the whole difference is that its target key is enum-bounded.
|
|
168
|
-
name: "settings_set",
|
|
169
|
-
description: "Sets a setting's value at a scope. NEVER agent-callable — see file header.",
|
|
172
|
+
name: "settings_set_value",
|
|
173
|
+
description: "Sets one registered setting at workspace scope (default) or the caller's own user scope. Call settings_list_definitions for valid keys, schemas, scopes and confirmation policy. Returns {key, scope, previous, value, revisionSeq}; previous is the old override, or null if absent. Privacy, instructions and host-protected assistant settings need a human confirmation card; the agent cannot confirm itself. Rejects unknown/tombstoned keys, disallowed scopes, invalid values and missing permissions. Cannot write globally, target another operator, reset a namespace or change definitions.",
|
|
170
174
|
sideEffects: "mutates-durable-state",
|
|
171
175
|
authorization: { permission: "settings.workspace.write" },
|
|
176
|
+
inputSchema: SET_VALUE_SCHEMA,
|
|
172
177
|
},
|
|
173
178
|
{
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
name: "settings_clear",
|
|
177
|
-
description: "Clears a setting's value at a scope, reverting it to default. NEVER agent-callable — see file header.",
|
|
179
|
+
name: "settings_clear_value",
|
|
180
|
+
description: "Clears one setting override at workspace scope (default) or the caller's own user scope so the next layer/default applies. Use to put one setting back to its inherited value; not to reset a namespace or delete a definition. Returns {key, scope, previous, effective}; restore a non-null previous override with settings_set_value. Protected assistant settings require a human confirmation card. Rejects unknown/tombstoned keys, disallowed scopes and missing permissions; cannot target global or another operator's layer.",
|
|
178
181
|
sideEffects: "mutates-durable-state",
|
|
179
182
|
authorization: { permission: "settings.workspace.write" },
|
|
183
|
+
inputSchema: CLEAR_VALUE_SCHEMA,
|
|
180
184
|
},
|
|
181
185
|
{
|
|
182
|
-
// EXCLUDED BY DESIGN, never wired: see this file's header. Bulk variant of
|
|
186
|
+
// EXCLUDED BY DESIGN, never wired: see this file's header. Bulk variant of a single-value clear —
|
|
183
187
|
// clears every value in an operator-named namespace at a scope in one call, irreversible.
|
|
184
188
|
name: "settings_reset",
|
|
185
189
|
description: "Resets every setting in a namespace to defaults at a scope. NEVER agent-callable — see file header.",
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type ToolExecutionContext, type ToolHandler } from "@jini-ai/core";
|
|
2
|
+
import type { JsonValue } from "@jini-ai/core/primitives";
|
|
3
|
+
import type { SettingsToolDeps } from "./tool-registrations.js";
|
|
4
|
+
export type SettingsValueWriteToolId = "settings_set_value" | "settings_clear_value";
|
|
5
|
+
/** Host-only port. This request is never an agent input and only the host's authenticated
|
|
6
|
+
* human transport may answer it. Returning true without a human violates this contract. */
|
|
7
|
+
export interface SettingsWriteConfirmation {
|
|
8
|
+
ctx: ToolExecutionContext;
|
|
9
|
+
toolId: SettingsValueWriteToolId;
|
|
10
|
+
namespace: string;
|
|
11
|
+
key: string;
|
|
12
|
+
scope: "workspace" | "user";
|
|
13
|
+
previous: JsonValue | null;
|
|
14
|
+
value?: JsonValue;
|
|
15
|
+
reason: string;
|
|
16
|
+
}
|
|
17
|
+
/** Builds one value-write handler. Effects: authorize -> raw read -> optional human card ->
|
|
18
|
+
* service write -> result. The service rechecks authorization and performs its normal transaction.
|
|
19
|
+
* @complexity O(value size + rule count) plus bounded repository calls and a human wait.
|
|
20
|
+
* @throws ToolInputError for invalid input, denied keys, absent/declined/stale confirmation. */
|
|
21
|
+
export declare function buildSettingsValueWriteHandler(deps: SettingsToolDeps, toolId: SettingsValueWriteToolId): ToolHandler;
|
|
22
|
+
//# sourceMappingURL=agent-value-write-tools.d.ts.map
|