@peers-app/peers-sdk 0.25.21 → 0.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contracts/__tests__/builder.test.js +0 -2
- package/dist/contracts/__tests__/contract-provider-router.test.js +51 -0
- package/dist/contracts/__tests__/contract-proxy.test.js +21 -0
- package/dist/contracts/__tests__/contract-resolvers.test.js +84 -0
- package/dist/contracts/__tests__/legacy-removal.test.d.ts +1 -0
- package/dist/contracts/__tests__/legacy-removal.test.js +90 -0
- package/dist/contracts/__tests__/system-contracts.test.js +88 -0
- package/dist/contracts/__tests__/tool-catalog-inventory.test.d.ts +1 -0
- package/dist/contracts/__tests__/tool-catalog-inventory.test.js +44 -0
- package/dist/contracts/__tests__/tool-catalog-service.test.d.ts +1 -0
- package/dist/contracts/__tests__/tool-catalog-service.test.js +446 -0
- package/dist/contracts/__tests__/tool-catalog.test.d.ts +1 -0
- package/dist/contracts/__tests__/tool-catalog.test.js +924 -0
- package/dist/contracts/__tests__/workflow-context.test.d.ts +1 -0
- package/dist/contracts/__tests__/workflow-context.test.js +61 -0
- package/dist/contracts/builder.d.ts +9 -8
- package/dist/contracts/builder.js +34 -16
- package/dist/contracts/contract-provider-router.d.ts +12 -1
- package/dist/contracts/contract-provider-router.js +40 -2
- package/dist/contracts/contract-proxy.d.ts +20 -6
- package/dist/contracts/contract-proxy.js +23 -12
- package/dist/contracts/contract-resolvers.d.ts +22 -3
- package/dist/contracts/contract-resolvers.js +86 -7
- package/dist/contracts/extract.d.ts +7 -0
- package/dist/contracts/extract.js +3 -0
- package/dist/contracts/index.d.ts +11 -4
- package/dist/contracts/index.js +14 -2
- package/dist/contracts/registry.d.ts +3 -0
- package/dist/contracts/registry.js +2 -0
- package/dist/contracts/system/desktop-tools-contract.d.ts +5 -0
- package/dist/contracts/system/desktop-tools-contract.js +88 -0
- package/dist/contracts/system/host-tools-contract.d.ts +5 -0
- package/dist/contracts/system/host-tools-contract.js +76 -0
- package/dist/contracts/system/index.d.ts +3 -0
- package/dist/contracts/system/index.js +3 -0
- package/dist/contracts/system/tool-catalog-contract.d.ts +73 -0
- package/dist/contracts/system/tool-catalog-contract.js +70 -0
- package/dist/contracts/system-contracts.d.ts +3 -1
- package/dist/contracts/system-contracts.js +20 -6
- package/dist/contracts/tool-catalog-identity.d.ts +35 -0
- package/dist/contracts/tool-catalog-identity.js +88 -0
- package/dist/contracts/tool-catalog-migrations.d.ts +12 -0
- package/dist/contracts/tool-catalog-migrations.js +179 -0
- package/dist/contracts/tool-catalog-service.d.ts +30 -0
- package/dist/contracts/tool-catalog-service.js +287 -0
- package/dist/contracts/tool-catalog.d.ts +96 -0
- package/dist/contracts/tool-catalog.js +542 -0
- package/dist/contracts/types.d.ts +7 -5
- package/dist/data/messages.d.ts +3 -3
- package/dist/data/orm/sql.data-source.d.ts +5 -0
- package/dist/data/orm/sql.data-source.js +28 -10
- package/dist/data/orm/sql.data-source.test.d.ts +1 -1
- package/dist/data/orm/sql.data-source.test.js +160 -0
- package/dist/data/orm/table-container.d.ts +14 -0
- package/dist/data/orm/table-container.js +20 -0
- package/dist/data/tool-access-approvals.d.ts +6 -6
- package/dist/data/tool-catalog-fields.d.ts +31 -0
- package/dist/data/tool-catalog-fields.js +67 -0
- package/dist/data/tools.d.ts +38 -10
- package/dist/data/tools.js +31 -8
- package/dist/data/workflow-logs.d.ts +6 -2
- package/dist/data/workflow-logs.js +7 -5
- package/dist/data/workflow-runs.d.ts +6 -6
- package/dist/index.d.ts +0 -2
- package/dist/index.js +1 -3
- package/dist/package-loader/contract-package-loader.d.ts +12 -3
- package/dist/package-loader/contract-package-loader.js +54 -50
- package/dist/package-loader/contract-package-loader.test.d.ts +1 -1
- package/dist/package-loader/contract-package-loader.test.js +172 -13
- package/dist/package-loader/host-authority-loading.test.js +16 -3
- package/dist/package-loader/isolated-runtime.d.ts +14 -2
- package/dist/package-loader/isolated-table-gateway.d.ts +3 -1
- package/dist/package-loader/isolated-table-gateway.js +54 -5
- package/dist/package-loader/isolated-table-gateway.test.js +123 -0
- package/dist/package-loader/package-loader.d.ts +14 -2
- package/dist/package-loader/package-loader.js +184 -62
- package/dist/package-loader/package-loader.test.js +674 -1
- package/dist/package-loader/resolve-consumed-contracts.js +1 -1
- package/dist/system-ids.d.ts +6 -0
- package/dist/system-ids.js +7 -1
- package/dist/types/peers-package.d.ts +3 -2
- package/dist/types/workflow-run-context.d.ts +12 -2
- package/package.json +1 -1
- package/dist/tools/index.d.ts +0 -1
- package/dist/tools/index.js +0 -17
- package/dist/tools/tools-factory.d.ts +0 -5
- package/dist/tools/tools-factory.js +0 -34
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { ITool } from "../../data/tools";
|
|
2
|
+
import type { IContractConsumerBase } from "../contract-proxy";
|
|
3
|
+
import type { ToolCatalogTarget } from "../tool-catalog-identity";
|
|
4
|
+
import type { IContractDefinition } from "../types";
|
|
5
|
+
/** Version of the local System Tool Catalog API. */
|
|
6
|
+
export declare const TOOL_CATALOG_CONTRACT_VERSION = 1;
|
|
7
|
+
/** Built-in provider of the System Tool Catalog. */
|
|
8
|
+
export declare const toolCatalogProviderPackageId = "000peers0system0000000001";
|
|
9
|
+
/** Permanent tool metadata combined with this context's live dispatch and policy state. */
|
|
10
|
+
export interface IToolCatalogEntry {
|
|
11
|
+
toolId: string;
|
|
12
|
+
aliases: string[];
|
|
13
|
+
name: string;
|
|
14
|
+
usageDescription: string;
|
|
15
|
+
inputSchema: ITool["inputSchema"];
|
|
16
|
+
outputSchema: ITool["outputSchema"];
|
|
17
|
+
catalogState: ITool["catalogState"];
|
|
18
|
+
catalogIdentity: ITool["catalogIdentity"];
|
|
19
|
+
target?: ToolCatalogTarget;
|
|
20
|
+
workflowInvocable: boolean;
|
|
21
|
+
availability: {
|
|
22
|
+
dispatch: "contract" | "unavailable";
|
|
23
|
+
reason?: string;
|
|
24
|
+
message?: string;
|
|
25
|
+
requiresWorkflowRun?: boolean;
|
|
26
|
+
};
|
|
27
|
+
provider?: {
|
|
28
|
+
activePackageId?: string;
|
|
29
|
+
registeredPackageIds: string[];
|
|
30
|
+
implementation?: {
|
|
31
|
+
contractId: string;
|
|
32
|
+
version: number;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
access?: {
|
|
36
|
+
accessLevel: number;
|
|
37
|
+
callerAccessLevel: number;
|
|
38
|
+
allowed: boolean;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** Bounded text discovery in one data context. */
|
|
42
|
+
export interface IListToolCatalogInput {
|
|
43
|
+
query?: string;
|
|
44
|
+
limit?: number;
|
|
45
|
+
}
|
|
46
|
+
/** Exact ID, exact name, then unambiguous text lookup. */
|
|
47
|
+
export interface IGetToolCatalogInput {
|
|
48
|
+
toolIdOrName: string;
|
|
49
|
+
runnableOnly?: boolean;
|
|
50
|
+
}
|
|
51
|
+
/** Checked contract invocation; caller authority is never accepted in this payload. */
|
|
52
|
+
export interface IInvokeToolCatalogInput {
|
|
53
|
+
toolId: string;
|
|
54
|
+
args?: Record<string, unknown>;
|
|
55
|
+
providerPackageId?: string;
|
|
56
|
+
fallbackToDefaultProvider?: boolean;
|
|
57
|
+
}
|
|
58
|
+
/** Authenticated local CLI/UI consumer of the System Tool Catalog. */
|
|
59
|
+
export interface IToolCatalogConsumer extends IContractConsumerBase {
|
|
60
|
+
tools: {
|
|
61
|
+
listTools(input: IListToolCatalogInput): Promise<{
|
|
62
|
+
tools: IToolCatalogEntry[];
|
|
63
|
+
}>;
|
|
64
|
+
getTool(input: IGetToolCatalogInput): Promise<{
|
|
65
|
+
tool?: IToolCatalogEntry;
|
|
66
|
+
}>;
|
|
67
|
+
invokeTool(input: IInvokeToolCatalogInput): Promise<{
|
|
68
|
+
result: unknown;
|
|
69
|
+
}>;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** Return the local-only discovery and checked contract invocation definition. */
|
|
73
|
+
export declare function getToolCatalogContractDefinition(): IContractDefinition;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toolCatalogProviderPackageId = exports.TOOL_CATALOG_CONTRACT_VERSION = void 0;
|
|
4
|
+
exports.getToolCatalogContractDefinition = getToolCatalogContractDefinition;
|
|
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 local System Tool Catalog API. */
|
|
9
|
+
exports.TOOL_CATALOG_CONTRACT_VERSION = 1;
|
|
10
|
+
/** Built-in provider of the System Tool Catalog. */
|
|
11
|
+
exports.toolCatalogProviderPackageId = system_ids_1.peersSystemPackageId;
|
|
12
|
+
const field = (name, type, description, optional = false) => ({
|
|
13
|
+
name,
|
|
14
|
+
type,
|
|
15
|
+
description,
|
|
16
|
+
optional,
|
|
17
|
+
});
|
|
18
|
+
let definition;
|
|
19
|
+
/** Return the local-only discovery and checked contract invocation definition. */
|
|
20
|
+
function getToolCatalogContractDefinition() {
|
|
21
|
+
definition ??= {
|
|
22
|
+
contractId: system_ids_1.toolCatalogContractId,
|
|
23
|
+
version: exports.TOOL_CATALOG_CONTRACT_VERSION,
|
|
24
|
+
devTag: "dev",
|
|
25
|
+
name: "System Tool Catalog",
|
|
26
|
+
description: "Discover tools and invoke their selected contract providers.",
|
|
27
|
+
tables: [],
|
|
28
|
+
observables: [],
|
|
29
|
+
events: [],
|
|
30
|
+
tools: [
|
|
31
|
+
{
|
|
32
|
+
name: "listTools",
|
|
33
|
+
usageDescription: "List tool metadata and current dispatch availability.",
|
|
34
|
+
inputFields: [
|
|
35
|
+
field("query", field_type_1.FieldType.string, "Text query.", true),
|
|
36
|
+
field("limit", field_type_1.FieldType.number, "Maximum rows (up to 500).", true),
|
|
37
|
+
],
|
|
38
|
+
outputFields: [{ ...field("tools", field_type_1.FieldType.object, "Catalog entries."), isArray: true }],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: "getTool",
|
|
42
|
+
usageDescription: "Find one tool by ID, exact name or unambiguous text.",
|
|
43
|
+
inputFields: [
|
|
44
|
+
field("toolIdOrName", field_type_1.FieldType.string, "ID or name."),
|
|
45
|
+
field("runnableOnly", field_type_1.FieldType.boolean, "Exclude unavailable name/text matches.", true),
|
|
46
|
+
],
|
|
47
|
+
outputFields: [field("tool", field_type_1.FieldType.object, "Catalog entry, if found.", true)],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: "invokeTool",
|
|
51
|
+
usageDescription: "Validate arguments and invoke a contract tool as the original caller.",
|
|
52
|
+
inputFields: [
|
|
53
|
+
// The shipped Scheduler alias has 26 characters; global isid stays strict.
|
|
54
|
+
field("toolId", field_type_1.FieldType.string, "Catalog tool ID."),
|
|
55
|
+
field("args", field_type_1.FieldType.object, "Target arguments.", true),
|
|
56
|
+
field("providerPackageId", field_type_1.FieldType.id, "Preferred provider package.", true),
|
|
57
|
+
field("fallbackToDefaultProvider", field_type_1.FieldType.boolean, "Allow the active provider when the preference is missing.", true),
|
|
58
|
+
],
|
|
59
|
+
outputFields: [field("result", field_type_1.FieldType.any, "Target result.")],
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
};
|
|
63
|
+
return definition;
|
|
64
|
+
}
|
|
65
|
+
(0, system_contracts_1.registerSystemContract)({
|
|
66
|
+
providerPackageId: exports.toolCatalogProviderPackageId,
|
|
67
|
+
contractId: system_ids_1.toolCatalogContractId,
|
|
68
|
+
version: exports.TOOL_CATALOG_CONTRACT_VERSION,
|
|
69
|
+
getDefinition: getToolCatalogContractDefinition,
|
|
70
|
+
});
|
|
@@ -36,7 +36,7 @@ export declare function registerSystemContract(registration: ISystemContractRegi
|
|
|
36
36
|
* Register every known system contract into `registry` as a provider.
|
|
37
37
|
* Safe to call more than once for the same registry (provider updates in place).
|
|
38
38
|
*/
|
|
39
|
-
export declare function installSystemContracts(registry: ContractRegistry): void
|
|
39
|
+
export declare function installSystemContracts(registry: ContractRegistry): Promise<void>;
|
|
40
40
|
/** Snapshot of registered system contracts (for tests and diagnostics). */
|
|
41
41
|
export declare function listSystemContracts(): readonly ISystemContractRegistration[];
|
|
42
42
|
/**
|
|
@@ -45,3 +45,5 @@ export declare function listSystemContracts(): readonly ISystemContractRegistrat
|
|
|
45
45
|
* @internal
|
|
46
46
|
*/
|
|
47
47
|
export declare function _clearSystemContractsForTests(): void;
|
|
48
|
+
/** Whether an identity belongs to a built-in system contract. */
|
|
49
|
+
export declare function isSystemContractId(contractId: string): boolean;
|
|
@@ -4,6 +4,7 @@ exports.registerSystemContract = registerSystemContract;
|
|
|
4
4
|
exports.installSystemContracts = installSystemContracts;
|
|
5
5
|
exports.listSystemContracts = listSystemContracts;
|
|
6
6
|
exports._clearSystemContractsForTests = _clearSystemContractsForTests;
|
|
7
|
+
exports.isSystemContractId = isSystemContractId;
|
|
7
8
|
const systemContracts = [];
|
|
8
9
|
function systemContractKey(contractId, version) {
|
|
9
10
|
return `${contractId}@${version}`;
|
|
@@ -48,13 +49,22 @@ function registerSystemContract(registration) {
|
|
|
48
49
|
* Register every known system contract into `registry` as a provider.
|
|
49
50
|
* Safe to call more than once for the same registry (provider updates in place).
|
|
50
51
|
*/
|
|
51
|
-
function installSystemContracts(registry) {
|
|
52
|
+
async function installSystemContracts(registry) {
|
|
53
|
+
if (registry.toolCatalog) {
|
|
54
|
+
await registry.toolCatalog.ready();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Standalone registries have no DataContext/storage (schema tooling and tests).
|
|
58
|
+
const groups = new Map();
|
|
52
59
|
for (const entry of systemContracts) {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
60
|
+
const registrations = groups.get(entry.providerPackageId) ?? [];
|
|
61
|
+
registrations.push({ definition: entry.getDefinition() });
|
|
62
|
+
groups.set(entry.providerPackageId, registrations);
|
|
63
|
+
}
|
|
64
|
+
for (const [provider, registrations] of groups) {
|
|
65
|
+
const result = registry.replaceBatch(provider, registrations);
|
|
66
|
+
if (!result.valid)
|
|
67
|
+
throw new Error(result.errors.map((error) => error.message).join("; "));
|
|
58
68
|
}
|
|
59
69
|
}
|
|
60
70
|
/** Snapshot of registered system contracts (for tests and diagnostics). */
|
|
@@ -69,3 +79,7 @@ function listSystemContracts() {
|
|
|
69
79
|
function _clearSystemContractsForTests() {
|
|
70
80
|
systemContracts.length = 0;
|
|
71
81
|
}
|
|
82
|
+
/** Whether an identity belongs to a built-in system contract. */
|
|
83
|
+
function isSystemContractId(contractId) {
|
|
84
|
+
return systemContracts.some((entry) => (entry.contractId ?? entry.getDefinition().contractId) === contractId);
|
|
85
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Case-sensitive public contract member identity, independent of any provider. */
|
|
2
|
+
export interface ToolCatalogTarget {
|
|
3
|
+
contractId: string;
|
|
4
|
+
version: number;
|
|
5
|
+
toolName: string;
|
|
6
|
+
}
|
|
7
|
+
/** The shipped 26-character contract ID is accepted only by catalog target validation. */
|
|
8
|
+
export declare const legacyCatalogContractId = "000peers0toolaccessctl0001";
|
|
9
|
+
/** The shipped Scheduler list tool ID is accepted only by Tools identity validation. */
|
|
10
|
+
export declare const legacyCatalogToolId = "00muxgugn661g0qmpuwafrmsi4";
|
|
11
|
+
/** Validate a contract ID without weakening global peer-ID validation. */
|
|
12
|
+
export declare function isCatalogContractId(value: string): boolean;
|
|
13
|
+
/** Validate a Tools primary key, including the single shipped length exception. */
|
|
14
|
+
export declare function isCatalogToolId(value: string): boolean;
|
|
15
|
+
/** Validate exact names and well-formed Unicode; never trim or normalize identity input. */
|
|
16
|
+
export declare function validateToolCatalogTarget(target: ToolCatalogTarget): void;
|
|
17
|
+
/**
|
|
18
|
+
* Permanent v1 encoding approved in the Tools Catalog Foreman specification
|
|
19
|
+
* (2026-10-13): UTF-8 of compact JSON, including the domain separator.
|
|
20
|
+
* The protocol and fixed vectors are published in docs/System/Tools.md.
|
|
21
|
+
*/
|
|
22
|
+
export declare function encodeToolCatalogTarget(target: ToolCatalogTarget): Uint8Array;
|
|
23
|
+
/** Unambiguous, case-sensitive tuple key used for indexing and collision checks. */
|
|
24
|
+
export declare function toolCatalogTargetKey(target: ToolCatalogTarget): string;
|
|
25
|
+
/**
|
|
26
|
+
* Permanent catalog ID: SHA-512 as an unsigned big-endian integer modulo 36^17,
|
|
27
|
+
* padded lowercase base36 with the `000tool0` prefix (25 characters total).
|
|
28
|
+
*
|
|
29
|
+
* Explicit exception to newid(): random/time allocation would give the same public
|
|
30
|
+
* tool different IDs on independent installations. Never replace this derivation
|
|
31
|
+
* with newid(). Use newid() only for genuinely new contract IDs, committed once.
|
|
32
|
+
*/
|
|
33
|
+
export declare function deriveToolCatalogId(target: ToolCatalogTarget): string;
|
|
34
|
+
/** Reject reuse of an ID for a different target, including genuine hash collisions. */
|
|
35
|
+
export declare function validateToolCatalogCollision(identities: Map<string, string>, toolId: string, target: ToolCatalogTarget): void;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.legacyCatalogToolId = exports.legacyCatalogContractId = void 0;
|
|
4
|
+
exports.isCatalogContractId = isCatalogContractId;
|
|
5
|
+
exports.isCatalogToolId = isCatalogToolId;
|
|
6
|
+
exports.validateToolCatalogTarget = validateToolCatalogTarget;
|
|
7
|
+
exports.encodeToolCatalogTarget = encodeToolCatalogTarget;
|
|
8
|
+
exports.toolCatalogTargetKey = toolCatalogTargetKey;
|
|
9
|
+
exports.deriveToolCatalogId = deriveToolCatalogId;
|
|
10
|
+
exports.validateToolCatalogCollision = validateToolCatalogCollision;
|
|
11
|
+
const nacl = require("tweetnacl");
|
|
12
|
+
const tweetnacl_util_1 = require("tweetnacl-util");
|
|
13
|
+
const utils_1 = require("../utils");
|
|
14
|
+
/** The shipped 26-character contract ID is accepted only by catalog target validation. */
|
|
15
|
+
exports.legacyCatalogContractId = "000peers0toolaccessctl0001";
|
|
16
|
+
/** The shipped Scheduler list tool ID is accepted only by Tools identity validation. */
|
|
17
|
+
exports.legacyCatalogToolId = "00muxgugn661g0qmpuwafrmsi4";
|
|
18
|
+
/** Validate a contract ID without weakening global peer-ID validation. */
|
|
19
|
+
function isCatalogContractId(value) {
|
|
20
|
+
return typeof value === "string" && ((0, utils_1.isid)(value) || value === exports.legacyCatalogContractId);
|
|
21
|
+
}
|
|
22
|
+
/** Validate a Tools primary key, including the single shipped length exception. */
|
|
23
|
+
function isCatalogToolId(value) {
|
|
24
|
+
return typeof value === "string" && ((0, utils_1.isid)(value) || value === exports.legacyCatalogToolId);
|
|
25
|
+
}
|
|
26
|
+
/** Validate exact names and well-formed Unicode; never trim or normalize identity input. */
|
|
27
|
+
function validateToolCatalogTarget(target) {
|
|
28
|
+
if (!isCatalogContractId(target.contractId))
|
|
29
|
+
throw new Error("Invalid catalog contractId");
|
|
30
|
+
if (!Number.isSafeInteger(target.version) || target.version < 1)
|
|
31
|
+
throw new Error("Invalid catalog version");
|
|
32
|
+
if (typeof target.toolName !== "string" || target.toolName.length === 0)
|
|
33
|
+
throw new Error("Invalid catalog toolName");
|
|
34
|
+
// Reject lone UTF-16 surrogates rather than letting a UTF-8 encoder replace them.
|
|
35
|
+
for (let i = 0; i < target.toolName.length; i++) {
|
|
36
|
+
const unit = target.toolName.charCodeAt(i);
|
|
37
|
+
if (unit >= 0xd800 && unit <= 0xdbff) {
|
|
38
|
+
const next = target.toolName.charCodeAt(++i);
|
|
39
|
+
if (!(next >= 0xdc00 && next <= 0xdfff))
|
|
40
|
+
throw new Error("Malformed Unicode toolName");
|
|
41
|
+
}
|
|
42
|
+
else if (unit >= 0xdc00 && unit <= 0xdfff)
|
|
43
|
+
throw new Error("Malformed Unicode toolName");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Permanent v1 encoding approved in the Tools Catalog Foreman specification
|
|
48
|
+
* (2026-10-13): UTF-8 of compact JSON, including the domain separator.
|
|
49
|
+
* The protocol and fixed vectors are published in docs/System/Tools.md.
|
|
50
|
+
*/
|
|
51
|
+
function encodeToolCatalogTarget(target) {
|
|
52
|
+
validateToolCatalogTarget(target);
|
|
53
|
+
return (0, tweetnacl_util_1.decodeUTF8)(toolCatalogTargetKey(target));
|
|
54
|
+
}
|
|
55
|
+
/** Unambiguous, case-sensitive tuple key used for indexing and collision checks. */
|
|
56
|
+
function toolCatalogTargetKey(target) {
|
|
57
|
+
return JSON.stringify([
|
|
58
|
+
"peers.tools-catalog.v1",
|
|
59
|
+
target.contractId,
|
|
60
|
+
target.version,
|
|
61
|
+
target.toolName,
|
|
62
|
+
]);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Permanent catalog ID: SHA-512 as an unsigned big-endian integer modulo 36^17,
|
|
66
|
+
* padded lowercase base36 with the `000tool0` prefix (25 characters total).
|
|
67
|
+
*
|
|
68
|
+
* Explicit exception to newid(): random/time allocation would give the same public
|
|
69
|
+
* tool different IDs on independent installations. Never replace this derivation
|
|
70
|
+
* with newid(). Use newid() only for genuinely new contract IDs, committed once.
|
|
71
|
+
*/
|
|
72
|
+
function deriveToolCatalogId(target) {
|
|
73
|
+
let digest = 0n;
|
|
74
|
+
for (const byte of nacl.hash(encodeToolCatalogTarget(target)))
|
|
75
|
+
digest = digest * 256n + BigInt(byte);
|
|
76
|
+
return `000tool0${(digest % 36n ** 17n).toString(36).padStart(17, "0")}`;
|
|
77
|
+
}
|
|
78
|
+
/** Reject reuse of an ID for a different target, including genuine hash collisions. */
|
|
79
|
+
function validateToolCatalogCollision(identities, toolId, target) {
|
|
80
|
+
if (!isCatalogToolId(toolId))
|
|
81
|
+
throw new Error("Invalid catalog toolId");
|
|
82
|
+
validateToolCatalogTarget(target);
|
|
83
|
+
const key = toolCatalogTargetKey(target);
|
|
84
|
+
const previous = identities.get(toolId);
|
|
85
|
+
if (previous && previous !== key)
|
|
86
|
+
throw new Error(`Tool catalog identity collision: ${toolId}`);
|
|
87
|
+
identities.set(toolId, key);
|
|
88
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ToolCatalogTarget } from "./tool-catalog-identity";
|
|
2
|
+
/** Reviewed legacy identity with source provenance. No package code is imported. */
|
|
3
|
+
export interface ToolCatalogMigration extends ToolCatalogTarget {
|
|
4
|
+
toolId: string;
|
|
5
|
+
source: string;
|
|
6
|
+
}
|
|
7
|
+
/** Append-only compatibility inventory. Multiple IDs for a tuple are equal aliases. */
|
|
8
|
+
export declare const toolCatalogMigrations: readonly ToolCatalogMigration[];
|
|
9
|
+
/** Resolve an explicit alias; ambiguity fails closed rather than choosing by order. */
|
|
10
|
+
export declare function resolveLegacyToolId(toolId: string, inventory?: readonly ToolCatalogMigration[]): ToolCatalogTarget | undefined;
|
|
11
|
+
/** All protocol-selected identities; explicit aliases suppress the deterministic ID. */
|
|
12
|
+
export declare function toolCatalogIds(target: ToolCatalogTarget, inventory?: readonly ToolCatalogMigration[]): string[];
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toolCatalogMigrations = void 0;
|
|
4
|
+
exports.resolveLegacyToolId = resolveLegacyToolId;
|
|
5
|
+
exports.toolCatalogIds = toolCatalogIds;
|
|
6
|
+
const system_ids_1 = require("../system-ids");
|
|
7
|
+
const tool_catalog_identity_1 = require("./tool-catalog-identity");
|
|
8
|
+
/** Append-only compatibility inventory. Multiple IDs for a tuple are equal aliases. */
|
|
9
|
+
exports.toolCatalogMigrations = [
|
|
10
|
+
...reviewed("000peers0toolaccessctl0001", "peers-sdk/src/system-ids.ts: toolAccessControlToolIds; contracts/system/tool-access-control-contract.ts", [
|
|
11
|
+
["000peers0tacapprove000001", "approve"],
|
|
12
|
+
["000peers0tacreject0000001", "reject"],
|
|
13
|
+
["000peers0taclist000000001", "listPending"],
|
|
14
|
+
]),
|
|
15
|
+
...reviewed("00mu8uuzvo2zux1wfb9f1r48l", "peers-sdk/src/system-ids.ts: invitesToolIds; contracts/system/invites-contract.ts", [
|
|
16
|
+
["00mu8uuzvqbn5o23ya563wmp5", "createContactInvite"],
|
|
17
|
+
["00mu8uuzvqz17wedq1iqmh9i4", "createGroupInvite"],
|
|
18
|
+
["00mu8uuzvqhbk5avjpew7w9ng", "inviteContactToGroup"],
|
|
19
|
+
["00mu8uuzvqwbo180wgz4ctslm", "previewInvite"],
|
|
20
|
+
["00mu8uuzvq8i1boc4ml1ywk30", "acceptInvite"],
|
|
21
|
+
["00mu8uuzvq97veint1977p2ey", "declineInvite"],
|
|
22
|
+
["00mu8uuzvqisozhlfbe1oeo0e", "approveJoinRequest"],
|
|
23
|
+
["00mu8uuzvqdars4o466eansi2", "denyJoinRequest"],
|
|
24
|
+
["00mu8uuzvqndg6qdh74dob9j1", "revokeInvite"],
|
|
25
|
+
["00mu8uuzvqbu5ri9octpk64oo", "regenerateProfileInvite"],
|
|
26
|
+
["00mu8uuzvq4xlaiqrn5notj1j", "syncMailbox"],
|
|
27
|
+
["00mu8uuzvqfego6lyjjkgr4s7", "listInvites"],
|
|
28
|
+
]),
|
|
29
|
+
...reviewed("00muc9mlzv32qg00zz7cyixu9", "peers-sdk/src/system-ids.ts: identityToolIds; contracts/system/identity-contract.ts", [
|
|
30
|
+
["00muc9mlzx4hqsfm132w4bzfm", "startSource"],
|
|
31
|
+
["00muc9mlzxnfqylatvsyl41fc", "startDestination"],
|
|
32
|
+
["00muc9mlzx1vpfyfexbd1yjbc", "approve"],
|
|
33
|
+
["00muc9mlzxij1praa2scg4v5r", "reject"],
|
|
34
|
+
["00muc9mlzxtq87urc75qc4r5v", "cancel"],
|
|
35
|
+
["00muc9mlzx3t5evd57bns5z5n", "getSession"],
|
|
36
|
+
["00muc9mlzx456ecfmzp1xn0db", "signIn"],
|
|
37
|
+
["00muc9mlzxwdm2yj5p5wkjvz7", "signOut"],
|
|
38
|
+
["00muc9mlzx07q98l3f9x49o10", "registerWithPeersServices"],
|
|
39
|
+
["00mus1g5sfmu8vhazy7grwtjz", "getKeyInfo"],
|
|
40
|
+
["00mus1g5sfrifcnula9crst8s", "rotateKey"],
|
|
41
|
+
["00mustp0jrvoxpgion9dfgizc", "getRecoveryEmail"],
|
|
42
|
+
["00mustox69twakb9sss2cto4g", "bindEmailStart"],
|
|
43
|
+
["00mustox6brb044r1ms5gylw5", "bindEmailVerify"],
|
|
44
|
+
["00mustox6b3afftshfac8vc04", "unbindEmail"],
|
|
45
|
+
["00mustox6bjv7mo0jtywuzehm", "startAnchorSession"],
|
|
46
|
+
["00mustox6bvmiuzzq4t7kg18q", "confirmAnchorSession"],
|
|
47
|
+
["00musvcrtk1bkhivlo3d9e51z", "contestRecovery"],
|
|
48
|
+
["00musvcrtlpgic1r6w2boo4k4", "acceptRecovery"],
|
|
49
|
+
["00musvcrtl6ruaysm9f8he39x", "recoverKey"],
|
|
50
|
+
["00musw0he8emme6dxl16ks885", "setAnchors"],
|
|
51
|
+
["00musw0he9s4v0lz8bn4qpk7w", "passkeyRegisterStart"],
|
|
52
|
+
["00musw0he9w4smpnzer0gqy22", "passkeyRegisterFinish"],
|
|
53
|
+
["00musw0he9ad5zggw924sqd05", "passkeyAuthStart"],
|
|
54
|
+
["00musw0he9yq03hf7qyk3b8dn", "passkeyAuthFinish"],
|
|
55
|
+
]),
|
|
56
|
+
...reviewed("00mukk9dwb1mjtd845kftuazm", "peers-sdk/src/system-ids.ts: localFoldersToolIds; contracts/system/local-folders-contract.ts", [
|
|
57
|
+
["00mukk9dwdcv4f99ydwxao97f", "requestGrant"],
|
|
58
|
+
["00mukk9dwdq119xmvz4ap8aum", "listGrants"],
|
|
59
|
+
["00mukk9dwdezt5sbjviq1n1sp", "revokeGrant"],
|
|
60
|
+
["00mukk9dwd6mxscrv9eeaanai", "list"],
|
|
61
|
+
["00mukk9dwdon2y2487clcg67k", "stat"],
|
|
62
|
+
["00mukk9dwdih6mh8rrofph80o", "readRange"],
|
|
63
|
+
["00mukk9dwdm01bxg3hrby6pli", "index"],
|
|
64
|
+
["00mumw1pmmf3y2ujfdc99h4ib", "getFileBlocks"],
|
|
65
|
+
["00mungara9ixeolgxukzj2aku", "assemble"],
|
|
66
|
+
["00mukk9dwd1c1f51xjysssgtv", "getJob"],
|
|
67
|
+
["00mukk9dweizvif4ghp6kfa92", "cancelJob"],
|
|
68
|
+
["00mukk9dwer8wsw5eiwis8tzm", "move"],
|
|
69
|
+
["00mukk9dwejbuehqzszpyxefx", "trash"],
|
|
70
|
+
["00mukk9dwe6co8gvuy44kmuzd", "purgeTrash"],
|
|
71
|
+
]),
|
|
72
|
+
...reviewed("00muxgugn4tzd527r3cwnie2o", "peers-sdk/src/system-ids.ts: httpToolIds; contracts/system/http-contract.ts", [
|
|
73
|
+
["00muxgugn6e3dan5ej6dotzy5", "request"],
|
|
74
|
+
["00muxgugn6scnni9563focivs", "cancel"],
|
|
75
|
+
["00muxgugn6kouo2ocpun70q31", "describePolicy"],
|
|
76
|
+
]),
|
|
77
|
+
...reviewed("00muxgugn6ncjuunb8r28puae", "peers-sdk/src/system-ids.ts: contractCatalogToolIds; contracts/system/contract-catalog-contract.ts", [["00muxgugn6ek5apk8d5jtfavp", "listContractProviders"]]),
|
|
78
|
+
...reviewed("00muxgugn6pj2o0lcu7kxkvrs", "peers-sdk/src/system-ids.ts: schedulerToolIds; contracts/system/scheduler-contract.ts", [
|
|
79
|
+
["00muxgugn6t0o5s7239zg6bf5", "schedule"],
|
|
80
|
+
["00muxgugn6vqfxpppodqlgfhg", "cancel"],
|
|
81
|
+
["00muxgugn661g0qmpuwafrmsi4", "list"],
|
|
82
|
+
]),
|
|
83
|
+
...reviewed("00mriijkhq94msfe9m2j6quwp", "peers-sdk/src/contracts/system/device-operations-contract.ts", [
|
|
84
|
+
["00mriijkhr4iptdefp4a7ifcq", "getDeviceStatus"],
|
|
85
|
+
["00mriijkhrd54n33ey0omeejo", "queryDatabase"],
|
|
86
|
+
["00mriijkhr4fpyd70nyo5iqlq", "listTools"],
|
|
87
|
+
["00mriijkhrid4wpf89i4ikvay", "getTool"],
|
|
88
|
+
["00mriijkhrfequch2qaeoihol", "runTool"],
|
|
89
|
+
]),
|
|
90
|
+
...reviewed("00ms1yb50w29oi116uwwrg7rl", "peers-sdk/src/contracts/system/network-contracts.ts", [
|
|
91
|
+
["00ms1yb50ym353ads0gel5jpv", "getOverview"],
|
|
92
|
+
["00ms1yb50ykny9kdgiclpa1t4", "getConnections"],
|
|
93
|
+
["00ms1yb50yp2q7jr0jglzsztq", "getGroupSyncStatus"],
|
|
94
|
+
["00ms1yb50yw792rslve1q99qg", "getDeviceDetails"],
|
|
95
|
+
["00ms1yb50yuru8h1fg4t9na3e", "getGroupDetails"],
|
|
96
|
+
["00ms1yb50y3jpoby5zomltahr", "getDisconnectedDevices"],
|
|
97
|
+
["00ms1yb50y2fbfnth22yz52eu", "queryRemoteLogs"],
|
|
98
|
+
["00mujw2tgbpoohxvwd23u9moz", "getSyncRecoveryEntries"],
|
|
99
|
+
]),
|
|
100
|
+
...reviewed("00ms1yb50yj9w5qbytl69qfht", "peers-sdk/src/contracts/system/network-contracts.ts", [
|
|
101
|
+
["00ms1yb50y9rsdyqmr81vjoli", "refreshNetworkInfo"],
|
|
102
|
+
["00ms1yb50y40ty8tr0sic875x", "connectToDevice"],
|
|
103
|
+
["00ms1yb50yqvboqmhshqvlibr", "disconnectDevice"],
|
|
104
|
+
["00ms1yb50y5mc448nuavlex86", "deleteDevice"],
|
|
105
|
+
["00ms1yb50ylnqlra26jx232py", "syncGroupNow"],
|
|
106
|
+
["00ms1yb50yfuackpl1w37hmxc", "resetChangeTracking"],
|
|
107
|
+
["00mujw2tgcelvpg556n836ah7", "retrySyncRecovery"],
|
|
108
|
+
["00mujw2tgciywn8krykc6gmwx", "resolveSyncRecovery"],
|
|
109
|
+
["00mujw2tgc5lrezqrw4oneaot", "resetDeviceSyncInfo"],
|
|
110
|
+
]),
|
|
111
|
+
...reviewed("00mp287gdomtx12ald8oelyp0", "peers-core/src/package.ts; common/tools/index.ts and *.tool.ts; common/consts.ts", [
|
|
112
|
+
["000peers0tool0000000newid", "new-id"],
|
|
113
|
+
["000peers0tool0000throwerr", "throw-error"],
|
|
114
|
+
["000peers0tool000000setvar", "set-variable"],
|
|
115
|
+
["000peers0tool00000sendmsg", "send-message"],
|
|
116
|
+
["000peers0tool00wrkflwsrch", "search-workflows"],
|
|
117
|
+
["000peers0tool0runworkflow", "run-a-workflow"],
|
|
118
|
+
["00mlwl2km0iymo1hwhtvqij2n", "cli_assistant_runner"],
|
|
119
|
+
]),
|
|
120
|
+
...reviewed("00mp287gdl5atltgs5bh0vm9z", "peers-core/src/package.ts; tasks/tools/index.ts and *.tool.ts; tasks/consts.ts", [
|
|
121
|
+
["00mh0wlipkdbeaw8newtsk001", "new-task"],
|
|
122
|
+
["00mh0wlipkdbeaw8wrttsk001", "write-task"],
|
|
123
|
+
["00mh0wlipkdbeaw8wrtcmt001", "write-task-comment"],
|
|
124
|
+
]),
|
|
125
|
+
...reviewed("00mp50k37x131g7owkejhyb2t", "official-packages/groceries/src/package.ts, consts.ts, tools/index.ts, tools/add-to-shopping-list.tool.ts", [["00mh0wlipkdbeaw8shopitm01", "add-to-shopping-list"]]),
|
|
126
|
+
...reviewed("00muxgugn6xvs8f2r80ru205t", "official-packages/groceries/src/voice/groceries-voice-skill.ts and consts.ts; peers-core/src/tasks/voice-skill.ts and voice-skill-consts.ts", [
|
|
127
|
+
["00muxoa8xeet2lpi8bdq55q03", "invoke"],
|
|
128
|
+
["00muxob3hbo3f6g49mipy1hyt", "invoke"],
|
|
129
|
+
]),
|
|
130
|
+
...reviewed(system_ids_1.hostToolsContractId, "peers-device/src/host-tools/contract.ts", [
|
|
131
|
+
["000peers0tool0creategroup", "create-group"],
|
|
132
|
+
["000peers0tool00querydb001", "query-database"],
|
|
133
|
+
]),
|
|
134
|
+
...reviewed(system_ids_1.desktopToolsContractId, "peers-electron/src/data/system/tools/*", [
|
|
135
|
+
["000peers0tool00000homedir", "get-user-home-directory"],
|
|
136
|
+
["000peers0tool0000peersdir", "get-peers-data-directory"],
|
|
137
|
+
["000peers0tool00000showdir", "open-directory-in-os"],
|
|
138
|
+
["000peers0tool000000pkgdir", "get-peers-packages-directory"],
|
|
139
|
+
["000peers0tool00describdir", "describe-directory-contents"],
|
|
140
|
+
["000peers0tool00appversion", "app-version"],
|
|
141
|
+
["000peers0tool000publishpk", "publish-package"],
|
|
142
|
+
]),
|
|
143
|
+
...reviewed(system_ids_1.hostToolsContractId, "peers-device/src/host-tools/contract.ts", [
|
|
144
|
+
["000peers0tool00000runner1", "default_assistant_runner"],
|
|
145
|
+
["000peers0tool00toolsearch", "tool-search"],
|
|
146
|
+
]),
|
|
147
|
+
...reviewed(system_ids_1.desktopToolsContractId, "peers-electron/src/data/system/tools/*", [
|
|
148
|
+
["000peers0tool0000000dircd", "cd"],
|
|
149
|
+
["000peers0tool000000notify", "send-notification"],
|
|
150
|
+
]),
|
|
151
|
+
];
|
|
152
|
+
function reviewed(contractId, source, aliases) {
|
|
153
|
+
return aliases.map(([toolId, toolName]) => ({
|
|
154
|
+
toolId,
|
|
155
|
+
contractId,
|
|
156
|
+
version: 1,
|
|
157
|
+
toolName,
|
|
158
|
+
source,
|
|
159
|
+
}));
|
|
160
|
+
}
|
|
161
|
+
/** Resolve an explicit alias; ambiguity fails closed rather than choosing by order. */
|
|
162
|
+
function resolveLegacyToolId(toolId, inventory = exports.toolCatalogMigrations) {
|
|
163
|
+
const matches = inventory.filter((entry) => entry.toolId === toolId);
|
|
164
|
+
if (new Set(matches.map(tool_catalog_identity_1.toolCatalogTargetKey)).size > 1)
|
|
165
|
+
throw new Error(`Ambiguous legacy tool mapping: ${toolId}`);
|
|
166
|
+
const entry = matches[0];
|
|
167
|
+
return (entry && { contractId: entry.contractId, version: entry.version, toolName: entry.toolName });
|
|
168
|
+
}
|
|
169
|
+
/** All protocol-selected identities; explicit aliases suppress the deterministic ID. */
|
|
170
|
+
function toolCatalogIds(target, inventory = exports.toolCatalogMigrations) {
|
|
171
|
+
(0, tool_catalog_identity_1.validateToolCatalogTarget)(target);
|
|
172
|
+
const key = (0, tool_catalog_identity_1.toolCatalogTargetKey)(target);
|
|
173
|
+
const ids = [
|
|
174
|
+
...new Set(inventory.filter((entry) => (0, tool_catalog_identity_1.toolCatalogTargetKey)(entry) === key).map((entry) => entry.toolId)),
|
|
175
|
+
];
|
|
176
|
+
for (const id of ids)
|
|
177
|
+
resolveLegacyToolId(id, inventory);
|
|
178
|
+
return ids.length ? ids : [(0, tool_catalog_identity_1.deriveToolCatalogId)(target)];
|
|
179
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { DataContext } from "../context/data-context";
|
|
2
|
+
import { type ITool } from "../data/tools";
|
|
3
|
+
import type { IContractCallContext } from "./contract-proxy";
|
|
4
|
+
import type { IGetToolCatalogInput, IInvokeToolCatalogInput, IListToolCatalogInput, IToolCatalogEntry } from "./system/tool-catalog-contract";
|
|
5
|
+
import { type ToolCatalogTarget } from "./tool-catalog-identity";
|
|
6
|
+
/** Host-only variable resolution passed to the target endpoint. */
|
|
7
|
+
export interface IToolCatalogInvokeOptions {
|
|
8
|
+
/** Trusted Device Operations only: retain the remote caller’s own identity. */
|
|
9
|
+
allowRemoteCaller?: boolean;
|
|
10
|
+
/** Host workflow admission bound; a provider change must not exceed already authorized policy. */
|
|
11
|
+
maxAccessLevel?: number;
|
|
12
|
+
resolveVariable?: (variableName: string, requestingToolId: string) => Promise<string>;
|
|
13
|
+
}
|
|
14
|
+
/** System tools admitted to workflows; administrative contracts remain excluded. */
|
|
15
|
+
export declare const workflowInvocableSystemContractIds: ReadonlySet<string>;
|
|
16
|
+
/** Whether a contract target may execute inside a workflow or assistant run. */
|
|
17
|
+
export declare function isWorkflowInvocableTarget(target: ToolCatalogTarget): boolean;
|
|
18
|
+
/** Synchronously describe a row using registry state only. Callers await catalogReady first. */
|
|
19
|
+
export declare function describeToolCatalogRow(dataContext: DataContext, row: ITool): IToolCatalogEntry;
|
|
20
|
+
/** List bounded catalog rows after the context's catalog initialization. */
|
|
21
|
+
export declare function listToolCatalogEntries(dataContext: DataContext, input?: IListToolCatalogInput): Promise<IToolCatalogEntry[]>;
|
|
22
|
+
/** Resolve one identity without letting unavailable IDs fall through to unrelated names. */
|
|
23
|
+
export declare function findToolCatalogEntry(dataContext: DataContext, input: IGetToolCatalogInput, callerContext?: IContractCallContext): Promise<IToolCatalogEntry | undefined>;
|
|
24
|
+
/** Project live policy without resolving endpoints or starting isolated workers. */
|
|
25
|
+
export declare function projectToolCatalogAccess(dataContext: DataContext, entry: IToolCatalogEntry, callerContext: IContractCallContext): Promise<IToolCatalogEntry>;
|
|
26
|
+
/**
|
|
27
|
+
* Validate and invoke a contract target through the selected provider with original authority.
|
|
28
|
+
* Never dispatches legacy code. Disposes every endpoint and retries only its own retirement once.
|
|
29
|
+
*/
|
|
30
|
+
export declare function invokeToolCatalogTool(dataContext: DataContext, input: IInvokeToolCatalogInput, context: IContractCallContext, opts?: IToolCatalogInvokeOptions): Promise<unknown>;
|