@peers-app/peers-sdk 0.21.7 → 0.23.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/context/user-context-singleton.d.ts +42 -0
- package/dist/context/user-context-singleton.js +45 -0
- package/dist/contracts/__tests__/contract-proxy.test.js +51 -1
- package/dist/contracts/__tests__/contract-resolvers.test.js +65 -0
- package/dist/contracts/__tests__/playground.test.js +5 -2
- package/dist/contracts/__tests__/system-contracts.test.js +3 -0
- package/dist/contracts/contract-proxy.d.ts +27 -0
- package/dist/contracts/contract-proxy.js +37 -1
- package/dist/contracts/contract-resolvers.d.ts +10 -0
- package/dist/contracts/contract-resolvers.js +21 -3
- package/dist/contracts/index.d.ts +3 -2
- package/dist/contracts/index.js +5 -2
- package/dist/contracts/system/index.d.ts +2 -0
- package/dist/contracts/system/index.js +5 -1
- package/dist/contracts/system/tool-access-control-contract.d.ts +35 -0
- package/dist/contracts/system/tool-access-control-contract.js +70 -0
- package/dist/data/access-level.d.ts +72 -0
- package/dist/data/access-level.js +109 -0
- package/dist/data/access-level.test.d.ts +1 -0
- package/dist/data/access-level.test.js +53 -0
- package/dist/data/assistants.d.ts +24 -0
- package/dist/data/assistants.js +21 -0
- package/dist/data/group-member-roles.d.ts +9 -0
- package/dist/data/group-member-roles.js +9 -0
- package/dist/data/group-permissions.d.ts +55 -1
- package/dist/data/group-permissions.js +76 -6
- package/dist/data/index.d.ts +3 -1
- package/dist/data/index.js +3 -1
- package/dist/data/orm/sql.data-source.d.ts +10 -0
- package/dist/data/orm/sql.data-source.js +48 -30
- package/dist/data/orm/sql.data-source.test.js +13 -0
- package/dist/data/package-version-resolver.test.js +2 -0
- package/dist/data/tool-access-approvals.d.ts +126 -0
- package/dist/data/tool-access-approvals.js +86 -0
- package/dist/data/tool-access.d.ts +162 -0
- package/dist/data/tool-access.js +235 -0
- package/dist/data/tool-access.test.d.ts +1 -0
- package/dist/data/tool-access.test.js +159 -0
- package/dist/data/tools.d.ts +15 -0
- package/dist/data/tools.js +11 -0
- package/dist/data/workflow-logs.d.ts +5 -5
- package/dist/data/workflow-runs.d.ts +2 -2
- package/dist/device-pairing/types.d.ts +6 -6
- package/dist/package-installer/package-creator.d.ts +31 -0
- package/dist/package-installer/package-creator.js +140 -40
- package/dist/package-installer/package-creator.test.js +113 -11
- package/dist/rpc-types.d.ts +0 -17
- package/dist/rpc-types.js +0 -15
- package/dist/system-ids.d.ts +13 -0
- package/dist/system-ids.js +14 -1
- package/package.json +1 -1
- package/dist/data/voice-messages.d.ts +0 -33
- package/dist/data/voice-messages.js +0 -33
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.resolveLogsContract = exports.LOGS_CONTRACT_VERSION = exports.getLogsContractDefinition = exports.getDeviceOperationsContractDefinition = exports.deviceOperationsToolIds = exports.deviceOperationsProviderPackageId = exports.DEVICE_OPERATIONS_MAX_TOOLS = exports.DEVICE_OPERATIONS_MAX_ROWS = exports.DEVICE_OPERATIONS_MAX_RESULT_BYTES = exports.DEVICE_OPERATIONS_MAX_QUERY_LENGTH = exports.DEVICE_OPERATIONS_CONTRACT_VERSION = void 0;
|
|
17
|
+
exports.TOOL_ACCESS_CONTROL_CONTRACT_VERSION = exports.getToolAccessControlContractDefinition = exports.resolveLogsContract = exports.LOGS_CONTRACT_VERSION = exports.getLogsContractDefinition = exports.getDeviceOperationsContractDefinition = exports.deviceOperationsToolIds = exports.deviceOperationsProviderPackageId = exports.DEVICE_OPERATIONS_MAX_TOOLS = exports.DEVICE_OPERATIONS_MAX_ROWS = exports.DEVICE_OPERATIONS_MAX_RESULT_BYTES = exports.DEVICE_OPERATIONS_MAX_QUERY_LENGTH = exports.DEVICE_OPERATIONS_CONTRACT_VERSION = void 0;
|
|
18
18
|
/**
|
|
19
19
|
* Built-in system contracts. Importing this barrel runs each module's
|
|
20
20
|
* {@link registerSystemContract} side effect so the catalog is populated.
|
|
@@ -22,6 +22,7 @@ exports.resolveLogsContract = exports.LOGS_CONTRACT_VERSION = exports.getLogsCon
|
|
|
22
22
|
require("./device-operations-contract");
|
|
23
23
|
require("./logs-contract");
|
|
24
24
|
require("./network-contracts");
|
|
25
|
+
require("./tool-access-control-contract");
|
|
25
26
|
var device_operations_contract_1 = require("./device-operations-contract");
|
|
26
27
|
Object.defineProperty(exports, "DEVICE_OPERATIONS_CONTRACT_VERSION", { enumerable: true, get: function () { return device_operations_contract_1.DEVICE_OPERATIONS_CONTRACT_VERSION; } });
|
|
27
28
|
Object.defineProperty(exports, "DEVICE_OPERATIONS_MAX_QUERY_LENGTH", { enumerable: true, get: function () { return device_operations_contract_1.DEVICE_OPERATIONS_MAX_QUERY_LENGTH; } });
|
|
@@ -36,3 +37,6 @@ Object.defineProperty(exports, "getLogsContractDefinition", { enumerable: true,
|
|
|
36
37
|
Object.defineProperty(exports, "LOGS_CONTRACT_VERSION", { enumerable: true, get: function () { return logs_contract_1.LOGS_CONTRACT_VERSION; } });
|
|
37
38
|
Object.defineProperty(exports, "resolveLogsContract", { enumerable: true, get: function () { return logs_contract_1.resolveLogsContract; } });
|
|
38
39
|
__exportStar(require("./network-contracts"), exports);
|
|
40
|
+
var tool_access_control_contract_1 = require("./tool-access-control-contract");
|
|
41
|
+
Object.defineProperty(exports, "getToolAccessControlContractDefinition", { enumerable: true, get: function () { return tool_access_control_contract_1.getToolAccessControlContractDefinition; } });
|
|
42
|
+
Object.defineProperty(exports, "TOOL_ACCESS_CONTROL_CONTRACT_VERSION", { enumerable: true, get: function () { return tool_access_control_contract_1.TOOL_ACCESS_CONTROL_CONTRACT_VERSION; } });
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { IContractConsumerBase } from "../contract-proxy";
|
|
2
|
+
import type { IContractDefinition } from "../types";
|
|
3
|
+
/** Version of the built-in System Tool Access Control contract. */
|
|
4
|
+
export declare const TOOL_ACCESS_CONTROL_CONTRACT_VERSION = 1;
|
|
5
|
+
/**
|
|
6
|
+
* Local-only host contract for approving or rejecting step-up tool access.
|
|
7
|
+
*
|
|
8
|
+
* Assistants never receive these tools. Remote device connections must not
|
|
9
|
+
* resolve this contract.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getToolAccessControlContractDefinition(): IContractDefinition;
|
|
12
|
+
/** Consumer-side TypeScript shape for System Tool Access Control. */
|
|
13
|
+
export interface IToolAccessControlConsumer extends IContractConsumerBase {
|
|
14
|
+
tools: {
|
|
15
|
+
approve(input: {
|
|
16
|
+
approvalId: string;
|
|
17
|
+
nonce: string;
|
|
18
|
+
scope?: "once" | "thread" | "context";
|
|
19
|
+
}): Promise<{
|
|
20
|
+
result: unknown;
|
|
21
|
+
}>;
|
|
22
|
+
reject(input: {
|
|
23
|
+
approvalId: string;
|
|
24
|
+
nonce: string;
|
|
25
|
+
}): Promise<{
|
|
26
|
+
result: unknown;
|
|
27
|
+
}>;
|
|
28
|
+
listPending(input?: {
|
|
29
|
+
threadMessageId?: string;
|
|
30
|
+
workflowRunId?: string;
|
|
31
|
+
}): Promise<{
|
|
32
|
+
approvals: unknown[];
|
|
33
|
+
}>;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TOOL_ACCESS_CONTROL_CONTRACT_VERSION = void 0;
|
|
4
|
+
exports.getToolAccessControlContractDefinition = getToolAccessControlContractDefinition;
|
|
5
|
+
const system_ids_1 = require("../../system-ids");
|
|
6
|
+
const field_type_1 = require("../../types/field-type");
|
|
7
|
+
const system_contracts_1 = require("../system-contracts");
|
|
8
|
+
/** Version of the built-in System Tool Access Control contract. */
|
|
9
|
+
exports.TOOL_ACCESS_CONTROL_CONTRACT_VERSION = 1;
|
|
10
|
+
const field = (name, type, description, opts = {}) => ({ name, type, description, ...opts });
|
|
11
|
+
let definition;
|
|
12
|
+
/**
|
|
13
|
+
* Local-only host contract for approving or rejecting step-up tool access.
|
|
14
|
+
*
|
|
15
|
+
* Assistants never receive these tools. Remote device connections must not
|
|
16
|
+
* resolve this contract.
|
|
17
|
+
*/
|
|
18
|
+
function getToolAccessControlContractDefinition() {
|
|
19
|
+
definition ??= {
|
|
20
|
+
contractId: system_ids_1.toolAccessControlContractId,
|
|
21
|
+
version: exports.TOOL_ACCESS_CONTROL_CONTRACT_VERSION,
|
|
22
|
+
devTag: "dev",
|
|
23
|
+
name: "System Tool Access Control",
|
|
24
|
+
description: "Approve or reject privileged tool calls requested by Assistants.",
|
|
25
|
+
tables: [],
|
|
26
|
+
tools: [
|
|
27
|
+
{
|
|
28
|
+
name: "approve",
|
|
29
|
+
usageDescription: "Approve a pending tool-access request and execute the frozen call.",
|
|
30
|
+
inputFields: [
|
|
31
|
+
field("approvalId", field_type_1.FieldType.id, "Pending approval id."),
|
|
32
|
+
field("nonce", field_type_1.FieldType.string, "Single-use nonce from the pending row."),
|
|
33
|
+
field("scope", field_type_1.FieldType.string, "once, thread, or context.", { optional: true }),
|
|
34
|
+
],
|
|
35
|
+
outputFields: [field("result", field_type_1.FieldType.object, "Approval and execution result.")],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "reject",
|
|
39
|
+
usageDescription: "Reject a pending tool-access request.",
|
|
40
|
+
inputFields: [
|
|
41
|
+
field("approvalId", field_type_1.FieldType.id, "Pending approval id."),
|
|
42
|
+
field("nonce", field_type_1.FieldType.string, "Single-use nonce from the pending row."),
|
|
43
|
+
],
|
|
44
|
+
outputFields: [field("result", field_type_1.FieldType.object, "Rejection result.")],
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "listPending",
|
|
48
|
+
usageDescription: "List pending tool-access approvals for a thread or workflow.",
|
|
49
|
+
inputFields: [
|
|
50
|
+
field("threadMessageId", field_type_1.FieldType.id, "Thread root or parent user message.", {
|
|
51
|
+
optional: true,
|
|
52
|
+
}),
|
|
53
|
+
field("workflowRunId", field_type_1.FieldType.id, "Workflow run id.", { optional: true }),
|
|
54
|
+
],
|
|
55
|
+
outputFields: [
|
|
56
|
+
field("approvals", field_type_1.FieldType.object, "Pending approval rows.", { isArray: true }),
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
observables: [],
|
|
61
|
+
events: [],
|
|
62
|
+
};
|
|
63
|
+
return definition;
|
|
64
|
+
}
|
|
65
|
+
(0, system_contracts_1.registerSystemContract)({
|
|
66
|
+
providerPackageId: system_ids_1.peersSystemPackageId,
|
|
67
|
+
contractId: system_ids_1.toolAccessControlContractId,
|
|
68
|
+
version: exports.TOOL_ACCESS_CONTROL_CONTRACT_VERSION,
|
|
69
|
+
getDefinition: getToolAccessControlContractDefinition,
|
|
70
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { GroupMemberRole } from "./group-member-roles";
|
|
3
|
+
/**
|
|
4
|
+
* Named access-level constants on the same 0–100 scale as {@link GroupMemberRole}.
|
|
5
|
+
*
|
|
6
|
+
* Tools and Assistants store an integer in this range. Most callers use these
|
|
7
|
+
* named values; custom policies may use any integer from 0 through 100.
|
|
8
|
+
*
|
|
9
|
+
* `Self` (100) is operational authority in a personal context (or a group
|
|
10
|
+
* Founder). It is not connection {@link TrustLevel}.
|
|
11
|
+
*/
|
|
12
|
+
export declare const AccessLevel: {
|
|
13
|
+
readonly None: 0;
|
|
14
|
+
readonly Reader: 20;
|
|
15
|
+
readonly Writer: 40;
|
|
16
|
+
readonly Admin: 60;
|
|
17
|
+
readonly Owner: 80;
|
|
18
|
+
readonly Self: 100;
|
|
19
|
+
};
|
|
20
|
+
/** One of the named {@link AccessLevel} constants. */
|
|
21
|
+
export type NamedAccessLevel = (typeof AccessLevel)[keyof typeof AccessLevel];
|
|
22
|
+
/**
|
|
23
|
+
* Fail-closed default for unclassified tools and Assistants.
|
|
24
|
+
*
|
|
25
|
+
* Missing metadata is treated as {@link AccessLevel.Self} so a new package
|
|
26
|
+
* tool cannot run until someone explicitly lowers its requirement.
|
|
27
|
+
*/
|
|
28
|
+
export declare const DEFAULT_ACCESS_LEVEL: 100;
|
|
29
|
+
/** Inclusive minimum stored access level. */
|
|
30
|
+
export declare const MIN_ACCESS_LEVEL = 0;
|
|
31
|
+
/** Inclusive maximum stored access level. */
|
|
32
|
+
export declare const MAX_ACCESS_LEVEL = 100;
|
|
33
|
+
/**
|
|
34
|
+
* Zod schema for a stored access level: an integer from 0 through 100.
|
|
35
|
+
* Unspecified values default to {@link DEFAULT_ACCESS_LEVEL}.
|
|
36
|
+
*/
|
|
37
|
+
export declare const accessLevelSchema: z.ZodDefault<z.ZodNumber>;
|
|
38
|
+
/**
|
|
39
|
+
* Return a human-readable label for an access-level integer.
|
|
40
|
+
*
|
|
41
|
+
* Exact named values return `Self`, `Owner`, `Admin`, `Writer`, `Reader`, or
|
|
42
|
+
* `None`. Values between named tiers append `+` to the next-lower name
|
|
43
|
+
* (for example `61` → `Admin+`). Out-of-range numbers return `None`.
|
|
44
|
+
*
|
|
45
|
+
* @param value - Access level to label.
|
|
46
|
+
*/
|
|
47
|
+
export declare function getAccessLevelLabel(value: number): string;
|
|
48
|
+
/**
|
|
49
|
+
* Normalize a stored or missing access level to a safe integer.
|
|
50
|
+
*
|
|
51
|
+
* `undefined`, `null`, `NaN`, and non-integers become {@link DEFAULT_ACCESS_LEVEL}.
|
|
52
|
+
* Values outside 0–100 are clamped.
|
|
53
|
+
*
|
|
54
|
+
* @param value - Raw access level from a record or config.
|
|
55
|
+
*/
|
|
56
|
+
export declare function resolveAccessLevel(value: unknown): number;
|
|
57
|
+
/**
|
|
58
|
+
* Map a {@link GroupMemberRole} onto the access-level scale.
|
|
59
|
+
*
|
|
60
|
+
* Numeric values already match except the top label: group `Founder` (100)
|
|
61
|
+
* is access {@link AccessLevel.Self}.
|
|
62
|
+
*
|
|
63
|
+
* @param role - Group membership role.
|
|
64
|
+
*/
|
|
65
|
+
export declare function accessLevelFromGroupRole(role: GroupMemberRole): number;
|
|
66
|
+
/**
|
|
67
|
+
* Return the named access-level presets used by configuration UIs.
|
|
68
|
+
*/
|
|
69
|
+
export declare function listAccessLevelPresets(): ReadonlyArray<{
|
|
70
|
+
value: number;
|
|
71
|
+
label: string;
|
|
72
|
+
}>;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.accessLevelSchema = exports.MAX_ACCESS_LEVEL = exports.MIN_ACCESS_LEVEL = exports.DEFAULT_ACCESS_LEVEL = exports.AccessLevel = void 0;
|
|
4
|
+
exports.getAccessLevelLabel = getAccessLevelLabel;
|
|
5
|
+
exports.resolveAccessLevel = resolveAccessLevel;
|
|
6
|
+
exports.accessLevelFromGroupRole = accessLevelFromGroupRole;
|
|
7
|
+
exports.listAccessLevelPresets = listAccessLevelPresets;
|
|
8
|
+
const zod_1 = require("zod");
|
|
9
|
+
const group_member_roles_1 = require("./group-member-roles");
|
|
10
|
+
/**
|
|
11
|
+
* Named access-level constants on the same 0–100 scale as {@link GroupMemberRole}.
|
|
12
|
+
*
|
|
13
|
+
* Tools and Assistants store an integer in this range. Most callers use these
|
|
14
|
+
* named values; custom policies may use any integer from 0 through 100.
|
|
15
|
+
*
|
|
16
|
+
* `Self` (100) is operational authority in a personal context (or a group
|
|
17
|
+
* Founder). It is not connection {@link TrustLevel}.
|
|
18
|
+
*/
|
|
19
|
+
exports.AccessLevel = {
|
|
20
|
+
None: 0,
|
|
21
|
+
Reader: 20,
|
|
22
|
+
Writer: 40,
|
|
23
|
+
Admin: 60,
|
|
24
|
+
Owner: 80,
|
|
25
|
+
Self: 100,
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Fail-closed default for unclassified tools and Assistants.
|
|
29
|
+
*
|
|
30
|
+
* Missing metadata is treated as {@link AccessLevel.Self} so a new package
|
|
31
|
+
* tool cannot run until someone explicitly lowers its requirement.
|
|
32
|
+
*/
|
|
33
|
+
exports.DEFAULT_ACCESS_LEVEL = exports.AccessLevel.Self;
|
|
34
|
+
/** Inclusive minimum stored access level. */
|
|
35
|
+
exports.MIN_ACCESS_LEVEL = 0;
|
|
36
|
+
/** Inclusive maximum stored access level. */
|
|
37
|
+
exports.MAX_ACCESS_LEVEL = 100;
|
|
38
|
+
/**
|
|
39
|
+
* Zod schema for a stored access level: an integer from 0 through 100.
|
|
40
|
+
* Unspecified values default to {@link DEFAULT_ACCESS_LEVEL}.
|
|
41
|
+
*/
|
|
42
|
+
exports.accessLevelSchema = zod_1.z
|
|
43
|
+
.number()
|
|
44
|
+
.int()
|
|
45
|
+
.min(exports.MIN_ACCESS_LEVEL)
|
|
46
|
+
.max(exports.MAX_ACCESS_LEVEL)
|
|
47
|
+
.default(exports.DEFAULT_ACCESS_LEVEL);
|
|
48
|
+
const ACCESS_LEVEL_LABELS = [
|
|
49
|
+
{ level: exports.AccessLevel.Self, label: "Self" },
|
|
50
|
+
{ level: exports.AccessLevel.Owner, label: "Owner" },
|
|
51
|
+
{ level: exports.AccessLevel.Admin, label: "Admin" },
|
|
52
|
+
{ level: exports.AccessLevel.Writer, label: "Writer" },
|
|
53
|
+
{ level: exports.AccessLevel.Reader, label: "Reader" },
|
|
54
|
+
{ level: exports.AccessLevel.None, label: "None" },
|
|
55
|
+
];
|
|
56
|
+
/**
|
|
57
|
+
* Return a human-readable label for an access-level integer.
|
|
58
|
+
*
|
|
59
|
+
* Exact named values return `Self`, `Owner`, `Admin`, `Writer`, `Reader`, or
|
|
60
|
+
* `None`. Values between named tiers append `+` to the next-lower name
|
|
61
|
+
* (for example `61` → `Admin+`). Out-of-range numbers return `None`.
|
|
62
|
+
*
|
|
63
|
+
* @param value - Access level to label.
|
|
64
|
+
*/
|
|
65
|
+
function getAccessLevelLabel(value) {
|
|
66
|
+
for (const entry of ACCESS_LEVEL_LABELS) {
|
|
67
|
+
if (value >= entry.level) {
|
|
68
|
+
return value === entry.level ? entry.label : `${entry.label}+`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return "None";
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Normalize a stored or missing access level to a safe integer.
|
|
75
|
+
*
|
|
76
|
+
* `undefined`, `null`, `NaN`, and non-integers become {@link DEFAULT_ACCESS_LEVEL}.
|
|
77
|
+
* Values outside 0–100 are clamped.
|
|
78
|
+
*
|
|
79
|
+
* @param value - Raw access level from a record or config.
|
|
80
|
+
*/
|
|
81
|
+
function resolveAccessLevel(value) {
|
|
82
|
+
if (typeof value !== "number" || !Number.isFinite(value) || !Number.isInteger(value)) {
|
|
83
|
+
return exports.DEFAULT_ACCESS_LEVEL;
|
|
84
|
+
}
|
|
85
|
+
if (value < exports.MIN_ACCESS_LEVEL)
|
|
86
|
+
return exports.MIN_ACCESS_LEVEL;
|
|
87
|
+
if (value > exports.MAX_ACCESS_LEVEL)
|
|
88
|
+
return exports.MAX_ACCESS_LEVEL;
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Map a {@link GroupMemberRole} onto the access-level scale.
|
|
93
|
+
*
|
|
94
|
+
* Numeric values already match except the top label: group `Founder` (100)
|
|
95
|
+
* is access {@link AccessLevel.Self}.
|
|
96
|
+
*
|
|
97
|
+
* @param role - Group membership role.
|
|
98
|
+
*/
|
|
99
|
+
function accessLevelFromGroupRole(role) {
|
|
100
|
+
return role === group_member_roles_1.GroupMemberRole.Founder ? exports.AccessLevel.Self : role;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Return the named access-level presets used by configuration UIs.
|
|
104
|
+
*/
|
|
105
|
+
function listAccessLevelPresets() {
|
|
106
|
+
return ACCESS_LEVEL_LABELS.slice()
|
|
107
|
+
.reverse()
|
|
108
|
+
.map(({ level, label }) => ({ value: level, label }));
|
|
109
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const group_member_roles_1 = require("./group-member-roles");
|
|
4
|
+
const access_level_1 = require("./access-level");
|
|
5
|
+
describe("accessLevelSchema", () => {
|
|
6
|
+
it("defaults missing values to Self (100)", () => {
|
|
7
|
+
expect(access_level_1.accessLevelSchema.parse(undefined)).toBe(access_level_1.AccessLevel.Self);
|
|
8
|
+
expect(access_level_1.DEFAULT_ACCESS_LEVEL).toBe(100);
|
|
9
|
+
});
|
|
10
|
+
it("accepts custom integers between named tiers", () => {
|
|
11
|
+
expect(access_level_1.accessLevelSchema.parse(45)).toBe(45);
|
|
12
|
+
});
|
|
13
|
+
it("rejects values outside 0–100", () => {
|
|
14
|
+
expect(access_level_1.accessLevelSchema.safeParse(-1).success).toBe(false);
|
|
15
|
+
expect(access_level_1.accessLevelSchema.safeParse(101).success).toBe(false);
|
|
16
|
+
expect(access_level_1.accessLevelSchema.safeParse(40.5).success).toBe(false);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
describe("getAccessLevelLabel", () => {
|
|
20
|
+
it("labels named tiers", () => {
|
|
21
|
+
expect((0, access_level_1.getAccessLevelLabel)(0)).toBe("None");
|
|
22
|
+
expect((0, access_level_1.getAccessLevelLabel)(20)).toBe("Reader");
|
|
23
|
+
expect((0, access_level_1.getAccessLevelLabel)(40)).toBe("Writer");
|
|
24
|
+
expect((0, access_level_1.getAccessLevelLabel)(60)).toBe("Admin");
|
|
25
|
+
expect((0, access_level_1.getAccessLevelLabel)(80)).toBe("Owner");
|
|
26
|
+
expect((0, access_level_1.getAccessLevelLabel)(100)).toBe("Self");
|
|
27
|
+
});
|
|
28
|
+
it("labels in-between values with +", () => {
|
|
29
|
+
expect((0, access_level_1.getAccessLevelLabel)(61)).toBe("Admin+");
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
describe("resolveAccessLevel", () => {
|
|
33
|
+
it("fail-closes invalid values to 100", () => {
|
|
34
|
+
expect((0, access_level_1.resolveAccessLevel)(undefined)).toBe(100);
|
|
35
|
+
expect((0, access_level_1.resolveAccessLevel)("40")).toBe(100);
|
|
36
|
+
expect((0, access_level_1.resolveAccessLevel)(Number.NaN)).toBe(100);
|
|
37
|
+
});
|
|
38
|
+
it("clamps out-of-range integers", () => {
|
|
39
|
+
expect((0, access_level_1.resolveAccessLevel)(-5)).toBe(0);
|
|
40
|
+
expect((0, access_level_1.resolveAccessLevel)(200)).toBe(100);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe("accessLevelFromGroupRole", () => {
|
|
44
|
+
it("maps Founder to Self 100", () => {
|
|
45
|
+
expect((0, access_level_1.accessLevelFromGroupRole)(group_member_roles_1.GroupMemberRole.Founder)).toBe(access_level_1.AccessLevel.Self);
|
|
46
|
+
expect((0, access_level_1.accessLevelFromGroupRole)(group_member_roles_1.GroupMemberRole.Admin)).toBe(access_level_1.AccessLevel.Admin);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
describe("listAccessLevelPresets", () => {
|
|
50
|
+
it("returns named presets in ascending order", () => {
|
|
51
|
+
expect((0, access_level_1.listAccessLevelPresets)().map((p) => p.value)).toEqual([0, 20, 40, 60, 80, 100]);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import type { DataContext } from "../context/data-context";
|
|
3
|
+
/** How an Assistant selects tools for each run. */
|
|
3
4
|
export declare enum ToolInclusionStrategy {
|
|
4
5
|
Fixed = "Fixed",
|
|
5
6
|
Linked = "Linked",
|
|
6
7
|
Relevant = "Relevant"
|
|
7
8
|
}
|
|
9
|
+
/** Zod schema for a persisted {@link IAssistant} row. */
|
|
8
10
|
export declare const assistantSchema: z.ZodObject<{
|
|
9
11
|
assistantId: z.ZodEffects<z.ZodString, string, string>;
|
|
10
12
|
name: z.ZodString;
|
|
@@ -16,8 +18,10 @@ export declare const assistantSchema: z.ZodObject<{
|
|
|
16
18
|
toolsToInclude: z.ZodDefault<z.ZodString>;
|
|
17
19
|
toolInclusionStrategy: z.ZodDefault<z.ZodNativeEnum<typeof ToolInclusionStrategy>>;
|
|
18
20
|
packageId: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
21
|
+
accessLevel: z.ZodDefault<z.ZodNumber>;
|
|
19
22
|
}, "strip", z.ZodTypeAny, {
|
|
20
23
|
name: string;
|
|
24
|
+
accessLevel: number;
|
|
21
25
|
assistantId: string;
|
|
22
26
|
createdAt: Date;
|
|
23
27
|
assistantRunnerToolId: string;
|
|
@@ -34,6 +38,7 @@ export declare const assistantSchema: z.ZodObject<{
|
|
|
34
38
|
assistantId: string;
|
|
35
39
|
description?: string | undefined;
|
|
36
40
|
packageId?: string | undefined;
|
|
41
|
+
accessLevel?: number | undefined;
|
|
37
42
|
createdAt?: Date | undefined;
|
|
38
43
|
updatedAt?: Date | undefined;
|
|
39
44
|
assistantRunnerToolId?: string | undefined;
|
|
@@ -41,9 +46,16 @@ export declare const assistantSchema: z.ZodObject<{
|
|
|
41
46
|
toolsToInclude?: string | undefined;
|
|
42
47
|
toolInclusionStrategy?: ToolInclusionStrategy | undefined;
|
|
43
48
|
}>;
|
|
49
|
+
/** An Assistant definition stored in the Assistants table. */
|
|
44
50
|
export type IAssistant = z.infer<typeof assistantSchema>;
|
|
51
|
+
/**
|
|
52
|
+
* Accessor for the Assistants table.
|
|
53
|
+
*
|
|
54
|
+
* @param dataContext - Optional data context; defaults to the current singleton.
|
|
55
|
+
*/
|
|
45
56
|
export declare function Assistants(dataContext?: DataContext): import("..").Table<{
|
|
46
57
|
name: string;
|
|
58
|
+
accessLevel: number;
|
|
47
59
|
assistantId: string;
|
|
48
60
|
createdAt: Date;
|
|
49
61
|
assistantRunnerToolId: string;
|
|
@@ -66,8 +78,15 @@ export declare const userPrimaryAssistantVar: import("./persistent-vars").Persis
|
|
|
66
78
|
* their own preference. Can be set by group admins. Synced to all group members.
|
|
67
79
|
*/
|
|
68
80
|
export declare const groupPrimaryAssistantVar: import("./persistent-vars").PersistentVar<string | undefined>;
|
|
81
|
+
/**
|
|
82
|
+
* Resolve the current user's primary Assistant, falling back to the group
|
|
83
|
+
* default and then the built-in Shell Assistant.
|
|
84
|
+
*
|
|
85
|
+
* @param dataContext - Optional data context for the lookup.
|
|
86
|
+
*/
|
|
69
87
|
export declare const getPrimaryAssistant: (dataContext?: DataContext) => Promise<{
|
|
70
88
|
name: string;
|
|
89
|
+
accessLevel: number;
|
|
71
90
|
assistantId: string;
|
|
72
91
|
createdAt: Date;
|
|
73
92
|
assistantRunnerToolId: string;
|
|
@@ -80,4 +99,9 @@ export declare const getPrimaryAssistant: (dataContext?: DataContext) => Promise
|
|
|
80
99
|
packageId?: string | undefined;
|
|
81
100
|
updatedAt?: Date | undefined;
|
|
82
101
|
}>;
|
|
102
|
+
/**
|
|
103
|
+
* Return Assistant ids mentioned in markdown (`<@assistant:name:id>`).
|
|
104
|
+
*
|
|
105
|
+
* @param message - Message markdown that may contain mentions.
|
|
106
|
+
*/
|
|
83
107
|
export declare function getAllAssistantIdsMentioned(message: string): Promise<string[]>;
|
package/dist/data/assistants.js
CHANGED
|
@@ -8,15 +8,18 @@ const user_context_singleton_1 = require("../context/user-context-singleton");
|
|
|
8
8
|
const mentions_1 = require("../mentions");
|
|
9
9
|
const system_ids_1 = require("../system-ids");
|
|
10
10
|
const zod_types_1 = require("../types/zod-types");
|
|
11
|
+
const access_level_1 = require("./access-level");
|
|
11
12
|
const table_definitions_system_1 = require("./orm/table-definitions.system");
|
|
12
13
|
const types_1 = require("./orm/types");
|
|
13
14
|
const persistent_vars_1 = require("./persistent-vars");
|
|
15
|
+
/** How an Assistant selects tools for each run. */
|
|
14
16
|
var ToolInclusionStrategy;
|
|
15
17
|
(function (ToolInclusionStrategy) {
|
|
16
18
|
ToolInclusionStrategy["Fixed"] = "Fixed";
|
|
17
19
|
ToolInclusionStrategy["Linked"] = "Linked";
|
|
18
20
|
ToolInclusionStrategy["Relevant"] = "Relevant";
|
|
19
21
|
})(ToolInclusionStrategy || (exports.ToolInclusionStrategy = ToolInclusionStrategy = {}));
|
|
22
|
+
/** Zod schema for a persisted {@link IAssistant} row. */
|
|
20
23
|
exports.assistantSchema = zod_1.z.object({
|
|
21
24
|
assistantId: zod_types_1.zodPeerId,
|
|
22
25
|
name: zod_1.z.string(),
|
|
@@ -47,6 +50,7 @@ exports.assistantSchema = zod_1.z.object({
|
|
|
47
50
|
"- **Relevant** - `Linked` plus tools matching the context of the conversation determined via vector search (embeddings) of the tools descriptions.",
|
|
48
51
|
].join("\n")),
|
|
49
52
|
packageId: zod_types_1.zodPeerId.optional().describe("The package that installed this assistant, if any"),
|
|
53
|
+
accessLevel: access_level_1.accessLevelSchema.describe("Minimum user access to invoke this assistant, and the level it may run automatically. Unclassified assistants default to 100 (Self)."),
|
|
50
54
|
});
|
|
51
55
|
const metaData = {
|
|
52
56
|
name: "Assistants",
|
|
@@ -55,8 +59,14 @@ const metaData = {
|
|
|
55
59
|
fields: (0, types_1.schemaToFields)(exports.assistantSchema),
|
|
56
60
|
iconClassName: "bi bi-person-fill-gear",
|
|
57
61
|
indexes: [{ fields: ["name"] }],
|
|
62
|
+
versionNumber: 1,
|
|
58
63
|
};
|
|
59
64
|
(0, table_definitions_system_1.registerSystemTableDefinition)(metaData, exports.assistantSchema);
|
|
65
|
+
/**
|
|
66
|
+
* Accessor for the Assistants table.
|
|
67
|
+
*
|
|
68
|
+
* @param dataContext - Optional data context; defaults to the current singleton.
|
|
69
|
+
*/
|
|
60
70
|
function Assistants(dataContext) {
|
|
61
71
|
return (0, user_context_singleton_1.getTableContainer)(dataContext).getTable(metaData, exports.assistantSchema);
|
|
62
72
|
}
|
|
@@ -70,6 +80,12 @@ exports.userPrimaryAssistantVar = (0, persistent_vars_1.groupUserVar)("userPrima
|
|
|
70
80
|
* their own preference. Can be set by group admins. Synced to all group members.
|
|
71
81
|
*/
|
|
72
82
|
exports.groupPrimaryAssistantVar = (0, persistent_vars_1.groupVar)("groupPrimaryAssistantId");
|
|
83
|
+
/**
|
|
84
|
+
* Resolve the current user's primary Assistant, falling back to the group
|
|
85
|
+
* default and then the built-in Shell Assistant.
|
|
86
|
+
*
|
|
87
|
+
* @param dataContext - Optional data context for the lookup.
|
|
88
|
+
*/
|
|
73
89
|
const getPrimaryAssistant = async (dataContext) => {
|
|
74
90
|
await exports.userPrimaryAssistantVar.loadingPromise;
|
|
75
91
|
const userAssistantId = (0, exports.userPrimaryAssistantVar)();
|
|
@@ -91,6 +107,11 @@ const getPrimaryAssistant = async (dataContext) => {
|
|
|
91
107
|
return fallback;
|
|
92
108
|
};
|
|
93
109
|
exports.getPrimaryAssistant = getPrimaryAssistant;
|
|
110
|
+
/**
|
|
111
|
+
* Return Assistant ids mentioned in markdown (`<@assistant:name:id>`).
|
|
112
|
+
*
|
|
113
|
+
* @param message - Message markdown that may contain mentions.
|
|
114
|
+
*/
|
|
94
115
|
async function getAllAssistantIdsMentioned(message) {
|
|
95
116
|
const mentions = (0, mentions_1.getAllMentions)(message);
|
|
96
117
|
return mentions.filter((m) => m.kind === "assistant").map((m) => m.id);
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Numeric group membership roles. The same 0–100 scale is used for tool and
|
|
3
|
+
* Assistant {@link AccessLevel} values (`Founder` maps to access `Self`).
|
|
4
|
+
*/
|
|
1
5
|
export declare enum GroupMemberRole {
|
|
2
6
|
None = 0,
|
|
3
7
|
Reader = 20,
|
|
@@ -6,4 +10,9 @@ export declare enum GroupMemberRole {
|
|
|
6
10
|
Owner = 80,
|
|
7
11
|
Founder = 100
|
|
8
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Return a human-readable group-role label, using `+` for in-between values.
|
|
15
|
+
*
|
|
16
|
+
* @param value - Numeric role or access-like integer.
|
|
17
|
+
*/
|
|
9
18
|
export declare function getRoleLabel(value: number): string;
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GroupMemberRole = void 0;
|
|
4
4
|
exports.getRoleLabel = getRoleLabel;
|
|
5
|
+
/**
|
|
6
|
+
* Numeric group membership roles. The same 0–100 scale is used for tool and
|
|
7
|
+
* Assistant {@link AccessLevel} values (`Founder` maps to access `Self`).
|
|
8
|
+
*/
|
|
5
9
|
var GroupMemberRole;
|
|
6
10
|
(function (GroupMemberRole) {
|
|
7
11
|
GroupMemberRole[GroupMemberRole["None"] = 0] = "None";
|
|
@@ -11,6 +15,11 @@ var GroupMemberRole;
|
|
|
11
15
|
GroupMemberRole[GroupMemberRole["Owner"] = 80] = "Owner";
|
|
12
16
|
GroupMemberRole[GroupMemberRole["Founder"] = 100] = "Founder";
|
|
13
17
|
})(GroupMemberRole || (exports.GroupMemberRole = GroupMemberRole = {}));
|
|
18
|
+
/**
|
|
19
|
+
* Return a human-readable group-role label, using `+` for in-between values.
|
|
20
|
+
*
|
|
21
|
+
* @param value - Numeric role or access-like integer.
|
|
22
|
+
*/
|
|
14
23
|
function getRoleLabel(value) {
|
|
15
24
|
const roleEntries = Object.entries(GroupMemberRole)
|
|
16
25
|
.filter(([_key, val]) => typeof val === "number")
|
|
@@ -1,8 +1,62 @@
|
|
|
1
|
+
import type { DataContext } from "../context/data-context";
|
|
2
|
+
import type { UserContext } from "../context/user-context";
|
|
1
3
|
import { GroupMemberRole } from "./group-member-roles";
|
|
2
4
|
import type { IGroupMember } from "./group-members";
|
|
3
5
|
import type { IGroup } from "./groups";
|
|
4
6
|
export { GroupMemberRole };
|
|
5
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Return a user's {@link GroupMemberRole} in `groupId`.
|
|
9
|
+
*
|
|
10
|
+
* Missing groups and the group's founder resolve to {@link GroupMemberRole.Founder},
|
|
11
|
+
* which is how a personal context (no Groups row) becomes access 100.
|
|
12
|
+
*
|
|
13
|
+
* Prefer passing `userContext` from the provider that owns the data. The
|
|
14
|
+
* process singleton is only a fallback and is not awaited — multi-device
|
|
15
|
+
* tests never set it, and hanging here would stall contract calls.
|
|
16
|
+
*
|
|
17
|
+
* @param groupId - Group id, or the user's id for their personal context.
|
|
18
|
+
* @param userId - User whose role is requested.
|
|
19
|
+
* @param userContext - Provider-owned context. Falls back to {@link peekUserContext}.
|
|
20
|
+
* @throws If neither an explicit context nor the process singleton is available.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getUserRole(groupId: string, userId: string, userContext?: UserContext): Promise<GroupMemberRole>;
|
|
23
|
+
/**
|
|
24
|
+
* Resolve a group role from the signing public key of a Users record.
|
|
25
|
+
*
|
|
26
|
+
* Uses {@link peekUserContext}; throws if the process singleton is unset.
|
|
27
|
+
*
|
|
28
|
+
* @param groupId - Group or personal context id.
|
|
29
|
+
* @param publicKey - User public key that signed a record.
|
|
30
|
+
*/
|
|
6
31
|
export declare function getUserRoleFromPublicKey(groupId: string, publicKey: string): Promise<GroupMemberRole>;
|
|
32
|
+
/**
|
|
33
|
+
* Return the current user's access level in `dataContext`.
|
|
34
|
+
*
|
|
35
|
+
* Personal contexts (no `groupId`) use the user's id and resolve to 100.
|
|
36
|
+
*
|
|
37
|
+
* @param dataContext - Context whose group/personal role is evaluated.
|
|
38
|
+
*/
|
|
39
|
+
export declare function getCurrentUserAccessLevel(dataContext: DataContext): Promise<number>;
|
|
40
|
+
/**
|
|
41
|
+
* Return `userId`'s access level in `dataContext`.
|
|
42
|
+
*
|
|
43
|
+
* @param dataContext - Context whose group/personal role is evaluated.
|
|
44
|
+
* @param userId - User to resolve.
|
|
45
|
+
*/
|
|
46
|
+
export declare function getUserAccessLevel(dataContext: DataContext, userId: string): Promise<number>;
|
|
47
|
+
/**
|
|
48
|
+
* Verify that a group record was signed by an Admin+ member (Founder to change founder).
|
|
49
|
+
*
|
|
50
|
+
* @param group - Proposed group record.
|
|
51
|
+
* @param oldGroup - Previous record when this is an update.
|
|
52
|
+
*/
|
|
7
53
|
export declare function verifyGroupSignature(group: IGroup, oldGroup?: IGroup): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Return whether a group-member write is signed by someone allowed to make it.
|
|
56
|
+
*
|
|
57
|
+
* @param groupId - Group the membership belongs to.
|
|
58
|
+
* @param newGroupMember - Proposed membership row.
|
|
59
|
+
* @param oldGroupMember - Previous row when this is an update.
|
|
60
|
+
* @param signerRole - Optional precomputed signer role.
|
|
61
|
+
*/
|
|
8
62
|
export declare function isGroupMemberSignatureValid(groupId: string, newGroupMember: IGroupMember, oldGroupMember?: IGroupMember, signerRole?: GroupMemberRole): Promise<boolean>;
|