@peers-app/peers-sdk 0.9.5 → 0.10.3
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/data/assistants.d.ts +10 -0
- package/dist/data/assistants.js +28 -7
- package/dist/data/index.d.ts +1 -0
- package/dist/data/index.js +1 -0
- package/dist/data/package-version-permissions.d.ts +7 -0
- package/dist/data/package-version-permissions.js +18 -0
- package/dist/data/package-versions.d.ts +96 -0
- package/dist/data/package-versions.js +162 -0
- package/dist/data/packages.d.ts +11 -20
- package/dist/data/packages.js +3 -6
- package/dist/data/packages.utils.js +21 -23
- package/dist/device/get-trust-level-fn.d.ts +2 -1
- package/dist/device/get-trust-level-fn.js +42 -5
- package/dist/package-loader/package-loader.js +14 -3
- package/dist/rpc-types.d.ts +2 -1
- package/dist/rpc-types.js +2 -0
- package/dist/system-ids.d.ts +1 -0
- package/dist/system-ids.js +2 -1
- package/package.json +1 -1
|
@@ -52,6 +52,16 @@ export declare function Assistants(dataContext?: DataContext): import("./orm").T
|
|
|
52
52
|
description?: string | undefined;
|
|
53
53
|
updatedAt?: Date | undefined;
|
|
54
54
|
}>;
|
|
55
|
+
/**
|
|
56
|
+
* Per-user primary assistant preference for the current group.
|
|
57
|
+
* Overrides the group default when set. Synced across the user's devices.
|
|
58
|
+
*/
|
|
59
|
+
export declare const userPrimaryAssistantVar: import("./persistent-vars").PersistentVar<string | undefined>;
|
|
60
|
+
/**
|
|
61
|
+
* Group-wide default primary assistant. Applies to all members who haven't set
|
|
62
|
+
* their own preference. Can be set by group admins. Synced to all group members.
|
|
63
|
+
*/
|
|
64
|
+
export declare const groupPrimaryAssistantVar: import("./persistent-vars").PersistentVar<string | undefined>;
|
|
55
65
|
export declare const getPrimaryAssistant: (dataContext?: DataContext) => Promise<{
|
|
56
66
|
name: string;
|
|
57
67
|
createdAt: Date;
|
package/dist/data/assistants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getPrimaryAssistant = exports.assistantSchema = exports.ToolInclusionStrategy = void 0;
|
|
3
|
+
exports.getPrimaryAssistant = exports.groupPrimaryAssistantVar = exports.userPrimaryAssistantVar = exports.assistantSchema = exports.ToolInclusionStrategy = void 0;
|
|
4
4
|
exports.Assistants = Assistants;
|
|
5
5
|
exports.getAllAssistantIdsMentioned = getAllAssistantIdsMentioned;
|
|
6
6
|
const mentions_1 = require("../mentions");
|
|
@@ -48,14 +48,35 @@ const metaData = {
|
|
|
48
48
|
function Assistants(dataContext) {
|
|
49
49
|
return (0, user_context_singleton_1.getTableContainer)(dataContext).getTable(metaData, exports.assistantSchema);
|
|
50
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Per-user primary assistant preference for the current group.
|
|
53
|
+
* Overrides the group default when set. Synced across the user's devices.
|
|
54
|
+
*/
|
|
55
|
+
exports.userPrimaryAssistantVar = (0, persistent_vars_1.groupUserVar)('userPrimaryAssistantId');
|
|
56
|
+
/**
|
|
57
|
+
* Group-wide default primary assistant. Applies to all members who haven't set
|
|
58
|
+
* their own preference. Can be set by group admins. Synced to all group members.
|
|
59
|
+
*/
|
|
60
|
+
exports.groupPrimaryAssistantVar = (0, persistent_vars_1.groupVar)('groupPrimaryAssistantId');
|
|
51
61
|
const getPrimaryAssistant = async (dataContext) => {
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
62
|
+
await exports.userPrimaryAssistantVar.loadingPromise;
|
|
63
|
+
const userAssistantId = (0, exports.userPrimaryAssistantVar)();
|
|
64
|
+
if (userAssistantId) {
|
|
65
|
+
const a = await Assistants(dataContext).get(userAssistantId);
|
|
66
|
+
if (a)
|
|
67
|
+
return a;
|
|
68
|
+
}
|
|
69
|
+
await exports.groupPrimaryAssistantVar.loadingPromise;
|
|
70
|
+
const groupAssistantId = (0, exports.groupPrimaryAssistantVar)();
|
|
71
|
+
if (groupAssistantId) {
|
|
72
|
+
const a = await Assistants(dataContext).get(groupAssistantId);
|
|
73
|
+
if (a)
|
|
74
|
+
return a;
|
|
57
75
|
}
|
|
58
|
-
|
|
76
|
+
const fallback = await Assistants(dataContext).get(system_ids_1.openCodeAssistantId);
|
|
77
|
+
if (!fallback)
|
|
78
|
+
throw new Error('Primary assistant not found');
|
|
79
|
+
return fallback;
|
|
59
80
|
};
|
|
60
81
|
exports.getPrimaryAssistant = getPrimaryAssistant;
|
|
61
82
|
async function getAllAssistantIdsMentioned(message) {
|
package/dist/data/index.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export * from "./knowledge/knowledge-values";
|
|
|
17
17
|
export * from "./knowledge/peer-types";
|
|
18
18
|
export * from "./knowledge/predicates";
|
|
19
19
|
export * from "./messages";
|
|
20
|
+
export * from "./package-versions";
|
|
20
21
|
export * from "./packages";
|
|
21
22
|
export * from "./packages.utils";
|
|
22
23
|
export * from "./table-definitions-table";
|
package/dist/data/index.js
CHANGED
|
@@ -33,6 +33,7 @@ __exportStar(require("./knowledge/knowledge-values"), exports);
|
|
|
33
33
|
__exportStar(require("./knowledge/peer-types"), exports);
|
|
34
34
|
__exportStar(require("./knowledge/predicates"), exports);
|
|
35
35
|
__exportStar(require("./messages"), exports);
|
|
36
|
+
__exportStar(require("./package-versions"), exports);
|
|
36
37
|
__exportStar(require("./packages"), exports);
|
|
37
38
|
__exportStar(require("./packages.utils"), exports);
|
|
38
39
|
__exportStar(require("./table-definitions-table"), exports);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { IPackageVersion } from './package-versions';
|
|
2
|
+
/**
|
|
3
|
+
* Verifies that a package version update signature is valid, throws on invalid signature
|
|
4
|
+
* @param packageVersion The package version record to verify
|
|
5
|
+
* @throws Error if signature is invalid or unauthorized
|
|
6
|
+
*/
|
|
7
|
+
export declare function verifyPackageVersionSignature(packageVersion: IPackageVersion, groupId: string): Promise<void>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.verifyPackageVersionSignature = verifyPackageVersionSignature;
|
|
4
|
+
const keys_1 = require("../keys");
|
|
5
|
+
const group_permissions_1 = require("./group-permissions");
|
|
6
|
+
/**
|
|
7
|
+
* Verifies that a package version update signature is valid, throws on invalid signature
|
|
8
|
+
* @param packageVersion The package version record to verify
|
|
9
|
+
* @throws Error if signature is invalid or unauthorized
|
|
10
|
+
*/
|
|
11
|
+
async function verifyPackageVersionSignature(packageVersion, groupId) {
|
|
12
|
+
(0, keys_1.verifyObjectSignature)(packageVersion);
|
|
13
|
+
const signerPublicKey = (0, keys_1.getPublicKeyFromObjectSignature)(packageVersion) ?? '';
|
|
14
|
+
const signerRole = await (0, group_permissions_1.getUserRoleFromPublicKey)(groupId, signerPublicKey);
|
|
15
|
+
if (signerRole < group_permissions_1.GroupMemberRole.Admin) {
|
|
16
|
+
throw new Error('Only group admins can create or update package versions');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { DataContext } from "../context/data-context";
|
|
3
|
+
import type { ISaveOptions } from "./orm/data-query";
|
|
4
|
+
import { Table } from "./orm/table";
|
|
5
|
+
declare const schema: z.ZodObject<{
|
|
6
|
+
packageVersionId: z.ZodEffects<z.ZodString, string, string>;
|
|
7
|
+
packageId: z.ZodEffects<z.ZodString, string, string>;
|
|
8
|
+
version: z.ZodString;
|
|
9
|
+
versionTag: z.ZodOptional<z.ZodString>;
|
|
10
|
+
packageVersionHash: z.ZodString;
|
|
11
|
+
packageBundleFileId: z.ZodEffects<z.ZodString, string, string>;
|
|
12
|
+
packageBundleFileHash: z.ZodString;
|
|
13
|
+
routesBundleFileId: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
14
|
+
routesBundleFileHash: z.ZodOptional<z.ZodString>;
|
|
15
|
+
uiBundleFileId: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
16
|
+
uiBundleFileHash: z.ZodOptional<z.ZodString>;
|
|
17
|
+
appNavs: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
18
|
+
name: z.ZodString;
|
|
19
|
+
displayName: z.ZodOptional<z.ZodString>;
|
|
20
|
+
iconClassName: z.ZodString;
|
|
21
|
+
navigationPath: z.ZodString;
|
|
22
|
+
}, "strip", z.ZodTypeAny, {
|
|
23
|
+
name: string;
|
|
24
|
+
iconClassName: string;
|
|
25
|
+
navigationPath: string;
|
|
26
|
+
displayName?: string | undefined;
|
|
27
|
+
}, {
|
|
28
|
+
name: string;
|
|
29
|
+
iconClassName: string;
|
|
30
|
+
navigationPath: string;
|
|
31
|
+
displayName?: string | undefined;
|
|
32
|
+
}>, "many">>;
|
|
33
|
+
signature: z.ZodString;
|
|
34
|
+
createdBy: z.ZodEffects<z.ZodString, string, string>;
|
|
35
|
+
createdAt: z.ZodString;
|
|
36
|
+
}, "strip", z.ZodTypeAny, {
|
|
37
|
+
signature: string;
|
|
38
|
+
createdAt: string;
|
|
39
|
+
createdBy: string;
|
|
40
|
+
packageId: string;
|
|
41
|
+
packageVersionId: string;
|
|
42
|
+
version: string;
|
|
43
|
+
packageVersionHash: string;
|
|
44
|
+
packageBundleFileId: string;
|
|
45
|
+
packageBundleFileHash: string;
|
|
46
|
+
versionTag?: string | undefined;
|
|
47
|
+
routesBundleFileId?: string | undefined;
|
|
48
|
+
routesBundleFileHash?: string | undefined;
|
|
49
|
+
uiBundleFileId?: string | undefined;
|
|
50
|
+
uiBundleFileHash?: string | undefined;
|
|
51
|
+
appNavs?: {
|
|
52
|
+
name: string;
|
|
53
|
+
iconClassName: string;
|
|
54
|
+
navigationPath: string;
|
|
55
|
+
displayName?: string | undefined;
|
|
56
|
+
}[] | undefined;
|
|
57
|
+
}, {
|
|
58
|
+
signature: string;
|
|
59
|
+
createdAt: string;
|
|
60
|
+
createdBy: string;
|
|
61
|
+
packageId: string;
|
|
62
|
+
packageVersionId: string;
|
|
63
|
+
version: string;
|
|
64
|
+
packageVersionHash: string;
|
|
65
|
+
packageBundleFileId: string;
|
|
66
|
+
packageBundleFileHash: string;
|
|
67
|
+
versionTag?: string | undefined;
|
|
68
|
+
routesBundleFileId?: string | undefined;
|
|
69
|
+
routesBundleFileHash?: string | undefined;
|
|
70
|
+
uiBundleFileId?: string | undefined;
|
|
71
|
+
uiBundleFileHash?: string | undefined;
|
|
72
|
+
appNavs?: {
|
|
73
|
+
name: string;
|
|
74
|
+
iconClassName: string;
|
|
75
|
+
navigationPath: string;
|
|
76
|
+
displayName?: string | undefined;
|
|
77
|
+
}[] | undefined;
|
|
78
|
+
}>;
|
|
79
|
+
export type IPackageVersion = z.infer<typeof schema>;
|
|
80
|
+
export declare class PackageVersionsTable extends Table<IPackageVersion> {
|
|
81
|
+
static isPassthrough: boolean;
|
|
82
|
+
insert(packageVersion: IPackageVersion, opts?: ISaveOptions): Promise<IPackageVersion>;
|
|
83
|
+
update(packageVersion: IPackageVersion, opts?: ISaveOptions): Promise<IPackageVersion>;
|
|
84
|
+
save(packageVersion: IPackageVersion, opts?: ISaveOptions): Promise<IPackageVersion>;
|
|
85
|
+
signAndSave(packageVersion: IPackageVersion, opts?: ISaveOptions): Promise<IPackageVersion>;
|
|
86
|
+
private static addSignatureToPackageVersion;
|
|
87
|
+
static enablePackageVersionSigning(fn: (packageVersion: IPackageVersion) => IPackageVersion): void;
|
|
88
|
+
}
|
|
89
|
+
export declare function PackageVersions(dataContext?: DataContext): PackageVersionsTable;
|
|
90
|
+
/**
|
|
91
|
+
* Compute a hash combining the bundle file hashes to uniquely identify this version's content.
|
|
92
|
+
*/
|
|
93
|
+
export declare function computePackageVersionHash(version: string, versionTag: string, packageBundleFileHash: string, routesBundleFileHash?: string, uiBundleFileHash?: string): string;
|
|
94
|
+
export declare function isVersionInRange(activeVersion: string, incomingVersion: string, range: 'pinned' | 'patch' | 'minor' | 'latest'): boolean;
|
|
95
|
+
export declare function doesTagMatch(activeVersionTag: string | undefined, incomingVersionTag: string | undefined, followVersionTags: string | undefined, deviceVersionTag: string | undefined): boolean;
|
|
96
|
+
export {};
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
3
|
+
var useValue = arguments.length > 2;
|
|
4
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
5
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
6
|
+
}
|
|
7
|
+
return useValue ? value : void 0;
|
|
8
|
+
};
|
|
9
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
10
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
11
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
12
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
13
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
14
|
+
var _, done = false;
|
|
15
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
16
|
+
var context = {};
|
|
17
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
18
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
19
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
20
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
21
|
+
if (kind === "accessor") {
|
|
22
|
+
if (result === void 0) continue;
|
|
23
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
24
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
25
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
26
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
27
|
+
}
|
|
28
|
+
else if (_ = accept(result)) {
|
|
29
|
+
if (kind === "field") initializers.unshift(_);
|
|
30
|
+
else descriptor[key] = _;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
34
|
+
done = true;
|
|
35
|
+
};
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.PackageVersionsTable = void 0;
|
|
38
|
+
exports.PackageVersions = PackageVersions;
|
|
39
|
+
exports.computePackageVersionHash = computePackageVersionHash;
|
|
40
|
+
exports.isVersionInRange = isVersionInRange;
|
|
41
|
+
exports.doesTagMatch = doesTagMatch;
|
|
42
|
+
const zod_1 = require("zod");
|
|
43
|
+
const context_1 = require("../context");
|
|
44
|
+
const keys_1 = require("../keys");
|
|
45
|
+
const app_nav_1 = require("../types/app-nav");
|
|
46
|
+
const zod_types_1 = require("../types/zod-types");
|
|
47
|
+
const decorators_1 = require("./orm/decorators");
|
|
48
|
+
const table_1 = require("./orm/table");
|
|
49
|
+
const table_definitions_system_1 = require("./orm/table-definitions.system");
|
|
50
|
+
const types_1 = require("./orm/types");
|
|
51
|
+
const package_version_permissions_1 = require("./package-version-permissions");
|
|
52
|
+
const schema = zod_1.z.object({
|
|
53
|
+
packageVersionId: zod_types_1.zodPeerId,
|
|
54
|
+
packageId: zod_types_1.zodPeerId.describe('The package this version belongs to'),
|
|
55
|
+
version: zod_1.z.string().describe('Semantic version string (e.g., "1.0.0")'),
|
|
56
|
+
versionTag: zod_1.z.string().optional().describe('Version tag (e.g., "stable", "beta")'),
|
|
57
|
+
packageVersionHash: zod_1.z.string().describe('Hash of the combined bundle file hashes'),
|
|
58
|
+
packageBundleFileId: zod_types_1.zodPeerId.describe('File ID of the package bundle'),
|
|
59
|
+
packageBundleFileHash: zod_1.z.string().describe('Hash of the package bundle file'),
|
|
60
|
+
routesBundleFileId: zod_types_1.zodPeerId.optional().describe('File ID of the routes bundle'),
|
|
61
|
+
routesBundleFileHash: zod_1.z.string().optional().describe('Hash of the routes bundle'),
|
|
62
|
+
uiBundleFileId: zod_types_1.zodPeerId.optional().describe('File ID of the UI bundle'),
|
|
63
|
+
uiBundleFileHash: zod_1.z.string().optional().describe('Hash of the UI bundle'),
|
|
64
|
+
appNavs: app_nav_1.appNavSchema.array().optional().describe('The app navigation items that this version provides'),
|
|
65
|
+
signature: zod_1.z.string().describe('The signed hash of this data excluding the signature itself'),
|
|
66
|
+
createdBy: zod_types_1.zodPeerId.describe('The user who created this version'),
|
|
67
|
+
createdAt: zod_1.z.string().describe('ISO timestamp of when this version was created'),
|
|
68
|
+
});
|
|
69
|
+
const metaData = {
|
|
70
|
+
name: 'PackageVersions',
|
|
71
|
+
description: 'Versioned builds of packages',
|
|
72
|
+
primaryKeyName: 'packageVersionId',
|
|
73
|
+
iconClassName: 'bi bi-tag-fill',
|
|
74
|
+
fields: (0, types_1.schemaToFields)(schema),
|
|
75
|
+
indexes: [{ fields: ['packageId'] }],
|
|
76
|
+
};
|
|
77
|
+
let PackageVersionsTable = (() => {
|
|
78
|
+
let _classSuper = table_1.Table;
|
|
79
|
+
let _instanceExtraInitializers = [];
|
|
80
|
+
let _signAndSave_decorators;
|
|
81
|
+
return class PackageVersionsTable extends _classSuper {
|
|
82
|
+
static {
|
|
83
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
84
|
+
_signAndSave_decorators = [(0, decorators_1.ProxyClientTableMethodCalls)()];
|
|
85
|
+
__esDecorate(this, null, _signAndSave_decorators, { kind: "method", name: "signAndSave", static: false, private: false, access: { has: obj => "signAndSave" in obj, get: obj => obj.signAndSave }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
86
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
87
|
+
}
|
|
88
|
+
static isPassthrough = false;
|
|
89
|
+
async insert(packageVersion, opts) {
|
|
90
|
+
return this.save(packageVersion, opts);
|
|
91
|
+
}
|
|
92
|
+
async update(packageVersion, opts) {
|
|
93
|
+
return this.save(packageVersion, opts);
|
|
94
|
+
}
|
|
95
|
+
async save(packageVersion, opts) {
|
|
96
|
+
if (PackageVersionsTable.isPassthrough) {
|
|
97
|
+
return super.save(packageVersion, opts);
|
|
98
|
+
}
|
|
99
|
+
if (!this.groupId) {
|
|
100
|
+
// users can do whatever they want to package versions in their personal space
|
|
101
|
+
return super.save(packageVersion, opts);
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
await (0, package_version_permissions_1.verifyPackageVersionSignature)(packageVersion, this.groupId);
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
throw new Error('Package version verification failed. Did you mean to call `signAndSave`?', { cause: err });
|
|
108
|
+
}
|
|
109
|
+
return super.save(packageVersion, opts);
|
|
110
|
+
}
|
|
111
|
+
async signAndSave(packageVersion, opts) {
|
|
112
|
+
if (!PackageVersionsTable.addSignatureToPackageVersion) {
|
|
113
|
+
throw new Error('Package version signing is not enabled. Call PackageVersionsTable.enablePackageVersionSigning(fn) to enable it.');
|
|
114
|
+
}
|
|
115
|
+
packageVersion = await PackageVersionsTable.addSignatureToPackageVersion(packageVersion);
|
|
116
|
+
return super.save(packageVersion, opts);
|
|
117
|
+
}
|
|
118
|
+
static addSignatureToPackageVersion = undefined;
|
|
119
|
+
static enablePackageVersionSigning(fn) {
|
|
120
|
+
this.addSignatureToPackageVersion = fn;
|
|
121
|
+
}
|
|
122
|
+
constructor() {
|
|
123
|
+
super(...arguments);
|
|
124
|
+
__runInitializers(this, _instanceExtraInitializers);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
})();
|
|
128
|
+
exports.PackageVersionsTable = PackageVersionsTable;
|
|
129
|
+
(0, table_definitions_system_1.registerSystemTableDefinition)(metaData, schema, PackageVersionsTable);
|
|
130
|
+
function PackageVersions(dataContext) {
|
|
131
|
+
return (0, context_1.getTableContainer)(dataContext).getTable(metaData, schema, PackageVersionsTable);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Compute a hash combining the bundle file hashes to uniquely identify this version's content.
|
|
135
|
+
*/
|
|
136
|
+
function computePackageVersionHash(version, versionTag, packageBundleFileHash, routesBundleFileHash, uiBundleFileHash) {
|
|
137
|
+
return (0, keys_1.hashValue)([version, versionTag, packageBundleFileHash, routesBundleFileHash ?? '', uiBundleFileHash ?? ''].join(':'));
|
|
138
|
+
}
|
|
139
|
+
function isVersionInRange(activeVersion, incomingVersion, range) {
|
|
140
|
+
if (range === 'pinned')
|
|
141
|
+
return false;
|
|
142
|
+
if (range === 'latest')
|
|
143
|
+
return true;
|
|
144
|
+
const [aMaj, aMin] = activeVersion.split('.').map(Number);
|
|
145
|
+
const [iMaj, iMin] = incomingVersion.split('.').map(Number);
|
|
146
|
+
if (range === 'patch')
|
|
147
|
+
return aMaj === iMaj && aMin === iMin;
|
|
148
|
+
if (range === 'minor')
|
|
149
|
+
return aMaj === iMaj;
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
function doesTagMatch(activeVersionTag, incomingVersionTag, followVersionTags, deviceVersionTag) {
|
|
153
|
+
const inTag = incomingVersionTag || 'stable';
|
|
154
|
+
if (deviceVersionTag)
|
|
155
|
+
return inTag === deviceVersionTag;
|
|
156
|
+
if (!followVersionTags) {
|
|
157
|
+
return inTag === (activeVersionTag || 'stable');
|
|
158
|
+
}
|
|
159
|
+
if (followVersionTags === '*')
|
|
160
|
+
return true;
|
|
161
|
+
return followVersionTags.split(',').map(t => t.trim()).includes(inTag);
|
|
162
|
+
}
|
package/dist/data/packages.d.ts
CHANGED
|
@@ -26,12 +26,9 @@ declare const schema: z.ZodObject<{
|
|
|
26
26
|
navigationPath: string;
|
|
27
27
|
displayName?: string | undefined;
|
|
28
28
|
}>, "many">>;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
routesBundleFileHash: z.ZodOptional<z.ZodString>;
|
|
33
|
-
uiBundleFileId: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
34
|
-
uiBundleFileHash: z.ZodOptional<z.ZodString>;
|
|
29
|
+
activePackageVersionId: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
30
|
+
versionFollowRange: z.ZodOptional<z.ZodEnum<["pinned", "patch", "minor", "latest"]>>;
|
|
31
|
+
followVersionTags: z.ZodOptional<z.ZodString>;
|
|
35
32
|
signature: z.ZodString;
|
|
36
33
|
}, "strip", z.ZodTypeAny, {
|
|
37
34
|
name: string;
|
|
@@ -40,20 +37,17 @@ declare const schema: z.ZodObject<{
|
|
|
40
37
|
createdBy: string;
|
|
41
38
|
packageId: string;
|
|
42
39
|
localPath: string;
|
|
43
|
-
packageBundleFileId: string;
|
|
44
|
-
packageBundleFileHash: string;
|
|
45
40
|
disabled?: boolean | undefined;
|
|
46
|
-
remoteRepo?: string | undefined;
|
|
47
41
|
appNavs?: {
|
|
48
42
|
name: string;
|
|
49
43
|
iconClassName: string;
|
|
50
44
|
navigationPath: string;
|
|
51
45
|
displayName?: string | undefined;
|
|
52
46
|
}[] | undefined;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
47
|
+
remoteRepo?: string | undefined;
|
|
48
|
+
activePackageVersionId?: string | undefined;
|
|
49
|
+
versionFollowRange?: "pinned" | "patch" | "minor" | "latest" | undefined;
|
|
50
|
+
followVersionTags?: string | undefined;
|
|
57
51
|
}, {
|
|
58
52
|
name: string;
|
|
59
53
|
description: string;
|
|
@@ -61,20 +55,17 @@ declare const schema: z.ZodObject<{
|
|
|
61
55
|
createdBy: string;
|
|
62
56
|
packageId: string;
|
|
63
57
|
localPath: string;
|
|
64
|
-
packageBundleFileId: string;
|
|
65
|
-
packageBundleFileHash: string;
|
|
66
58
|
disabled?: boolean | undefined;
|
|
67
|
-
remoteRepo?: string | undefined;
|
|
68
59
|
appNavs?: {
|
|
69
60
|
name: string;
|
|
70
61
|
iconClassName: string;
|
|
71
62
|
navigationPath: string;
|
|
72
63
|
displayName?: string | undefined;
|
|
73
64
|
}[] | undefined;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
65
|
+
remoteRepo?: string | undefined;
|
|
66
|
+
activePackageVersionId?: string | undefined;
|
|
67
|
+
versionFollowRange?: "pinned" | "patch" | "minor" | "latest" | undefined;
|
|
68
|
+
followVersionTags?: string | undefined;
|
|
78
69
|
}>;
|
|
79
70
|
export type IPackage = z.infer<typeof schema>;
|
|
80
71
|
export declare class PackagesTable extends Table<IPackage> {
|
package/dist/data/packages.js
CHANGED
|
@@ -55,12 +55,9 @@ const schema = zod_1.z.object({
|
|
|
55
55
|
disabled: zod_1.z.boolean().optional().describe("Whether the package's components should be loaded and included in the app runtime"),
|
|
56
56
|
remoteRepo: zod_1.z.string().optional().describe('The remote repository where the package is stored'),
|
|
57
57
|
appNavs: app_nav_1.appNavSchema.array().optional().describe('The app navigation items that this package provides'),
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
routesBundleFileHash: zod_1.z.string().optional().describe('Hash of the routes bundle (optional)'),
|
|
62
|
-
uiBundleFileId: zod_types_1.zodPeerId.optional().describe('File ID of the UI bundle (optional)'),
|
|
63
|
-
uiBundleFileHash: zod_1.z.string().optional().describe('Hash of the UI bundle (optional)'),
|
|
58
|
+
activePackageVersionId: zod_types_1.zodPeerId.optional().describe('FK to PackageVersions — the currently active version'),
|
|
59
|
+
versionFollowRange: zod_1.z.enum(['pinned', 'patch', 'minor', 'latest']).optional().describe('Auto-update range: pinned=never, patch=same major.minor, minor=same major, latest=always'),
|
|
60
|
+
followVersionTags: zod_1.z.string().optional().describe('Tag policy: undefined="current" (follow active tag), "*"=any tag, or CSV like "stable,prod"'),
|
|
64
61
|
signature: zod_1.z.string().describe('The signed hash of this data excluding the signature itself'),
|
|
65
62
|
});
|
|
66
63
|
const metaData = {
|
|
@@ -3,6 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.copyPackageToAnotherDataContext = copyPackageToAnotherDataContext;
|
|
4
4
|
const packages_1 = require("./packages");
|
|
5
5
|
const files_1 = require("./files");
|
|
6
|
+
const package_versions_1 = require("./package-versions");
|
|
7
|
+
async function copyBundleFile(fileId, fromFiles, toFiles, label) {
|
|
8
|
+
if (!fileId)
|
|
9
|
+
return;
|
|
10
|
+
const file = await fromFiles.get(fileId);
|
|
11
|
+
if (file) {
|
|
12
|
+
await toFiles.saveFileRecord(file);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
console.warn(`${label} file ${fileId} not found in source context`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
6
18
|
async function copyPackageToAnotherDataContext(packageId, fromDataContext, toDataContext) {
|
|
7
19
|
const fromPackages = (0, packages_1.Packages)(fromDataContext);
|
|
8
20
|
const toPackages = (0, packages_1.Packages)(toDataContext);
|
|
@@ -12,29 +24,15 @@ async function copyPackageToAnotherDataContext(packageId, fromDataContext, toDat
|
|
|
12
24
|
}
|
|
13
25
|
const fromFiles = (0, files_1.Files)(fromDataContext);
|
|
14
26
|
const toFiles = (0, files_1.Files)(toDataContext);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (routesBundleFile) {
|
|
25
|
-
await toFiles.saveFileRecord(routesBundleFile);
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
throw new Error(`Routes bundle file ${pkg.routesBundleFileId} not found in fromDataContext`);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
if (pkg.uiBundleFileId) {
|
|
32
|
-
const uiBundleFile = await fromFiles.get(pkg.uiBundleFileId);
|
|
33
|
-
if (uiBundleFile) {
|
|
34
|
-
await toFiles.saveFileRecord(uiBundleFile);
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
throw new Error(`UI bundle file ${pkg.uiBundleFileId} not found in fromDataContext`);
|
|
27
|
+
if (pkg.activePackageVersionId) {
|
|
28
|
+
const fromPvTable = (0, package_versions_1.PackageVersions)(fromDataContext);
|
|
29
|
+
const toPvTable = (0, package_versions_1.PackageVersions)(toDataContext);
|
|
30
|
+
const pv = await fromPvTable.get(pkg.activePackageVersionId);
|
|
31
|
+
if (pv) {
|
|
32
|
+
await copyBundleFile(pv.packageBundleFileId, fromFiles, toFiles, 'Version package bundle');
|
|
33
|
+
await copyBundleFile(pv.routesBundleFileId, fromFiles, toFiles, 'Version routes bundle');
|
|
34
|
+
await copyBundleFile(pv.uiBundleFileId, fromFiles, toFiles, 'Version UI bundle');
|
|
35
|
+
await toPvTable.signAndSave(pv, { saveAsSnapshot: true });
|
|
38
36
|
}
|
|
39
37
|
}
|
|
40
38
|
return toPackages.signAndSave(pkg);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { UserContext } from "../context";
|
|
1
2
|
import { IDeviceInfo } from "../data";
|
|
2
3
|
import { TrustLevel } from "./socket.type";
|
|
3
|
-
export declare function getTrustLevelFn(me: Pick<IDeviceInfo, 'userId' | 'publicKey' | 'publicBoxKey'>, serverUrl?: string): (deviceInfo: IDeviceInfo, registerNew?: boolean) => Promise<TrustLevel>;
|
|
4
|
+
export declare function getTrustLevelFn(me: Pick<IDeviceInfo, 'userId' | 'publicKey' | 'publicBoxKey'>, serverUrl?: string, injectedUserContext?: UserContext): (deviceInfo: IDeviceInfo, registerNew?: boolean) => Promise<TrustLevel>;
|
|
@@ -4,9 +4,9 @@ exports.getTrustLevelFn = getTrustLevelFn;
|
|
|
4
4
|
const context_1 = require("../context");
|
|
5
5
|
const data_1 = require("../data");
|
|
6
6
|
const socket_type_1 = require("./socket.type");
|
|
7
|
-
function getTrustLevelFn(me, serverUrl) {
|
|
7
|
+
function getTrustLevelFn(me, serverUrl, injectedUserContext) {
|
|
8
8
|
return async function getTrustLevel(deviceInfo, registerNew) {
|
|
9
|
-
const userContext = await (0, context_1.getUserContext)();
|
|
9
|
+
const userContext = injectedUserContext ?? await (0, context_1.getUserContext)();
|
|
10
10
|
const userDataContext = userContext.userDataContext;
|
|
11
11
|
// if this is my own device it is trusted
|
|
12
12
|
if (deviceInfo.userId === me.userId && deviceInfo.publicKey === me.publicKey && deviceInfo.publicBoxKey === me.publicBoxKey) {
|
|
@@ -43,9 +43,32 @@ function getTrustLevelFn(me, serverUrl) {
|
|
|
43
43
|
}
|
|
44
44
|
// TODO check user trust level, if they are untrusted, return immediately
|
|
45
45
|
if (user && device && !(deviceInfo.userId === device.userId && deviceInfo.userId === user.userId && deviceInfo.publicKey === user.publicKey && deviceInfo.publicBoxKey === user.publicBoxKey)) {
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
|
|
46
|
+
// The stored user record has different public keys than what this device is presenting.
|
|
47
|
+
//
|
|
48
|
+
// By the time getTrustLevel is called the handshake has already been
|
|
49
|
+
// cryptographically verified: the connecting device proved ownership of
|
|
50
|
+
// deviceInfo.publicKey by signing the IDeviceHandshake with the
|
|
51
|
+
// corresponding secret key (verified in Device.handshakeResponse via
|
|
52
|
+
// openSignedObject). The stored record is therefore stale — most
|
|
53
|
+
// commonly because it was synced from a relay before the first direct
|
|
54
|
+
// WebRTC connection and the relay's copy had wrong/empty keys.
|
|
55
|
+
//
|
|
56
|
+
// Rather than returning Untrusted (which would permanently block this
|
|
57
|
+
// device on every reconnect after the first), we refresh the stored
|
|
58
|
+
// keys with the verified values. The signature is cleared so a
|
|
59
|
+
// subsequent sync of the real signed user record can replace this
|
|
60
|
+
// interim version.
|
|
61
|
+
if (deviceInfo.userId === device.userId) {
|
|
62
|
+
user.publicKey = deviceInfo.publicKey;
|
|
63
|
+
user.publicBoxKey = deviceInfo.publicBoxKey;
|
|
64
|
+
const { signature: _sig, ...userWithoutSig } = user;
|
|
65
|
+
await (0, data_1.Users)(userDataContext).save(userWithoutSig, { restoreIfDeleted: true });
|
|
66
|
+
user = userWithoutSig;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
// userId mismatch — genuinely untrusted
|
|
70
|
+
return socket_type_1.TrustLevel.Untrusted;
|
|
71
|
+
}
|
|
49
72
|
}
|
|
50
73
|
if (userTrustLevel?.trustLevel && userTrustLevel.trustLevel >= socket_type_1.TrustLevel.Trusted && device?.trustLevel && device.trustLevel >= socket_type_1.TrustLevel.Trusted) {
|
|
51
74
|
device.lastSeen = new Date();
|
|
@@ -78,6 +101,7 @@ function getTrustLevelFn(me, serverUrl) {
|
|
|
78
101
|
}
|
|
79
102
|
trustLevel = device.trustLevel;
|
|
80
103
|
let newUser = false;
|
|
104
|
+
let staleUserKeys = false;
|
|
81
105
|
if (!user) {
|
|
82
106
|
user = {
|
|
83
107
|
userId: deviceInfo.userId,
|
|
@@ -88,6 +112,16 @@ function getTrustLevelFn(me, serverUrl) {
|
|
|
88
112
|
trustLevel = socket_type_1.TrustLevel.NewUser;
|
|
89
113
|
newUser = true;
|
|
90
114
|
}
|
|
115
|
+
else if (user.publicKey !== deviceInfo.publicKey || user.publicBoxKey !== deviceInfo.publicBoxKey) {
|
|
116
|
+
// User record exists but has stale keys (e.g. from a sync that arrived
|
|
117
|
+
// before this direct connection). Refresh them with the verified keys
|
|
118
|
+
// so subsequent connections don't hit the mismatch check above.
|
|
119
|
+
user.publicKey = deviceInfo.publicKey;
|
|
120
|
+
user.publicBoxKey = deviceInfo.publicBoxKey;
|
|
121
|
+
const { signature: _sig, ...userWithoutSig } = user;
|
|
122
|
+
user = userWithoutSig;
|
|
123
|
+
staleUserKeys = true;
|
|
124
|
+
}
|
|
91
125
|
// TODO - reimplement this, checks with peers to see if this is an untrusted device
|
|
92
126
|
// let remoteTrustLevel = TrustLevel.Unknown;
|
|
93
127
|
// for (const [serverUrl, conn] of Object.entries(getActiveConnections())) {
|
|
@@ -123,6 +157,9 @@ function getTrustLevelFn(me, serverUrl) {
|
|
|
123
157
|
weakInsert: true,
|
|
124
158
|
});
|
|
125
159
|
}
|
|
160
|
+
else if (staleUserKeys) {
|
|
161
|
+
await (0, data_1.Users)(userDataContext).save(user, { restoreIfDeleted: true });
|
|
162
|
+
}
|
|
126
163
|
// device.trustLevel = remoteTrustLevel || trustLevel;
|
|
127
164
|
await (0, data_1.Devices)(userDataContext).save(device, {
|
|
128
165
|
restoreIfDeleted: true,
|
|
@@ -4,6 +4,7 @@ exports.PackageLoader = void 0;
|
|
|
4
4
|
exports.setDefaultRequire = setDefaultRequire;
|
|
5
5
|
const tools_1 = require("../tools");
|
|
6
6
|
const files_1 = require("../data/files");
|
|
7
|
+
const package_versions_1 = require("../data/package-versions");
|
|
7
8
|
const packages_1 = require("../data/packages");
|
|
8
9
|
const tools_2 = require("../data/tools");
|
|
9
10
|
class PackageLoader {
|
|
@@ -30,14 +31,24 @@ class PackageLoader {
|
|
|
30
31
|
}
|
|
31
32
|
try {
|
|
32
33
|
let bundleCode = '';
|
|
33
|
-
|
|
34
|
+
let bundleFileId;
|
|
35
|
+
if (pkg.activePackageVersionId) {
|
|
36
|
+
try {
|
|
37
|
+
const pv = await (0, package_versions_1.PackageVersions)(this.dataContext).get(pkg.activePackageVersionId);
|
|
38
|
+
if (pv) {
|
|
39
|
+
bundleFileId = pv.packageBundleFileId;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch { /* no version record */ }
|
|
43
|
+
}
|
|
44
|
+
if (bundleFileId) {
|
|
34
45
|
const filesTable = (0, files_1.Files)(this.dataContext);
|
|
35
|
-
const bundleBuffer = await filesTable.getFileContents(
|
|
46
|
+
const bundleBuffer = await filesTable.getFileContents(bundleFileId);
|
|
36
47
|
if (bundleBuffer) {
|
|
37
48
|
bundleCode = Buffer.from(bundleBuffer).toString('utf8');
|
|
38
49
|
}
|
|
39
50
|
else {
|
|
40
|
-
console.warn(`Package bundle file not found for ${pkg.name} (fileId: ${
|
|
51
|
+
console.warn(`Package bundle file not found for ${pkg.name} (fileId: ${bundleFileId})`);
|
|
41
52
|
}
|
|
42
53
|
}
|
|
43
54
|
else {
|
package/dist/rpc-types.d.ts
CHANGED
|
@@ -61,11 +61,12 @@ export declare const rpcServerCalls: {
|
|
|
61
61
|
importGroupShare: ((groupShareJson: string) => Promise<string>);
|
|
62
62
|
appQuit: (() => Promise<void>);
|
|
63
63
|
appRestart: (() => Promise<void>);
|
|
64
|
-
dbQuery: ((query: string) => Promise<{
|
|
64
|
+
dbQuery: ((query: string, dataContextId?: string) => Promise<{
|
|
65
65
|
columns: string[];
|
|
66
66
|
rows: any[][];
|
|
67
67
|
rowCount: number;
|
|
68
68
|
}>);
|
|
69
|
+
runTool: ((toolId: string, args: Record<string, any>, dataContextId?: string, assistantId?: string) => Promise<any>);
|
|
69
70
|
uiReload: ((options?: {
|
|
70
71
|
ignoreCache?: boolean;
|
|
71
72
|
}) => Promise<void>);
|
package/dist/rpc-types.js
CHANGED
|
@@ -33,6 +33,8 @@ exports.rpcServerCalls = {
|
|
|
33
33
|
appRestart: rpcStub('appRestart'),
|
|
34
34
|
// Database exploration (for CLI)
|
|
35
35
|
dbQuery: rpcStub('dbQuery'),
|
|
36
|
+
// Direct tool execution (for CLI)
|
|
37
|
+
runTool: rpcStub('runTool'),
|
|
36
38
|
// UI control (for CLI)
|
|
37
39
|
uiReload: rpcStub('uiReload'),
|
|
38
40
|
uiInspect: rpcStub('uiInspect'),
|
package/dist/system-ids.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare const peersRootUserId = "000peers0user000000000001";
|
|
2
2
|
export declare const defaultAssistantId = "000peers0bot00000000shell";
|
|
3
|
+
export declare const openCodeAssistantId = "00mlwl2km2opencode0000001";
|
|
3
4
|
export declare const defaultAssistantRunnerToolId = "000peers0tool00000runner1";
|
|
4
5
|
export declare const defaultSendMessageToolId = "000peers0tool00000sendmsg";
|
|
5
6
|
export declare const runWorkflowToolId = "000peers0tool0runworkflow";
|
package/dist/system-ids.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.peersCorePackageRepoUrl = exports.peersCorePackageId = exports.emitEventToolId = exports.runWorkflowToolId = exports.defaultSendMessageToolId = exports.defaultAssistantRunnerToolId = exports.defaultAssistantId = exports.peersRootUserId = void 0;
|
|
3
|
+
exports.peersCorePackageRepoUrl = exports.peersCorePackageId = exports.emitEventToolId = exports.runWorkflowToolId = exports.defaultSendMessageToolId = exports.defaultAssistantRunnerToolId = exports.openCodeAssistantId = exports.defaultAssistantId = exports.peersRootUserId = void 0;
|
|
4
4
|
exports.peersRootUserId = '000peers0user000000000001';
|
|
5
5
|
exports.defaultAssistantId = '000peers0bot00000000shell';
|
|
6
6
|
// export const defaultAssistantId = '000peers0bot000000000bot1';
|
|
7
|
+
exports.openCodeAssistantId = '00mlwl2km2opencode0000001';
|
|
7
8
|
exports.defaultAssistantRunnerToolId = '000peers0tool00000runner1';
|
|
8
9
|
exports.defaultSendMessageToolId = '000peers0tool00000sendmsg';
|
|
9
10
|
exports.runWorkflowToolId = '000peers0tool0runworkflow';
|