@peers-app/peers-sdk 0.20.0 → 0.20.2

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.
@@ -8,6 +8,7 @@ export { Contracts, ContractsTable, contractsMetaData, contractsSchema, type ICo
8
8
  export { extractTableShape, extractToolShape, type IExtractableTableDef, type IExtractableToolInstance, setSchemaToFieldsFn, } from "./extract";
9
9
  export { PersistentContractRegistry } from "./persistent-registry";
10
10
  export { ContractRegistry } from "./registry";
11
+ export { DEVICE_OPERATIONS_CONTRACT_VERSION, DEVICE_OPERATIONS_MAX_QUERY_LENGTH, DEVICE_OPERATIONS_MAX_RESULT_BYTES, DEVICE_OPERATIONS_MAX_ROWS, DEVICE_OPERATIONS_MAX_TOOLS, type DeviceOperationCapability, deviceOperationsProviderPackageId, deviceOperationsToolIds, getDeviceOperationsContractDefinition, type IDeviceDatabaseQueryInput, type IDeviceDatabaseQueryResult, type IDeviceOperationStatus, type IDeviceToolListInput, type IDeviceToolLookupInput, type IDeviceToolLookupResult, type IDeviceToolRunInput, } from "./system/device-operations-contract";
11
12
  export { getLogsContractDefinition, LOGS_CONTRACT_VERSION, resolveLogsContract, } from "./system/logs-contract";
12
13
  export type { IAlsoImplementsDeclaration, IConsumedContract, IContractDefinition, IContractEvent, IContractObservable, IContractTable, IContractTool, IPackageDefinitionResult, IResolvedContract, IValidationError, IValidationResult, } from "./types";
13
14
  export { contractKey } from "./types";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateProviderSatisfiesContract = exports.validateImmutability = exports.validateAlsoImplements = exports.contractKey = exports.resolveLogsContract = exports.LOGS_CONTRACT_VERSION = exports.getLogsContractDefinition = exports.ContractRegistry = exports.PersistentContractRegistry = exports.setSchemaToFieldsFn = exports.extractToolShape = exports.extractTableShape = exports.contractsSchema = exports.contractsMetaData = exports.ContractsTable = exports.Contracts = exports.inProcessTransportPair = exports.connectionContractTransport = exports.CONTRACT_REQUEST_CHANNEL = exports.CONTRACT_NOTIFY_CHANNEL = exports.registerContractResolver = exports.isSelfTrustedContractCaller = exports.handleContractCall = exports.getContractResolver = exports.createUserContextContractProviderRouter = exports.sameUserContractPermissionCheck = exports.createContractProviderSession = exports.createContractProviderEndpoint = exports.createContractProvider = exports.createContractConsumer = exports.CONTRACT_CALL_RPC = exports.contractProvidersSchema = exports.contractProvidersMetaData = exports.ContractProvidersTable = exports.ContractProviders = exports.createContractProviderRouter = exports.PackageBuilder = exports.definePackage = exports.ContractBuilder = void 0;
3
+ exports.validateProviderSatisfiesContract = exports.validateImmutability = exports.validateAlsoImplements = exports.contractKey = 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 = exports.ContractRegistry = exports.PersistentContractRegistry = exports.setSchemaToFieldsFn = exports.extractToolShape = exports.extractTableShape = exports.contractsSchema = exports.contractsMetaData = exports.ContractsTable = exports.Contracts = exports.inProcessTransportPair = exports.connectionContractTransport = exports.CONTRACT_REQUEST_CHANNEL = exports.CONTRACT_NOTIFY_CHANNEL = exports.registerContractResolver = exports.isSelfTrustedContractCaller = exports.handleContractCall = exports.getContractResolver = exports.createUserContextContractProviderRouter = exports.sameUserContractPermissionCheck = exports.createContractProviderSession = exports.createContractProviderEndpoint = exports.createContractProvider = exports.createContractConsumer = exports.CONTRACT_CALL_RPC = exports.contractProvidersSchema = exports.contractProvidersMetaData = exports.ContractProvidersTable = exports.ContractProviders = exports.createContractProviderRouter = exports.PackageBuilder = exports.definePackage = exports.ContractBuilder = void 0;
4
4
  var builder_1 = require("./builder");
5
5
  Object.defineProperty(exports, "ContractBuilder", { enumerable: true, get: function () { return builder_1.ContractBuilder; } });
6
6
  Object.defineProperty(exports, "definePackage", { enumerable: true, get: function () { return builder_1.definePackage; } });
@@ -43,6 +43,15 @@ var persistent_registry_1 = require("./persistent-registry");
43
43
  Object.defineProperty(exports, "PersistentContractRegistry", { enumerable: true, get: function () { return persistent_registry_1.PersistentContractRegistry; } });
44
44
  var registry_1 = require("./registry");
45
45
  Object.defineProperty(exports, "ContractRegistry", { enumerable: true, get: function () { return registry_1.ContractRegistry; } });
46
+ var device_operations_contract_1 = require("./system/device-operations-contract");
47
+ Object.defineProperty(exports, "DEVICE_OPERATIONS_CONTRACT_VERSION", { enumerable: true, get: function () { return device_operations_contract_1.DEVICE_OPERATIONS_CONTRACT_VERSION; } });
48
+ Object.defineProperty(exports, "DEVICE_OPERATIONS_MAX_QUERY_LENGTH", { enumerable: true, get: function () { return device_operations_contract_1.DEVICE_OPERATIONS_MAX_QUERY_LENGTH; } });
49
+ Object.defineProperty(exports, "DEVICE_OPERATIONS_MAX_RESULT_BYTES", { enumerable: true, get: function () { return device_operations_contract_1.DEVICE_OPERATIONS_MAX_RESULT_BYTES; } });
50
+ Object.defineProperty(exports, "DEVICE_OPERATIONS_MAX_ROWS", { enumerable: true, get: function () { return device_operations_contract_1.DEVICE_OPERATIONS_MAX_ROWS; } });
51
+ Object.defineProperty(exports, "DEVICE_OPERATIONS_MAX_TOOLS", { enumerable: true, get: function () { return device_operations_contract_1.DEVICE_OPERATIONS_MAX_TOOLS; } });
52
+ Object.defineProperty(exports, "deviceOperationsProviderPackageId", { enumerable: true, get: function () { return device_operations_contract_1.deviceOperationsProviderPackageId; } });
53
+ Object.defineProperty(exports, "deviceOperationsToolIds", { enumerable: true, get: function () { return device_operations_contract_1.deviceOperationsToolIds; } });
54
+ Object.defineProperty(exports, "getDeviceOperationsContractDefinition", { enumerable: true, get: function () { return device_operations_contract_1.getDeviceOperationsContractDefinition; } });
46
55
  var logs_contract_1 = require("./system/logs-contract");
47
56
  Object.defineProperty(exports, "getLogsContractDefinition", { enumerable: true, get: function () { return logs_contract_1.getLogsContractDefinition; } });
48
57
  Object.defineProperty(exports, "LOGS_CONTRACT_VERSION", { enumerable: true, get: function () { return logs_contract_1.LOGS_CONTRACT_VERSION; } });
@@ -0,0 +1,72 @@
1
+ import type { ITool } from "../../data/tools";
2
+ import type { IContractDefinition } from "../types";
3
+ /** Version of the built-in System Device Operations contract. */
4
+ export declare const DEVICE_OPERATIONS_CONTRACT_VERSION = 1;
5
+ /** Maximum SQL text accepted by the remote database operation. */
6
+ export declare const DEVICE_OPERATIONS_MAX_QUERY_LENGTH = 20000;
7
+ /** Maximum rows returned by one remote database operation. */
8
+ export declare const DEVICE_OPERATIONS_MAX_ROWS = 500;
9
+ /** Maximum serialized result size returned by one remote database operation. */
10
+ export declare const DEVICE_OPERATIONS_MAX_RESULT_BYTES = 1000000;
11
+ /** Maximum tools returned by one remote tool-list operation. */
12
+ export declare const DEVICE_OPERATIONS_MAX_TOOLS = 100;
13
+ /** Stable IDs for the live tools implementing System Device Operations v1. */
14
+ export declare const deviceOperationsToolIds: {
15
+ readonly getDeviceStatus: "00mriijkhr4iptdefp4a7ifcq";
16
+ readonly queryDatabase: "00mriijkhrd54n33ey0omeejo";
17
+ readonly listTools: "00mriijkhr4fpyd70nyo5iqlq";
18
+ readonly getTool: "00mriijkhrid4wpf89i4ikvay";
19
+ readonly runTool: "00mriijkhrfequch2qaeoihol";
20
+ };
21
+ /** Portable operations supported by System Device Operations v1. */
22
+ export type DeviceOperationCapability = "device-status" | "database-query" | "tool-list" | "tool-get" | "tool-run";
23
+ /** Status and capability information returned by a remote device. */
24
+ export interface IDeviceOperationStatus {
25
+ deviceId: string;
26
+ userId: string;
27
+ dataContextId: string;
28
+ contractVersion: number;
29
+ capabilities: DeviceOperationCapability[];
30
+ limits: {
31
+ maxQueryLength: number;
32
+ maxRows: number;
33
+ maxResultBytes: number;
34
+ maxTools: number;
35
+ };
36
+ }
37
+ /** Input for a bounded, read-only remote SQLite query. */
38
+ export interface IDeviceDatabaseQueryInput {
39
+ query: string;
40
+ }
41
+ /** Serializable result from a bounded, read-only remote SQLite query. */
42
+ export interface IDeviceDatabaseQueryResult {
43
+ columns: string[];
44
+ rows: unknown[][];
45
+ rowCount: number;
46
+ truncated: boolean;
47
+ }
48
+ /** Input for listing tools available in the selected data context. */
49
+ export interface IDeviceToolListInput {
50
+ limit?: number;
51
+ }
52
+ /** Input for exact-ID, exact-name, or unambiguous-text tool lookup. */
53
+ export interface IDeviceToolLookupInput {
54
+ toolIdOrName: string;
55
+ }
56
+ /** Input for running a tool on the remote device. */
57
+ export interface IDeviceToolRunInput extends IDeviceToolLookupInput {
58
+ args?: Record<string, unknown>;
59
+ assistantId?: string;
60
+ }
61
+ /** Result of an unambiguous tool lookup, or `null` when no tool matched. */
62
+ export type IDeviceToolLookupResult = ITool | null;
63
+ /**
64
+ * Return the portable, owner-authorized device administration contract shape.
65
+ *
66
+ * The contract intentionally exposes explicit operations instead of arbitrary table,
67
+ * filesystem, shell, UI, or lifecycle access. Authorization is supplied by the verified
68
+ * connection host before the live resolver is invoked.
69
+ */
70
+ export declare function getDeviceOperationsContractDefinition(): IContractDefinition;
71
+ /** Package ID used by live System Device Operations tool instances. */
72
+ export declare const deviceOperationsProviderPackageId = "000peers0system0000000001";
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deviceOperationsProviderPackageId = exports.deviceOperationsToolIds = exports.DEVICE_OPERATIONS_MAX_TOOLS = exports.DEVICE_OPERATIONS_MAX_RESULT_BYTES = exports.DEVICE_OPERATIONS_MAX_ROWS = exports.DEVICE_OPERATIONS_MAX_QUERY_LENGTH = exports.DEVICE_OPERATIONS_CONTRACT_VERSION = void 0;
4
+ exports.getDeviceOperationsContractDefinition = getDeviceOperationsContractDefinition;
5
+ const system_ids_1 = require("../../system-ids");
6
+ const field_type_1 = require("../../types/field-type");
7
+ /** Version of the built-in System Device Operations contract. */
8
+ exports.DEVICE_OPERATIONS_CONTRACT_VERSION = 1;
9
+ /** Maximum SQL text accepted by the remote database operation. */
10
+ exports.DEVICE_OPERATIONS_MAX_QUERY_LENGTH = 20_000;
11
+ /** Maximum rows returned by one remote database operation. */
12
+ exports.DEVICE_OPERATIONS_MAX_ROWS = 500;
13
+ /** Maximum serialized result size returned by one remote database operation. */
14
+ exports.DEVICE_OPERATIONS_MAX_RESULT_BYTES = 1_000_000;
15
+ /** Maximum tools returned by one remote tool-list operation. */
16
+ exports.DEVICE_OPERATIONS_MAX_TOOLS = 100;
17
+ /** Stable IDs for the live tools implementing System Device Operations v1. */
18
+ exports.deviceOperationsToolIds = {
19
+ getDeviceStatus: "00mriijkhr4iptdefp4a7ifcq",
20
+ queryDatabase: "00mriijkhrd54n33ey0omeejo",
21
+ listTools: "00mriijkhr4fpyd70nyo5iqlq",
22
+ getTool: "00mriijkhrid4wpf89i4ikvay",
23
+ runTool: "00mriijkhrfequch2qaeoihol",
24
+ };
25
+ const field = (name, type, description, opts = {}) => ({ name, type, description, ...opts });
26
+ let definition;
27
+ /**
28
+ * Return the portable, owner-authorized device administration contract shape.
29
+ *
30
+ * The contract intentionally exposes explicit operations instead of arbitrary table,
31
+ * filesystem, shell, UI, or lifecycle access. Authorization is supplied by the verified
32
+ * connection host before the live resolver is invoked.
33
+ */
34
+ function getDeviceOperationsContractDefinition() {
35
+ definition ??= {
36
+ contractId: system_ids_1.deviceOperationsContractId,
37
+ version: exports.DEVICE_OPERATIONS_CONTRACT_VERSION,
38
+ devTag: "dev",
39
+ name: "System Device Operations",
40
+ description: "Owner-authorized status, bounded read-only database, and installed-tool operations.",
41
+ tables: [],
42
+ tools: [
43
+ {
44
+ name: "getDeviceStatus",
45
+ usageDescription: "Return this device's identity, supported operations, and limits.",
46
+ inputFields: [],
47
+ outputFields: [
48
+ field("deviceId", field_type_1.FieldType.id, "The provider device ID."),
49
+ field("userId", field_type_1.FieldType.id, "The provider user ID."),
50
+ field("dataContextId", field_type_1.FieldType.id, "The selected data context ID."),
51
+ field("contractVersion", field_type_1.FieldType.number, "The supported contract version."),
52
+ field("capabilities", field_type_1.FieldType.string, "Supported portable operations.", {
53
+ isArray: true,
54
+ }),
55
+ field("limits", field_type_1.FieldType.object, "Provider-enforced request and result limits."),
56
+ ],
57
+ },
58
+ {
59
+ name: "queryDatabase",
60
+ usageDescription: "Run one bounded read-only SELECT or approved PRAGMA query.",
61
+ inputFields: [field("query", field_type_1.FieldType.string, "One read-only SQLite statement.")],
62
+ outputFields: [
63
+ field("columns", field_type_1.FieldType.string, "Result column names.", { isArray: true }),
64
+ field("rows", field_type_1.FieldType.any, "Serializable result rows.", { isArray: true }),
65
+ field("rowCount", field_type_1.FieldType.number, "Number of returned rows."),
66
+ field("truncated", field_type_1.FieldType.boolean, "Whether rows were omitted by provider limits."),
67
+ ],
68
+ },
69
+ {
70
+ name: "listTools",
71
+ usageDescription: "List installed tools in the selected data context.",
72
+ inputFields: [
73
+ field("limit", field_type_1.FieldType.number, "Maximum tools to return.", { optional: true }),
74
+ ],
75
+ outputFields: [
76
+ field("tools", field_type_1.FieldType.object, "Installed tool definitions.", { isArray: true }),
77
+ ],
78
+ },
79
+ {
80
+ name: "getTool",
81
+ usageDescription: "Resolve a tool by exact ID, exact name, or unambiguous text.",
82
+ inputFields: [
83
+ field("toolIdOrName", field_type_1.FieldType.string, "Tool ID, exact name, or search text."),
84
+ ],
85
+ outputFields: [
86
+ field("tool", field_type_1.FieldType.object, "The matching tool definition, or null.", {
87
+ optional: true,
88
+ }),
89
+ ],
90
+ },
91
+ {
92
+ name: "runTool",
93
+ usageDescription: "Resolve and run an installed tool in the selected data context.",
94
+ inputFields: [
95
+ field("toolIdOrName", field_type_1.FieldType.string, "Tool ID, exact name, or search text."),
96
+ field("args", field_type_1.FieldType.object, "Tool input arguments.", { optional: true }),
97
+ field("assistantId", field_type_1.FieldType.id, "Optional assistant execution context.", {
98
+ optional: true,
99
+ }),
100
+ ],
101
+ outputFields: [field("result", field_type_1.FieldType.any, "The tool execution result.")],
102
+ },
103
+ ],
104
+ observables: [],
105
+ events: [],
106
+ };
107
+ return definition;
108
+ }
109
+ /** Package ID used by live System Device Operations tool instances. */
110
+ exports.deviceOperationsProviderPackageId = system_ids_1.peersSystemPackageId;
@@ -18,8 +18,8 @@ export declare const assistantSchema: z.ZodObject<{
18
18
  packageId: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
19
19
  }, "strip", z.ZodTypeAny, {
20
20
  name: string;
21
- createdAt: Date;
22
21
  assistantId: string;
22
+ createdAt: Date;
23
23
  assistantRunnerToolId: string;
24
24
  assistantRunnerConfig: {} & {
25
25
  [k: string]: any;
@@ -42,10 +42,10 @@ export declare const assistantSchema: z.ZodObject<{
42
42
  toolInclusionStrategy?: ToolInclusionStrategy | undefined;
43
43
  }>;
44
44
  export type IAssistant = z.infer<typeof assistantSchema>;
45
- export declare function Assistants(dataContext?: DataContext): import("./orm").Table<{
45
+ export declare function Assistants(dataContext?: DataContext): import("..").Table<{
46
46
  name: string;
47
- createdAt: Date;
48
47
  assistantId: string;
48
+ createdAt: Date;
49
49
  assistantRunnerToolId: string;
50
50
  assistantRunnerConfig: {} & {
51
51
  [k: string]: any;
@@ -68,8 +68,8 @@ export declare const userPrimaryAssistantVar: import("./persistent-vars").Persis
68
68
  export declare const groupPrimaryAssistantVar: import("./persistent-vars").PersistentVar<string | undefined>;
69
69
  export declare const getPrimaryAssistant: (dataContext?: DataContext) => Promise<{
70
70
  name: string;
71
- createdAt: Date;
72
71
  assistantId: string;
72
+ createdAt: Date;
73
73
  assistantRunnerToolId: string;
74
74
  assistantRunnerConfig: {} & {
75
75
  [k: string]: any;
@@ -20,7 +20,7 @@ export declare const channelSchema: z.ZodObject<{
20
20
  owningGroupId: string;
21
21
  }>;
22
22
  export type IChannel = z.infer<typeof channelSchema>;
23
- export declare function Channels(dataContext?: DataContext): import("./orm").Table<{
23
+ export declare function Channels(dataContext?: DataContext): import("..").Table<{
24
24
  name: string;
25
25
  description: string;
26
26
  createdAt: Date;
@@ -38,7 +38,7 @@ export interface IDeviceHandshake extends IDeviceInfo {
38
38
  serverAddress: string;
39
39
  timestamp: number;
40
40
  }
41
- export declare function Devices(dataContext?: DataContext): import("./orm").Table<{
41
+ export declare function Devices(dataContext?: DataContext): import("..").Table<{
42
42
  userId: string;
43
43
  deviceId: string;
44
44
  firstSeen: Date;
@@ -34,7 +34,7 @@ export declare const embeddingSchema: z.ZodObject<{
34
34
  embeddingType: string;
35
35
  }>;
36
36
  export type IEmbedding = z.infer<typeof embeddingSchema>;
37
- export declare function Embeddings(dataContext?: DataContext): import("./orm").Table<{
37
+ export declare function Embeddings(dataContext?: DataContext): import("..").Table<{
38
38
  metadata: {
39
39
  fkId?: string | undefined;
40
40
  } & {
@@ -0,0 +1,21 @@
1
+ import type { DataContext } from "../context/data-context";
2
+ import { type IPublicKeys, type IPublicPrivateKeys } from "../keys";
3
+ import { type IPersistentVar } from "./persistent-vars";
4
+ /** Prefix used for each group's encrypted secret-key persistent variable. */
5
+ export declare const GROUP_SECRET_KEY_PVAR_PREFIX = "groupSecretKey_";
6
+ /** Return the personal-context persistent-variable name for a group secret key. */
7
+ export declare function groupSecretKeyPvarName(groupId: string): string;
8
+ /**
9
+ * Derive a group secret's public keys and verify they match the signed group record.
10
+ *
11
+ * @throws When the secret is malformed or derives different signing/box public keys.
12
+ */
13
+ export declare function validateGroupSecretKey(secretKey: string, expected: IPublicKeys): IPublicPrivateKeys;
14
+ /**
15
+ * Save a known-valid group secret in the user's personal context.
16
+ *
17
+ * Legacy random IDs and duplicate name rows are canonicalized before the replacement is
18
+ * encrypted and saved. The caller must supply the expected signed group public keys, so this
19
+ * function cannot silently install unrelated key material.
20
+ */
21
+ export declare function saveGroupSecretKey(userDataContext: DataContext, groupId: string, secretKey: string, expected: IPublicKeys): Promise<IPersistentVar>;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GROUP_SECRET_KEY_PVAR_PREFIX = void 0;
4
+ exports.groupSecretKeyPvarName = groupSecretKeyPvarName;
5
+ exports.validateGroupSecretKey = validateGroupSecretKey;
6
+ exports.saveGroupSecretKey = saveGroupSecretKey;
7
+ const keys_1 = require("../keys");
8
+ const utils_1 = require("../utils");
9
+ const persistent_vars_1 = require("./persistent-vars");
10
+ /** Prefix used for each group's encrypted secret-key persistent variable. */
11
+ exports.GROUP_SECRET_KEY_PVAR_PREFIX = "groupSecretKey_";
12
+ /** Return the personal-context persistent-variable name for a group secret key. */
13
+ function groupSecretKeyPvarName(groupId) {
14
+ return `${exports.GROUP_SECRET_KEY_PVAR_PREFIX}${groupId}`;
15
+ }
16
+ /**
17
+ * Derive a group secret's public keys and verify they match the signed group record.
18
+ *
19
+ * @throws When the secret is malformed or derives different signing/box public keys.
20
+ */
21
+ function validateGroupSecretKey(secretKey, expected) {
22
+ const derived = (0, keys_1.hydrateKeys)(secretKey);
23
+ if (derived.publicKey !== expected.publicKey || derived.publicBoxKey !== expected.publicBoxKey) {
24
+ throw new Error("Group secret key does not match the group's public keys");
25
+ }
26
+ return derived;
27
+ }
28
+ /**
29
+ * Save a known-valid group secret in the user's personal context.
30
+ *
31
+ * Legacy random IDs and duplicate name rows are canonicalized before the replacement is
32
+ * encrypted and saved. The caller must supply the expected signed group public keys, so this
33
+ * function cannot silently install unrelated key material.
34
+ */
35
+ async function saveGroupSecretKey(userDataContext, groupId, secretKey, expected) {
36
+ validateGroupSecretKey(secretKey, expected);
37
+ const name = groupSecretKeyPvarName(groupId);
38
+ const table = (0, persistent_vars_1.PersistentVars)(userDataContext);
39
+ const records = await table.list({ name });
40
+ let canonical = records.find((record) => record.persistentVarId === (0, utils_1.deterministicPvarId)(name));
41
+ for (const record of records) {
42
+ if (record !== canonical) {
43
+ canonical = await table.migrateLegacyId(record);
44
+ }
45
+ }
46
+ return table.save({
47
+ persistentVarId: canonical?.persistentVarId ?? "",
48
+ name,
49
+ scope: "groupUser",
50
+ isSecret: true,
51
+ value: { value: secretKey },
52
+ });
53
+ }
@@ -8,6 +8,7 @@ export * from "./files";
8
8
  export * from "./group-member-roles";
9
9
  export * from "./group-members";
10
10
  export * from "./group-permissions";
11
+ export * from "./group-secret";
11
12
  export * from "./group-share";
12
13
  export * from "./groups";
13
14
  export * from "./messages";
@@ -24,6 +24,7 @@ __exportStar(require("./files"), exports);
24
24
  __exportStar(require("./group-member-roles"), exports);
25
25
  __exportStar(require("./group-members"), exports);
26
26
  __exportStar(require("./group-permissions"), exports);
27
+ __exportStar(require("./group-secret"), exports);
27
28
  __exportStar(require("./group-share"), exports);
28
29
  __exportStar(require("./groups"), exports);
29
30
  __exportStar(require("./messages"), exports);
@@ -35,7 +35,7 @@ export declare const messageSchema: z.ZodObject<{
35
35
  fileIds?: string[] | undefined;
36
36
  }>;
37
37
  export type IMessage = z.infer<typeof messageSchema>;
38
- export declare function Messages(dataContext?: DataContext): import("./orm").Table<{
38
+ export declare function Messages(dataContext?: DataContext): import("..").Table<{
39
39
  message: string;
40
40
  userId: string;
41
41
  createdAt: Date;
@@ -54,8 +54,8 @@ declare const schema: z.ZodObject<{
54
54
  version: string;
55
55
  signature: string;
56
56
  packageId: string;
57
- createdBy: string;
58
57
  createdAt: string;
58
+ createdBy: string;
59
59
  packageVersionId: string;
60
60
  packageVersionHash: string;
61
61
  packageBundleFileId: string;
@@ -82,8 +82,8 @@ declare const schema: z.ZodObject<{
82
82
  version: string;
83
83
  signature: string;
84
84
  packageId: string;
85
- createdBy: string;
86
85
  createdAt: string;
86
+ createdBy: string;
87
87
  packageVersionId: string;
88
88
  packageVersionHash: string;
89
89
  packageBundleFileId: string;
@@ -91,7 +91,7 @@ declare const valueTypeSchema: z.ZodObject<{
91
91
  iconClass?: string | undefined;
92
92
  }>;
93
93
  export type IPeerType = z.infer<typeof valueTypeSchema>;
94
- export declare function PeerTypes(dataContext?: DataContext): import("./orm").Table<{
94
+ export declare function PeerTypes(dataContext?: DataContext): import("..").Table<{
95
95
  name: string;
96
96
  schema: {
97
97
  type: import("./tools").IOSchemaType;
@@ -52,20 +52,37 @@ declare const schema: z.ZodObject<{
52
52
  modifiedAt?: number | undefined;
53
53
  packageId?: string | undefined;
54
54
  }>;
55
+ /** Table metadata for persisted observable variables. */
55
56
  export declare const persistentVarsMetaData: ITableMetaData;
57
+ /** Stored record for one persistent variable. */
56
58
  export type IPersistentVar = z.infer<typeof schema>;
59
+ /** Persistent-variable table with deterministic IDs and secret-value handling. */
57
60
  export declare class PersistentVarsTable extends Table<IPersistentVar> {
61
+ /** Insert a persistent variable through the canonical save path. */
58
62
  insert(persistentVar: IPersistentVar): Promise<IPersistentVar>;
63
+ /** Update a persistent variable through the canonical save path. */
59
64
  update(persistentVar: IPersistentVar): Promise<IPersistentVar>;
65
+ /** Save a variable, assigning its deterministic ID and encrypting new secret plaintext. */
60
66
  save(persistentVar: IPersistentVar, opts?: ISaveOptions): Promise<IPersistentVar>;
67
+ /**
68
+ * Replace a legacy random record ID without re-encrypting its already-stored value.
69
+ *
70
+ * Migration is storage-only: the value and modified timestamp are preserved. If the
71
+ * deterministic record already exists, it wins and the duplicate legacy row is removed.
72
+ */
73
+ migrateLegacyId(persistentVar: IPersistentVar): Promise<IPersistentVar>;
74
+ /** Return a stored variable's raw value by name. */
61
75
  getPersistentVarValue<T>(name: string): Promise<T | undefined>;
62
76
  }
77
+ /** Return the persistent-variable table for a data context. */
63
78
  export declare function PersistentVars(dataContext?: DataContext): PersistentVarsTable;
79
+ /** Reactive persistent value with an awaitable initial load and explicit deletion. */
64
80
  export type PersistentVar<T> = Observable<T> & {
65
81
  loadingPromise: Promise<PersistentVar<T>>;
66
82
  /** Delete the persistent variable from the database and reset to default value */
67
83
  delete: () => Promise<void>;
68
84
  };
85
+ /** Resolve a persistent-variable record by name, preferring device scope. */
69
86
  export declare function getPersistentVar(name: string, dataContext?: DataContext): Promise<IPersistentVar | undefined>;
70
87
  interface IPersistentVarOptionsBase {
71
88
  scope?: "device" | "user" | "group" | "groupDevice" | "groupUser";
@@ -5,6 +5,40 @@
5
5
  * Tests for this module are located in peers-device/src/persistent-vars.test.ts
6
6
  * (requires SQLite which is not available in peers-sdk)
7
7
  */
8
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
9
+ var useValue = arguments.length > 2;
10
+ for (var i = 0; i < initializers.length; i++) {
11
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
12
+ }
13
+ return useValue ? value : void 0;
14
+ };
15
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
16
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
17
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
18
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
19
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
20
+ var _, done = false;
21
+ for (var i = decorators.length - 1; i >= 0; i--) {
22
+ var context = {};
23
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
24
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
25
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
26
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
27
+ if (kind === "accessor") {
28
+ if (result === void 0) continue;
29
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
30
+ if (_ = accept(result.get)) descriptor.get = _;
31
+ if (_ = accept(result.set)) descriptor.set = _;
32
+ if (_ = accept(result.init)) initializers.unshift(_);
33
+ }
34
+ else if (_ = accept(result)) {
35
+ if (kind === "field") initializers.unshift(_);
36
+ else descriptor[key] = _;
37
+ }
38
+ }
39
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
40
+ done = true;
41
+ };
8
42
  Object.defineProperty(exports, "__esModule", { value: true });
9
43
  exports.PersistentVarsTable = exports.persistentVarsMetaData = void 0;
10
44
  exports.PersistentVars = PersistentVars;
@@ -21,6 +55,7 @@ const observable_1 = require("../observable");
21
55
  const rpc_types_1 = require("../rpc-types");
22
56
  const zod_types_1 = require("../types/zod-types");
23
57
  const utils_1 = require("../utils");
58
+ const decorators_1 = require("./orm/decorators");
24
59
  const table_1 = require("./orm/table");
25
60
  const table_definitions_system_1 = require("./orm/table-definitions.system");
26
61
  const types_1 = require("./orm/types");
@@ -44,6 +79,7 @@ const schema = zod_1.z.object({
44
79
  .optional()
45
80
  .describe("The package that owns this persistent variable, if any"),
46
81
  });
82
+ /** Table metadata for persisted observable variables. */
47
83
  exports.persistentVarsMetaData = {
48
84
  name: "PersistentVars",
49
85
  description: "table to persist variables across sessions and devices",
@@ -52,46 +88,93 @@ exports.persistentVarsMetaData = {
52
88
  iconClassName: "bi bi-braces",
53
89
  indexes: [{ fields: ["name"], unique: true }],
54
90
  };
55
- class PersistentVarsTable extends table_1.Table {
56
- async insert(persistentVar) {
57
- return this.save(persistentVar);
58
- }
59
- async update(persistentVar) {
60
- return this.save(persistentVar);
61
- }
62
- async save(persistentVar, opts) {
63
- if (!persistentVar.persistentVarId) {
64
- persistentVar.persistentVarId = (0, utils_1.deterministicPvarId)(persistentVar.name);
91
+ /** Persistent-variable table with deterministic IDs and secret-value handling. */
92
+ let PersistentVarsTable = (() => {
93
+ let _classSuper = table_1.Table;
94
+ let _instanceExtraInitializers = [];
95
+ let _migrateLegacyId_decorators;
96
+ return class PersistentVarsTable extends _classSuper {
97
+ static {
98
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
99
+ _migrateLegacyId_decorators = [(0, decorators_1.ProxyClientTableMethodCalls)()];
100
+ __esDecorate(this, null, _migrateLegacyId_decorators, { kind: "method", name: "migrateLegacyId", static: false, private: false, access: { has: obj => "migrateLegacyId" in obj, get: obj => obj.migrateLegacyId }, metadata: _metadata }, null, _instanceExtraInitializers);
101
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
102
+ }
103
+ /** Insert a persistent variable through the canonical save path. */
104
+ async insert(persistentVar) {
105
+ return this.save(persistentVar);
106
+ }
107
+ /** Update a persistent variable through the canonical save path. */
108
+ async update(persistentVar) {
109
+ return this.save(persistentVar);
110
+ }
111
+ /** Save a variable, assigning its deterministic ID and encrypting new secret plaintext. */
112
+ async save(persistentVar, opts) {
113
+ if (!persistentVar.persistentVarId) {
114
+ persistentVar.persistentVarId = (0, utils_1.deterministicPvarId)(persistentVar.name);
115
+ }
116
+ const dbVar = await this.get(persistentVar.persistentVarId);
117
+ if (persistentVar.isSecret &&
118
+ persistentVar.value.value !== undefined &&
119
+ (!rpc_types_1.isClient || (0, rpc_types_1.isSingleProcessClient)())) {
120
+ if (!dbVar ||
121
+ dbVar.value.value !== persistentVar.value.value ||
122
+ dbVar.isSecret !== persistentVar.isSecret) {
123
+ persistentVar.value.value = await rpc_types_1.rpcServerCalls.encryptData(persistentVar.value.value || "", this.groupId);
124
+ }
125
+ }
126
+ persistentVar.modifiedAt = Date.now();
127
+ opts ??= {};
128
+ opts = { saveAsSnapshot: true, ...opts };
129
+ return super.save(persistentVar, opts);
130
+ }
131
+ /**
132
+ * Replace a legacy random record ID without re-encrypting its already-stored value.
133
+ *
134
+ * Migration is storage-only: the value and modified timestamp are preserved. If the
135
+ * deterministic record already exists, it wins and the duplicate legacy row is removed.
136
+ */
137
+ async migrateLegacyId(persistentVar) {
138
+ if ((0, utils_1.isDeterministicPvarId)(persistentVar.persistentVarId)) {
139
+ return persistentVar;
140
+ }
141
+ const deterministicId = (0, utils_1.deterministicPvarId)(persistentVar.name);
142
+ const existing = await this.get(deterministicId);
143
+ await super.delete(persistentVar);
144
+ if (existing) {
145
+ return existing;
146
+ }
147
+ const migrated = { ...persistentVar, persistentVarId: deterministicId };
148
+ try {
149
+ return await super.save(migrated, { saveAsSnapshot: true });
150
+ }
151
+ catch (error) {
152
+ await super.save(persistentVar, { saveAsSnapshot: true }).catch(() => { });
153
+ throw error;
154
+ }
65
155
  }
66
- const dbVar = await this.get(persistentVar.persistentVarId);
67
- if (persistentVar.isSecret &&
68
- persistentVar.value.value !== undefined &&
69
- (!rpc_types_1.isClient || (0, rpc_types_1.isSingleProcessClient)())) {
70
- if (!dbVar ||
71
- dbVar.value.value !== persistentVar.value.value ||
72
- dbVar.isSecret !== persistentVar.isSecret) {
73
- persistentVar.value.value = await rpc_types_1.rpcServerCalls.encryptData(persistentVar.value.value || "", this.groupId);
156
+ /** Return a stored variable's raw value by name. */
157
+ async getPersistentVarValue(name) {
158
+ const pVars = await this.list({ name });
159
+ if (pVars.length > 1) {
160
+ console.warn(`Multiple persistent variables found with name "${name}". Using the last one.`);
74
161
  }
162
+ const pVar = pVars[pVars.length - 1];
163
+ return pVar?.value?.value;
75
164
  }
76
- persistentVar.modifiedAt = Date.now();
77
- opts ??= {};
78
- opts = { saveAsSnapshot: true, ...opts };
79
- return super.save(persistentVar, opts);
80
- }
81
- async getPersistentVarValue(name) {
82
- const pVars = await this.list({ name });
83
- if (pVars.length > 1) {
84
- console.warn(`Multiple persistent variables found with name "${name}". Using the last one.`);
165
+ constructor() {
166
+ super(...arguments);
167
+ __runInitializers(this, _instanceExtraInitializers);
85
168
  }
86
- const pVar = pVars[pVars.length - 1];
87
- return pVar?.value?.value;
88
- }
89
- }
169
+ };
170
+ })();
90
171
  exports.PersistentVarsTable = PersistentVarsTable;
91
172
  (0, table_definitions_system_1.registerSystemTableDefinition)(exports.persistentVarsMetaData, schema, PersistentVarsTable);
173
+ /** Return the persistent-variable table for a data context. */
92
174
  function PersistentVars(dataContext) {
93
175
  return (0, user_context_singleton_1.getTableContainer)(dataContext).getTable(exports.persistentVarsMetaData, schema, PersistentVarsTable);
94
176
  }
177
+ /** Resolve a persistent-variable record by name, preferring device scope. */
95
178
  async function getPersistentVar(name, dataContext) {
96
179
  const pVars = await PersistentVars(dataContext).list({ name });
97
180
  if (!pVars.length) {
@@ -210,10 +293,7 @@ function persistentVarFactory(name, opts) {
210
293
  }
211
294
  }
212
295
  if (dbRec && !(0, utils_1.isDeterministicPvarId)(dbRec.persistentVarId)) {
213
- const newId = (0, utils_1.deterministicPvarId)(name);
214
- await table.delete(dbRec);
215
- dbRec.persistentVarId = newId;
216
- dbRec = await table.save(dbRec);
296
+ dbRec = await table.migrateLegacyId(dbRec);
217
297
  }
218
298
  if (!dbRec) {
219
299
  dbRec = {
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const originalClientFlag = process.env.PEERS_IS_CLIENT;
4
+ function createEventRegistry() {
5
+ return {
6
+ getEmitter: jest.fn().mockReturnValue({
7
+ event: { subscribe: jest.fn() },
8
+ emit: jest.fn(),
9
+ }),
10
+ };
11
+ }
12
+ function createLegacyRecord(name) {
13
+ return {
14
+ persistentVarId: "00mriijkhq94msfe9m2j6quwp",
15
+ name,
16
+ scope: "device",
17
+ isSecret: true,
18
+ value: { value: "encrypted:ciphertext" },
19
+ modifiedAt: 1234,
20
+ };
21
+ }
22
+ afterEach(() => {
23
+ if (originalClientFlag === undefined) {
24
+ delete process.env.PEERS_IS_CLIENT;
25
+ }
26
+ else {
27
+ process.env.PEERS_IS_CLIENT = originalClientFlag;
28
+ }
29
+ jest.resetModules();
30
+ jest.restoreAllMocks();
31
+ });
32
+ describe("PersistentVars legacy ID migration", () => {
33
+ it("uses one custom table RPC from a renderer client", async () => {
34
+ process.env.PEERS_IS_CLIENT = "true";
35
+ jest.resetModules();
36
+ await jest.isolateModulesAsync(async () => {
37
+ jest.doMock("../context/user-context-singleton", () => ({
38
+ getTableContainer: jest.fn(),
39
+ getUserContext: jest.fn(),
40
+ }));
41
+ const { PersistentVarsTable, persistentVarsMetaData } = await Promise.resolve().then(() => require("./persistent-vars"));
42
+ const { ClientProxyDataSource } = await Promise.resolve().then(() => require("./orm/client-proxy.data-source"));
43
+ const { rpcServerCalls } = await Promise.resolve().then(() => require("../rpc-types"));
44
+ const record = createLegacyRecord("rendererMigration");
45
+ const migrated = { ...record, persistentVarId: "00mriijkhq94msfe9m2j6quwq" };
46
+ const tableMethodCall = jest.fn().mockResolvedValue(migrated);
47
+ rpcServerCalls.tableMethodCall = tableMethodCall;
48
+ const dataContextId = "00mriijkhq94msfe9m2j6qabc";
49
+ const table = new PersistentVarsTable(persistentVarsMetaData, {
50
+ dataSource: new ClientProxyDataSource(persistentVarsMetaData, undefined, dataContextId),
51
+ eventRegistry: createEventRegistry(),
52
+ });
53
+ await expect(table.migrateLegacyId(record)).resolves.toEqual(migrated);
54
+ expect(tableMethodCall).toHaveBeenCalledTimes(1);
55
+ expect(tableMethodCall).toHaveBeenCalledWith(dataContextId, "PersistentVars", "migrateLegacyId", record);
56
+ });
57
+ });
58
+ it("removes a legacy duplicate when the canonical record already exists", async () => {
59
+ delete process.env.PEERS_IS_CLIENT;
60
+ jest.resetModules();
61
+ await jest.isolateModulesAsync(async () => {
62
+ jest.doMock("../context/user-context-singleton", () => ({
63
+ getTableContainer: jest.fn(),
64
+ getUserContext: jest.fn(),
65
+ }));
66
+ const { PersistentVarsTable, persistentVarsMetaData } = await Promise.resolve().then(() => require("./persistent-vars"));
67
+ const { deterministicPvarId } = await Promise.resolve().then(() => require("../utils"));
68
+ const legacy = createLegacyRecord("existingCanonical");
69
+ const canonical = {
70
+ ...legacy,
71
+ persistentVarId: deterministicPvarId(legacy.name),
72
+ value: { value: "encrypted:canonical" },
73
+ };
74
+ const deleteRecord = jest.fn().mockResolvedValue(undefined);
75
+ const save = jest.fn();
76
+ const table = new PersistentVarsTable(persistentVarsMetaData, {
77
+ dataSource: {
78
+ tableName: "PersistentVars",
79
+ primaryKeyName: "persistentVarId",
80
+ get: jest.fn().mockResolvedValue(canonical),
81
+ list: jest.fn(),
82
+ count: jest.fn(),
83
+ save,
84
+ insert: jest.fn(),
85
+ update: jest.fn(),
86
+ delete: deleteRecord,
87
+ },
88
+ eventRegistry: createEventRegistry(),
89
+ });
90
+ await expect(table.migrateLegacyId(legacy)).resolves.toEqual(canonical);
91
+ expect(deleteRecord).toHaveBeenCalledWith(legacy);
92
+ expect(save).not.toHaveBeenCalled();
93
+ });
94
+ });
95
+ it("restores the legacy record when writing the canonical ID fails", async () => {
96
+ delete process.env.PEERS_IS_CLIENT;
97
+ jest.resetModules();
98
+ await jest.isolateModulesAsync(async () => {
99
+ jest.doMock("../context/user-context-singleton", () => ({
100
+ getTableContainer: jest.fn(),
101
+ getUserContext: jest.fn(),
102
+ }));
103
+ const { PersistentVarsTable, persistentVarsMetaData } = await Promise.resolve().then(() => require("./persistent-vars"));
104
+ const legacy = createLegacyRecord("rollbackMigration");
105
+ const migrationError = new Error("canonical write failed");
106
+ const deleteRecord = jest.fn().mockResolvedValue(undefined);
107
+ const save = jest.fn().mockRejectedValueOnce(migrationError).mockResolvedValueOnce(legacy);
108
+ const table = new PersistentVarsTable(persistentVarsMetaData, {
109
+ dataSource: {
110
+ tableName: "PersistentVars",
111
+ primaryKeyName: "persistentVarId",
112
+ get: jest.fn().mockResolvedValue(undefined),
113
+ list: jest.fn(),
114
+ count: jest.fn(),
115
+ save,
116
+ insert: jest.fn(),
117
+ update: jest.fn(),
118
+ delete: deleteRecord,
119
+ },
120
+ eventRegistry: createEventRegistry(),
121
+ });
122
+ await expect(table.migrateLegacyId(legacy)).rejects.toBe(migrationError);
123
+ expect(deleteRecord).toHaveBeenCalledWith(legacy);
124
+ expect(save).toHaveBeenCalledTimes(2);
125
+ expect(save.mock.calls[0][0]).toMatchObject({
126
+ name: legacy.name,
127
+ value: legacy.value,
128
+ });
129
+ expect(save.mock.calls[0][0].persistentVarId).not.toBe(legacy.persistentVarId);
130
+ expect(save.mock.calls[1][0]).toEqual(legacy);
131
+ });
132
+ });
133
+ });
@@ -34,7 +34,7 @@ export type ITableDefinitionRecord = z.infer<typeof tableDefinitionRecordSchema>
34
34
  *
35
35
  * @param dataContext - Optional data context; when omitted the singleton context is used.
36
36
  */
37
- export declare function TableDefinitions(dataContext?: DataContext): import("./orm").Table<{
37
+ export declare function TableDefinitions(dataContext?: DataContext): import("..").Table<{
38
38
  name: string;
39
39
  metaData: {} & {
40
40
  [k: string]: any;
@@ -26,7 +26,7 @@ export declare const toolTestSchema: z.ZodObject<{
26
26
  mocks?: any;
27
27
  }>;
28
28
  export type IToolTest = z.infer<typeof toolTestSchema>;
29
- export declare function ToolTests(dataContext?: DataContext): import("./orm").Table<{
29
+ export declare function ToolTests(dataContext?: DataContext): import("..").Table<{
30
30
  code: string;
31
31
  description: string;
32
32
  toolId: string;
@@ -313,7 +313,7 @@ export interface IToolInstance {
313
313
  inputSchema?: z.ZodObject<any>;
314
314
  outputSchema?: z.ZodObject<any>;
315
315
  }
316
- export declare function Tools(dataContext?: DataContext): import("./orm").Table<{
316
+ export declare function Tools(dataContext?: DataContext): import("..").Table<{
317
317
  code: string;
318
318
  name: string;
319
319
  toolId: string;
@@ -27,7 +27,7 @@ export declare const userTrustLevelSchema: z.ZodObject<{
27
27
  /** A trust assignment for one user within a specific data context. */
28
28
  export type IUserTrustLevel = z.infer<typeof userTrustLevelSchema>;
29
29
  /** Returns the context-scoped table containing explicit user trust assignments. */
30
- export declare function UserTrustLevels(dataContext?: DataContext): import("./orm").Table<{
30
+ export declare function UserTrustLevels(dataContext?: DataContext): import("..").Table<{
31
31
  userId: string;
32
32
  trustLevel: TrustLevel;
33
33
  assignedAt?: Date | undefined;
@@ -23,7 +23,7 @@ export declare const voiceMessageSchema: z.ZodObject<{
23
23
  threadId?: string | undefined;
24
24
  }>;
25
25
  export type IVoiceMessage = z.infer<typeof voiceMessageSchema>;
26
- export declare function VoiceMessages(dataContext?: DataContext): import("./orm").Table<{
26
+ export declare function VoiceMessages(dataContext?: DataContext): import("..").Table<{
27
27
  content: string;
28
28
  role: "user" | "assistant";
29
29
  createdAt: Date;
@@ -66,7 +66,7 @@ export declare const workflowLogSchema: z.ZodObject<{
66
66
  isError?: boolean | undefined;
67
67
  }>;
68
68
  export type IWorkflowLog = z.infer<typeof workflowLogSchema>;
69
- export declare function WorkflowLogs(dataContext?: DataContext): import("./orm").Table<{
69
+ export declare function WorkflowLogs(dataContext?: DataContext): import("..").Table<{
70
70
  workflowLogId: string;
71
71
  workflowRunId: string;
72
72
  contextId: string;
@@ -32,6 +32,7 @@ export declare const workflowRunSchema: z.ZodObject<{
32
32
  parentWorkflowRunId: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
33
33
  defaultAssistantId: z.ZodEffects<z.ZodString, string, string>;
34
34
  }, "strip", z.ZodTypeAny, {
35
+ createdAt: Date;
35
36
  defaultAssistantId: string;
36
37
  instructions: {
37
38
  markdown?: string | undefined;
@@ -39,7 +40,6 @@ export declare const workflowRunSchema: z.ZodObject<{
39
40
  directCallToolId?: string | undefined;
40
41
  subWorkflowId?: string | undefined;
41
42
  }[];
42
- createdAt: Date;
43
43
  workflowRunId: string;
44
44
  parentMessageId: string;
45
45
  currentInstructionIndex: number;
@@ -57,6 +57,7 @@ export declare const workflowRunSchema: z.ZodObject<{
57
57
  defaultAssistantId: string;
58
58
  workflowRunId: string;
59
59
  parentMessageId: string;
60
+ createdAt?: Date | undefined;
60
61
  workflowId?: string | undefined;
61
62
  instructions?: {
62
63
  markdown?: string | undefined;
@@ -64,7 +65,6 @@ export declare const workflowRunSchema: z.ZodObject<{
64
65
  directCallToolId?: string | undefined;
65
66
  subWorkflowId?: string | undefined;
66
67
  }[] | undefined;
67
- createdAt?: Date | undefined;
68
68
  scheduleDT?: Date | undefined;
69
69
  currentInstructionIndex?: number | undefined;
70
70
  instructionResults?: any[] | undefined;
@@ -1,7 +1,9 @@
1
1
  import type { DataContext } from "../context/data-context";
2
- export declare function Workflows(dataContext?: DataContext): import("./orm").Table<{
2
+ export declare function Workflows(dataContext?: DataContext): import("..").Table<{
3
3
  name: string;
4
4
  description: string;
5
+ createdAt: Date;
6
+ updatedAt: Date;
5
7
  workflowId: string;
6
8
  defaultAssistantId: string;
7
9
  instructions: {
@@ -11,7 +13,5 @@ export declare function Workflows(dataContext?: DataContext): import("./orm").Ta
11
13
  subWorkflowId?: string | undefined;
12
14
  }[];
13
15
  createdBy: string;
14
- createdAt: Date;
15
- updatedAt: Date;
16
16
  packageId?: string | undefined;
17
17
  }>;
@@ -1,7 +1,12 @@
1
+ import type { IDeviceDatabaseQueryResult, IDeviceOperationStatus, IDeviceToolRunInput } from "./contracts/system/device-operations-contract";
2
+ import type { ITool } from "./data/tools";
3
+ import type { IConsoleLog } from "./logging/console-logs.table";
4
+ /** Named event payload sent across the frontend RPC bridge. */
1
5
  export interface IEventData<T = any> {
2
6
  name: string;
3
7
  data: T;
4
8
  }
9
+ /** Serializable description of one interactive UI element. */
5
10
  export interface UIElement {
6
11
  tag: string;
7
12
  text?: string;
@@ -18,6 +23,7 @@ export interface UIElement {
18
23
  height: number;
19
24
  };
20
25
  }
26
+ /** Serializable renderer state returned to CLI UI-inspection commands. */
21
27
  export interface UIState {
22
28
  url: string;
23
29
  title: string;
@@ -25,6 +31,24 @@ export interface UIState {
25
31
  text: string;
26
32
  elements: UIElement[];
27
33
  }
34
+ /** One verified direct device connection exposed by the local Electron bridge. */
35
+ export interface IConnectedDeviceSummary {
36
+ deviceId: string;
37
+ userId: string;
38
+ connectionId: string;
39
+ connectionAddress?: string;
40
+ trustLevel: number;
41
+ verified: boolean;
42
+ }
43
+ /** Filters and bounds for one remote System Logs query. */
44
+ export interface IRemoteLogsQueryInput {
45
+ dataContextId?: string;
46
+ filter?: Record<string, unknown>;
47
+ pageSize?: number;
48
+ sortBy?: string[];
49
+ textSearch?: string;
50
+ }
51
+ /** RPC methods implemented by the trusted local server/main process. */
28
52
  export declare const rpcServerCalls: {
29
53
  ping: (msg: string) => Promise<string>;
30
54
  openLinkInBrowser: (url: string) => Promise<void>;
@@ -102,6 +126,13 @@ export declare const rpcServerCalls: {
102
126
  rowCount: number;
103
127
  }>;
104
128
  runTool: (toolId: string, args: Record<string, any>, dataContextId?: string, assistantId?: string) => Promise<any>;
129
+ listConnectedDevices: () => Promise<IConnectedDeviceSummary[]>;
130
+ getRemoteDeviceStatus: (deviceId: string, dataContextId?: string) => Promise<IDeviceOperationStatus>;
131
+ remoteDbQuery: (deviceId: string, query: string, dataContextId?: string) => Promise<IDeviceDatabaseQueryResult>;
132
+ remoteListTools: (deviceId: string, limit?: number, dataContextId?: string) => Promise<ITool[]>;
133
+ remoteGetTool: (deviceId: string, toolIdOrName: string, dataContextId?: string) => Promise<ITool | null>;
134
+ remoteRunTool: (deviceId: string, input: IDeviceToolRunInput, dataContextId?: string) => Promise<unknown>;
135
+ remoteQueryLogs: (deviceId: string, input?: IRemoteLogsQueryInput) => Promise<IConsoleLog[]>;
105
136
  uiReload: (options?: {
106
137
  ignoreCache?: boolean;
107
138
  }) => Promise<void>;
@@ -152,6 +183,7 @@ export declare const rpcServerCalls: {
152
183
  subscribePrefixes: (prefixes: string[]) => Promise<void>;
153
184
  unsubscribePrefixes: (prefixes: string[]) => Promise<void>;
154
185
  };
186
+ /** RPC methods implemented by renderer/frontend clients. */
155
187
  export declare const rpcClientCalls: {
156
188
  ping: (msg: string) => Promise<string>;
157
189
  emitEvent: (event: IEventData) => Promise<boolean>;
@@ -182,8 +214,13 @@ export declare const rpcClientCalls: {
182
214
  error?: string;
183
215
  }>;
184
216
  };
217
+ /** Name of a server/main-process RPC method. */
185
218
  export type RpcServerNames = keyof typeof rpcServerCalls;
219
+ /** Name of a renderer/frontend RPC method. */
186
220
  export type RpcClientNames = keyof typeof rpcClientCalls;
221
+ /** Whether this module is executing in a renderer, browser, or CLI client context. */
187
222
  export declare const isClient: boolean;
223
+ /** Mark the runtime as a single-process client such as the PWA. */
188
224
  export declare function setSingleProcessClient(value: boolean): void;
225
+ /** Return whether client and server responsibilities share one process. */
189
226
  export declare function isSingleProcessClient(): boolean;
package/dist/rpc-types.js CHANGED
@@ -10,6 +10,7 @@ function rpcStub(rpcName) {
10
10
  JSON.stringify({ rpcName, args }, null, 2));
11
11
  };
12
12
  }
13
+ /** RPC methods implemented by the trusted local server/main process. */
13
14
  exports.rpcServerCalls = {
14
15
  ping: async (msg) => `pong: ${msg}`,
15
16
  // TODO collapse these two down to just openPath
@@ -60,6 +61,14 @@ exports.rpcServerCalls = {
60
61
  dbQuery: rpcStub("dbQuery"),
61
62
  // Direct tool execution (for CLI)
62
63
  runTool: rpcStub("runTool"),
64
+ // Headless direct-device administration bridge (for CLI)
65
+ listConnectedDevices: rpcStub("listConnectedDevices"),
66
+ getRemoteDeviceStatus: rpcStub("getRemoteDeviceStatus"),
67
+ remoteDbQuery: rpcStub("remoteDbQuery"),
68
+ remoteListTools: rpcStub("remoteListTools"),
69
+ remoteGetTool: rpcStub("remoteGetTool"),
70
+ remoteRunTool: rpcStub("remoteRunTool"),
71
+ remoteQueryLogs: rpcStub("remoteQueryLogs"),
63
72
  // UI control (for CLI)
64
73
  uiReload: rpcStub("uiReload"),
65
74
  uiInspect: rpcStub("uiInspect"),
@@ -90,6 +99,7 @@ exports.rpcServerCalls = {
90
99
  subscribePrefixes: rpcStub("subscribePrefixes"),
91
100
  unsubscribePrefixes: rpcStub("unsubscribePrefixes"),
92
101
  };
102
+ /** RPC methods implemented by renderer/frontend clients. */
93
103
  exports.rpcClientCalls = {
94
104
  ping: async (msg) => `pong: ${msg}`,
95
105
  // emitEvent: rpcStub('emitEvent') as ((event: IEventData) => Promise<boolean>),
@@ -106,14 +116,17 @@ exports.rpcClientCalls = {
106
116
  // Check if we're in a client context (browser, webview, or CLI connected to server)
107
117
  // - Browser: window + document exist
108
118
  // - CLI: process.env.PEERS_IS_CLIENT === 'true'
119
+ /** Whether this module is executing in a renderer, browser, or CLI client context. */
109
120
  exports.isClient = (typeof window !== "undefined" && typeof document !== "undefined") ||
110
121
  (typeof process !== "undefined" && process.env?.PEERS_IS_CLIENT === "true");
111
122
  // Single-process mode (PWA): client and server live in the same process,
112
123
  // so Table events must NOT be suppressed on the client side.
113
124
  let _singleProcessClient = false;
125
+ /** Mark the runtime as a single-process client such as the PWA. */
114
126
  function setSingleProcessClient(value) {
115
127
  _singleProcessClient = value;
116
128
  }
129
+ /** Return whether client and server responsibilities share one process. */
117
130
  function isSingleProcessClient() {
118
131
  return _singleProcessClient;
119
132
  }
@@ -1,11 +1,20 @@
1
+ /** Stable user ID that owns built-in Peers system records. */
1
2
  export declare const peersRootUserId = "000peers0user000000000001";
3
+ /** Default assistant used when no user-selected assistant is available. */
2
4
  export declare const defaultAssistantId = "000peers0bot00000000shell";
5
+ /** Stable ID of the bundled OpenCode assistant. */
3
6
  export declare const openCodeAssistantId = "00mlwl2km2opencode0000001";
7
+ /** Stable ID of the default assistant-runner tool. */
4
8
  export declare const defaultAssistantRunnerToolId = "000peers0tool00000runner1";
9
+ /** Stable ID of the built-in send-message tool. */
5
10
  export declare const defaultSendMessageToolId = "000peers0tool00000sendmsg";
11
+ /** Stable ID of the built-in workflow runner tool. */
6
12
  export declare const runWorkflowToolId = "000peers0tool0runworkflow";
13
+ /** Stable package ID of the bundled peers-core package. */
7
14
  export declare const peersCorePackageId = "00mh0wlipjixk2gqmurbwee0o";
15
+ /** Canonical source repository for peers-core. */
8
16
  export declare const peersCorePackageRepoUrl = "https://github.com/peers-app/peers-core";
17
+ /** Trusted publishing key for official peers-core releases. */
9
18
  export declare const peersCorePublishPublicKey = "S7cQqnvVz-FVDO6Lk5zC7epSvcP_-NyBVZz9gdcj73c";
10
19
  /**
11
20
  * Stable id of the peers **system** itself, used as the `providerPackageId` for
@@ -18,3 +27,8 @@ export declare const peersSystemPackageId = "000peers0system0000000001";
18
27
  * contract-consumer-based remote RPC. See `contracts/system/logs-contract.ts`.
19
28
  */
20
29
  export declare const logsContractId = "000peers0logs000000000001";
30
+ /**
31
+ * Contract id for the built-in **System Device Operations** contract. The provider exposes
32
+ * explicit owner-authorized status, bounded read-only database, and installed-tool operations.
33
+ */
34
+ export declare const deviceOperationsContractId = "00mriijkhq94msfe9m2j6quwp";
@@ -1,15 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.logsContractId = exports.peersSystemPackageId = exports.peersCorePublishPublicKey = exports.peersCorePackageRepoUrl = exports.peersCorePackageId = exports.runWorkflowToolId = exports.defaultSendMessageToolId = exports.defaultAssistantRunnerToolId = exports.openCodeAssistantId = exports.defaultAssistantId = exports.peersRootUserId = void 0;
3
+ exports.deviceOperationsContractId = exports.logsContractId = exports.peersSystemPackageId = exports.peersCorePublishPublicKey = exports.peersCorePackageRepoUrl = exports.peersCorePackageId = exports.runWorkflowToolId = exports.defaultSendMessageToolId = exports.defaultAssistantRunnerToolId = exports.openCodeAssistantId = exports.defaultAssistantId = exports.peersRootUserId = void 0;
4
+ /** Stable user ID that owns built-in Peers system records. */
4
5
  exports.peersRootUserId = "000peers0user000000000001";
6
+ /** Default assistant used when no user-selected assistant is available. */
5
7
  exports.defaultAssistantId = "000peers0bot00000000shell";
6
8
  // export const defaultAssistantId = '000peers0bot000000000bot1';
9
+ /** Stable ID of the bundled OpenCode assistant. */
7
10
  exports.openCodeAssistantId = "00mlwl2km2opencode0000001";
11
+ /** Stable ID of the default assistant-runner tool. */
8
12
  exports.defaultAssistantRunnerToolId = "000peers0tool00000runner1";
13
+ /** Stable ID of the built-in send-message tool. */
9
14
  exports.defaultSendMessageToolId = "000peers0tool00000sendmsg";
15
+ /** Stable ID of the built-in workflow runner tool. */
10
16
  exports.runWorkflowToolId = "000peers0tool0runworkflow";
17
+ /** Stable package ID of the bundled peers-core package. */
11
18
  exports.peersCorePackageId = "00mh0wlipjixk2gqmurbwee0o";
19
+ /** Canonical source repository for peers-core. */
12
20
  exports.peersCorePackageRepoUrl = "https://github.com/peers-app/peers-core";
21
+ /** Trusted publishing key for official peers-core releases. */
13
22
  exports.peersCorePublishPublicKey = "S7cQqnvVz-FVDO6Lk5zC7epSvcP_-NyBVZz9gdcj73c";
14
23
  /**
15
24
  * Stable id of the peers **system** itself, used as the `providerPackageId` for
@@ -22,3 +31,8 @@ exports.peersSystemPackageId = "000peers0system0000000001";
22
31
  * contract-consumer-based remote RPC. See `contracts/system/logs-contract.ts`.
23
32
  */
24
33
  exports.logsContractId = "000peers0logs000000000001";
34
+ /**
35
+ * Contract id for the built-in **System Device Operations** contract. The provider exposes
36
+ * explicit owner-authorized status, bounded read-only database, and installed-tool operations.
37
+ */
38
+ exports.deviceOperationsContractId = "00mriijkhq94msfe9m2j6quwp";
@@ -44,6 +44,8 @@ export declare const workflowSchema: z.ZodObject<{
44
44
  }, "strip", z.ZodTypeAny, {
45
45
  name: string;
46
46
  description: string;
47
+ createdAt: Date;
48
+ updatedAt: Date;
47
49
  workflowId: string;
48
50
  defaultAssistantId: string;
49
51
  instructions: {
@@ -53,8 +55,6 @@ export declare const workflowSchema: z.ZodObject<{
53
55
  subWorkflowId?: string | undefined;
54
56
  }[];
55
57
  createdBy: string;
56
- createdAt: Date;
57
- updatedAt: Date;
58
58
  packageId?: string | undefined;
59
59
  }, {
60
60
  name: string;
@@ -63,13 +63,13 @@ export declare const workflowSchema: z.ZodObject<{
63
63
  defaultAssistantId: string;
64
64
  createdBy: string;
65
65
  packageId?: string | undefined;
66
+ createdAt?: Date | undefined;
67
+ updatedAt?: Date | undefined;
66
68
  instructions?: {
67
69
  markdown?: string | undefined;
68
70
  onError?: string | undefined;
69
71
  directCallToolId?: string | undefined;
70
72
  subWorkflowId?: string | undefined;
71
73
  }[] | undefined;
72
- createdAt?: Date | undefined;
73
- updatedAt?: Date | undefined;
74
74
  }>;
75
75
  export type IWorkflow = z.infer<typeof workflowSchema>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peers-app/peers-sdk",
3
- "version": "0.20.0",
3
+ "version": "0.20.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/peers-app/peers-sdk.git"