@rynx-ai/daemon 0.1.10 → 0.1.11-beta.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.
- package/bundled-plugins/.rynx-plugin/marketplace.json +10 -0
- package/bundled-plugins/plugins/lark/.rynx-plugin/plugin.json +37 -0
- package/bundled-plugins/plugins/lark/dist/cli-mirror/mirror-index.d.ts +48 -0
- package/bundled-plugins/plugins/lark/dist/cli-mirror/mirror-index.js +54 -0
- package/bundled-plugins/plugins/lark/dist/cli-mirror/rollout-mirror.d.ts +85 -0
- package/bundled-plugins/plugins/lark/dist/cli-mirror/rollout-mirror.js +333 -0
- package/bundled-plugins/plugins/lark/dist/cli-mirror/rollout-watcher.d.ts +109 -0
- package/bundled-plugins/plugins/lark/dist/cli-mirror/rollout-watcher.js +347 -0
- package/bundled-plugins/plugins/lark/dist/host-adapters.d.ts +95 -0
- package/bundled-plugins/plugins/lark/dist/host-adapters.js +504 -0
- package/bundled-plugins/plugins/lark/dist/index.d.ts +7 -0
- package/bundled-plugins/plugins/lark/dist/index.js +7 -0
- package/bundled-plugins/plugins/lark/dist/lark-card-stream.d.ts +363 -0
- package/bundled-plugins/plugins/lark/dist/lark-card-stream.js +1335 -0
- package/bundled-plugins/plugins/lark/dist/lark-config-store.d.ts +30 -0
- package/bundled-plugins/plugins/lark/dist/lark-config-store.js +135 -0
- package/bundled-plugins/plugins/lark/dist/lark-content.d.ts +30 -0
- package/bundled-plugins/plugins/lark/dist/lark-content.js +138 -0
- package/bundled-plugins/plugins/lark/dist/lark-conversation-directory.d.ts +65 -0
- package/bundled-plugins/plugins/lark/dist/lark-conversation-directory.js +106 -0
- package/bundled-plugins/plugins/lark/dist/lark-diff-card.d.ts +25 -0
- package/bundled-plugins/plugins/lark/dist/lark-diff-card.js +58 -0
- package/bundled-plugins/plugins/lark/dist/lark-fork-transcript.d.ts +16 -0
- package/bundled-plugins/plugins/lark/dist/lark-fork-transcript.js +141 -0
- package/bundled-plugins/plugins/lark/dist/lark-resume-card.d.ts +31 -0
- package/bundled-plugins/plugins/lark/dist/lark-resume-card.js +105 -0
- package/bundled-plugins/plugins/lark/dist/lark-runtime-state-store.d.ts +18 -0
- package/bundled-plugins/plugins/lark/dist/lark-runtime-state-store.js +95 -0
- package/bundled-plugins/plugins/lark/dist/lark-sdk/client.d.ts +8 -0
- package/bundled-plugins/plugins/lark/dist/lark-sdk/client.js +32 -0
- package/bundled-plugins/plugins/lark/dist/lark-sdk/index.d.ts +1 -0
- package/bundled-plugins/plugins/lark/dist/lark-sdk/index.js +1 -0
- package/bundled-plugins/plugins/lark/dist/lark-sender.d.ts +114 -0
- package/bundled-plugins/plugins/lark/dist/lark-sender.js +323 -0
- package/bundled-plugins/plugins/lark/dist/lark-session-store.d.ts +13 -0
- package/bundled-plugins/plugins/lark/dist/lark-session-store.js +14 -0
- package/bundled-plugins/plugins/lark/dist/lark-settings-card.d.ts +55 -0
- package/bundled-plugins/plugins/lark/dist/lark-settings-card.js +158 -0
- package/bundled-plugins/plugins/lark/dist/lark-setup.d.ts +39 -0
- package/bundled-plugins/plugins/lark/dist/lark-setup.js +103 -0
- package/bundled-plugins/plugins/lark/dist/lark.d.ts +507 -0
- package/bundled-plugins/plugins/lark/dist/lark.js +1977 -0
- package/bundled-plugins/plugins/lark/dist/runtime.d.ts +13 -0
- package/bundled-plugins/plugins/lark/dist/runtime.js +131316 -0
- package/bundled-plugins/plugins/lark/dist/settings.d.ts +7 -0
- package/bundled-plugins/plugins/lark/dist/settings.js +126958 -0
- package/bundled-plugins/plugins/lark/package.json +57 -0
- package/bundled-plugins/plugins/lark/ui/assets/index-B2dhMlMU.css +1 -0
- package/bundled-plugins/plugins/lark/ui/assets/index-D9N-AkLX.js +201 -0
- package/bundled-plugins/plugins/lark/ui/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/index.html +13 -0
- package/dist/bundled-plugins.d.ts +15 -0
- package/dist/bundled-plugins.js +134 -0
- package/dist/cli.js +26 -208
- package/dist/control-deps.js +2 -79
- package/dist/daemon-server.d.ts +4 -1
- package/dist/daemon-server.js +167 -57
- package/dist/db.js +145 -124
- package/dist/index-daemon.js +25 -4
- package/dist/migrations/cleanup-legacy-sessions.d.ts +1 -1
- package/dist/migrations/cleanup-legacy-sessions.js +33 -15
- package/dist/official-plugins.d.ts +2 -0
- package/dist/official-plugins.js +2 -0
- package/dist/plugin-cli.d.ts +1 -3
- package/dist/plugin-cli.js +56 -45
- package/dist/plugin-host-leases.d.ts +4 -0
- package/dist/plugin-host-leases.js +7 -0
- package/dist/plugin-host-rpc.d.ts +42 -4
- package/dist/plugin-host-rpc.js +144 -34
- package/dist/plugin-installer.d.ts +24 -55
- package/dist/plugin-installer.js +202 -415
- package/dist/plugin-management-service.d.ts +30 -23
- package/dist/plugin-management-service.js +290 -105
- package/dist/plugin-marketplace.d.ts +35 -0
- package/dist/plugin-marketplace.js +299 -0
- package/dist/plugin-package.d.ts +22 -24
- package/dist/plugin-package.js +520 -571
- package/dist/plugin-skill-context.d.ts +4 -0
- package/dist/plugin-skill-context.js +35 -0
- package/dist/plugin-store.d.ts +36 -37
- package/dist/plugin-store.js +140 -92
- package/dist/plugin-supervisor.d.ts +45 -125
- package/dist/plugin-supervisor.js +516 -1053
- package/dist/pm2.js +15 -10
- package/dist/runtime-project-store.d.ts +9 -0
- package/dist/runtime-project-store.js +83 -0
- package/dist/session-fallback-workspace.d.ts +22 -0
- package/dist/session-fallback-workspace.js +120 -0
- package/dist/session-fork-store.d.ts +41 -0
- package/dist/session-fork-store.js +288 -0
- package/dist/session-launch-operations.d.ts +14 -2
- package/dist/session-launch-operations.js +34 -2
- package/dist/session-meta-store.d.ts +7 -9
- package/dist/session-meta-store.js +28 -49
- package/dist/setup.js +26 -14
- package/package.json +14 -11
- package/dist/channel-store.d.ts +0 -22
- package/dist/channel-store.js +0 -65
- package/dist/instance-store.d.ts +0 -38
- package/dist/instance-store.js +0 -85
- package/dist/plugin-install-restart.d.ts +0 -13
- package/dist/plugin-install-restart.js +0 -24
- package/dist/plugin-runtime-control.d.ts +0 -2
- package/dist/plugin-runtime-control.js +0 -37
- package/dist/registry.d.ts +0 -10
- package/dist/registry.js +0 -52
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { lstatSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, } from "node:fs";
|
|
2
|
+
import { isAbsolute, join, posix, relative, resolve, sep } from "node:path";
|
|
3
|
+
import { MARKETPLACE_ID_PATTERN, parsePluginMarketplace, } from "@rynx-ai/plugin-sdk";
|
|
4
|
+
import { rynxHome } from "@rynx-ai/core";
|
|
5
|
+
import { db } from "./db.js";
|
|
6
|
+
import { detectPluginSource, materializePluginPackage, parsePluginSourceSpec, pluginSourceFingerprint, } from "./plugin-package.js";
|
|
7
|
+
export function listPluginMarketplaces() {
|
|
8
|
+
return db().prepare("SELECT * FROM plugin_marketplaces ORDER BY marketplace_id").all().map(toRecord);
|
|
9
|
+
}
|
|
10
|
+
export function getPluginMarketplace(id) {
|
|
11
|
+
const row = db().prepare("SELECT * FROM plugin_marketplaces WHERE marketplace_id = ?").get(id);
|
|
12
|
+
return row ? toRecord(row) : undefined;
|
|
13
|
+
}
|
|
14
|
+
export async function addPluginMarketplace(spec, options = {}) {
|
|
15
|
+
const staged = await stageMarketplace(spec, options);
|
|
16
|
+
try {
|
|
17
|
+
const repositoryId = githubRepositoryMarketplaceId(staged.requestedSource);
|
|
18
|
+
if (repositoryId && options.alias && options.alias !== repositoryId) {
|
|
19
|
+
throw new Error(`GitHub marketplace id is fixed to "${repositoryId}" and cannot be aliased`);
|
|
20
|
+
}
|
|
21
|
+
const marketplaceId = repositoryId ?? options.alias ?? staged.catalog.id;
|
|
22
|
+
if (!MARKETPLACE_ID_PATTERN.test(marketplaceId)) {
|
|
23
|
+
throw new Error(`invalid marketplace id "${marketplaceId}"`);
|
|
24
|
+
}
|
|
25
|
+
const existing = getPluginMarketplace(marketplaceId);
|
|
26
|
+
if (existing?.builtIn && !options.builtIn) {
|
|
27
|
+
throw new Error(`built-in marketplace "${marketplaceId}" is managed by Rynx`);
|
|
28
|
+
}
|
|
29
|
+
const now = new Date().toISOString();
|
|
30
|
+
db().transaction(() => {
|
|
31
|
+
const binding = db().prepare(`SELECT source_fingerprint AS sourceFingerprint
|
|
32
|
+
FROM plugin_marketplace_bindings
|
|
33
|
+
WHERE marketplace_id = ?`).get(marketplaceId);
|
|
34
|
+
if (binding &&
|
|
35
|
+
binding.sourceFingerprint !== staged.sourceFingerprint &&
|
|
36
|
+
!options.allowSourceRebind) {
|
|
37
|
+
throw new Error(`marketplace id "${marketplaceId}" is already bound to another source; use a different alias`);
|
|
38
|
+
}
|
|
39
|
+
db().prepare(`INSERT INTO plugin_marketplace_bindings (
|
|
40
|
+
marketplace_id, source_fingerprint, created_at
|
|
41
|
+
) VALUES (?, ?, ?)
|
|
42
|
+
ON CONFLICT(marketplace_id) DO UPDATE SET
|
|
43
|
+
source_fingerprint = excluded.source_fingerprint`).run(marketplaceId, staged.sourceFingerprint, now);
|
|
44
|
+
db().prepare(`INSERT INTO plugin_marketplaces (
|
|
45
|
+
marketplace_id, source_type, requested_source, resolved_revision,
|
|
46
|
+
source_fingerprint, built_in, catalog, created_at, refreshed_at
|
|
47
|
+
) VALUES (
|
|
48
|
+
@marketplaceId, @sourceType, @requestedSource, @resolvedRevision,
|
|
49
|
+
@sourceFingerprint, @builtIn, @catalog, @now, @now
|
|
50
|
+
)
|
|
51
|
+
ON CONFLICT(marketplace_id) DO UPDATE SET
|
|
52
|
+
source_type = excluded.source_type,
|
|
53
|
+
requested_source = excluded.requested_source,
|
|
54
|
+
resolved_revision = excluded.resolved_revision,
|
|
55
|
+
source_fingerprint = excluded.source_fingerprint,
|
|
56
|
+
built_in = excluded.built_in,
|
|
57
|
+
catalog = excluded.catalog,
|
|
58
|
+
refreshed_at = excluded.refreshed_at`).run({
|
|
59
|
+
marketplaceId,
|
|
60
|
+
sourceType: staged.requestedSource.type,
|
|
61
|
+
requestedSource: JSON.stringify(staged.requestedSource),
|
|
62
|
+
resolvedRevision: staged.resolvedRevision,
|
|
63
|
+
sourceFingerprint: staged.sourceFingerprint,
|
|
64
|
+
builtIn: options.builtIn ? 1 : 0,
|
|
65
|
+
catalog: JSON.stringify(staged.catalog),
|
|
66
|
+
now,
|
|
67
|
+
});
|
|
68
|
+
}).immediate();
|
|
69
|
+
return getPluginMarketplace(marketplaceId);
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
staged.discard();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export async function refreshPluginMarketplace(marketplaceId, options = {}) {
|
|
76
|
+
const existing = getPluginMarketplace(marketplaceId);
|
|
77
|
+
if (!existing)
|
|
78
|
+
throw new Error(`marketplace "${marketplaceId}" not found`);
|
|
79
|
+
if (existing.builtIn) {
|
|
80
|
+
throw new Error(`built-in marketplace "${marketplaceId}" updates with Rynx and cannot be refreshed`);
|
|
81
|
+
}
|
|
82
|
+
return await addPluginMarketplace(serializeSource(existing.requestedSource), {
|
|
83
|
+
...options,
|
|
84
|
+
alias: marketplaceId,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
export function removePluginMarketplace(marketplaceId) {
|
|
88
|
+
if (!MARKETPLACE_ID_PATTERN.test(marketplaceId))
|
|
89
|
+
return false;
|
|
90
|
+
const existing = getPluginMarketplace(marketplaceId);
|
|
91
|
+
if (existing?.builtIn) {
|
|
92
|
+
throw new Error(`built-in marketplace "${marketplaceId}" is part of Rynx and cannot be removed`);
|
|
93
|
+
}
|
|
94
|
+
const installed = db().prepare("SELECT COUNT(*) AS count FROM plugin_installations WHERE marketplace_id = ?").get(marketplaceId);
|
|
95
|
+
if (installed.count > 0) {
|
|
96
|
+
throw new Error(`marketplace "${marketplaceId}" still owns installed plugins; uninstall them first`);
|
|
97
|
+
}
|
|
98
|
+
return db().prepare("DELETE FROM plugin_marketplaces WHERE marketplace_id = ?").run(marketplaceId).changes > 0;
|
|
99
|
+
}
|
|
100
|
+
export function isBuiltInPluginMarketplace(marketplaceId) {
|
|
101
|
+
return getPluginMarketplace(marketplaceId)?.builtIn === true;
|
|
102
|
+
}
|
|
103
|
+
export function resolveMarketplacePlugin(identity) {
|
|
104
|
+
const separator = identity.lastIndexOf("@");
|
|
105
|
+
if (separator <= 0 || separator === identity.length - 1) {
|
|
106
|
+
throw new Error("marketplace plugin identity must be <plugin-id>@<marketplace-id>");
|
|
107
|
+
}
|
|
108
|
+
const pluginId = identity.slice(0, separator);
|
|
109
|
+
const marketplaceId = identity.slice(separator + 1);
|
|
110
|
+
const marketplace = getPluginMarketplace(marketplaceId);
|
|
111
|
+
if (!marketplace)
|
|
112
|
+
throw new Error(`marketplace "${marketplaceId}" not found`);
|
|
113
|
+
const entry = marketplace.catalog.plugins.find((plugin) => plugin.id === pluginId);
|
|
114
|
+
if (!entry)
|
|
115
|
+
throw new Error(`plugin "${pluginId}" not found in marketplace "${marketplaceId}"`);
|
|
116
|
+
return {
|
|
117
|
+
marketplace,
|
|
118
|
+
pluginId,
|
|
119
|
+
spec: serializeSource(resolveCatalogSource(marketplace, entry.source)),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
async function stageMarketplace(spec, options) {
|
|
123
|
+
options.signal?.throwIfAborted();
|
|
124
|
+
const sourceType = detectPluginSource(spec);
|
|
125
|
+
const normalized = parsePluginSourceSpec(spec, sourceType);
|
|
126
|
+
if (normalized.type === "local" && !options.materializer) {
|
|
127
|
+
return {
|
|
128
|
+
catalog: readMarketplaceCatalog(selectLocalMarketplaceRoot(normalized)),
|
|
129
|
+
requestedSource: structuredClone(normalized.requested),
|
|
130
|
+
resolvedRevision: "local",
|
|
131
|
+
sourceFingerprint: pluginSourceFingerprint(normalized),
|
|
132
|
+
discard: () => { },
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const stagingRoot = join(rynxHome(), "plugins", "staging");
|
|
136
|
+
mkdirSync(stagingRoot, { recursive: true, mode: 0o700 });
|
|
137
|
+
const transaction = mkdtempSync(join(stagingRoot, "market-"));
|
|
138
|
+
const source = join(transaction, "source");
|
|
139
|
+
try {
|
|
140
|
+
const materializeSpec = !options.materializer && normalized.type === "git"
|
|
141
|
+
? serializeSource({
|
|
142
|
+
...normalized.requested,
|
|
143
|
+
subdir: combineSubdirectories(normalized.subdir, ".rynx-plugin"),
|
|
144
|
+
})
|
|
145
|
+
: spec;
|
|
146
|
+
const destination = !options.materializer && normalized.type === "git"
|
|
147
|
+
? join(source, ".rynx-plugin")
|
|
148
|
+
: source;
|
|
149
|
+
const materialized = await (options.materializer ?? materializePluginPackage)({
|
|
150
|
+
spec: materializeSpec,
|
|
151
|
+
source: sourceType,
|
|
152
|
+
destination,
|
|
153
|
+
onProgress: options.onProgress ?? (() => { }),
|
|
154
|
+
signal: options.signal,
|
|
155
|
+
});
|
|
156
|
+
return {
|
|
157
|
+
catalog: readMarketplaceCatalog(source),
|
|
158
|
+
requestedSource: structuredClone(normalized.requested),
|
|
159
|
+
resolvedRevision: materialized.resolvedRevision,
|
|
160
|
+
sourceFingerprint: pluginSourceFingerprint(normalized),
|
|
161
|
+
discard: () => rmSync(transaction, { recursive: true, force: true }),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
rmSync(transaction, { recursive: true, force: true });
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function selectLocalMarketplaceRoot(source) {
|
|
170
|
+
const candidate = source.subdir === "."
|
|
171
|
+
? source.normalizedLocation
|
|
172
|
+
: resolve(source.normalizedLocation, ...source.subdir.split("/"));
|
|
173
|
+
const info = lstatSync(candidate);
|
|
174
|
+
if (!info.isDirectory() || info.isSymbolicLink()) {
|
|
175
|
+
throw new Error("marketplace source must be a regular directory");
|
|
176
|
+
}
|
|
177
|
+
const selected = realpathSync(candidate);
|
|
178
|
+
const rel = relative(source.normalizedLocation, selected);
|
|
179
|
+
if (rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {
|
|
180
|
+
throw new Error("marketplace source subdirectory resolves outside its source");
|
|
181
|
+
}
|
|
182
|
+
return selected;
|
|
183
|
+
}
|
|
184
|
+
function readMarketplaceCatalog(root) {
|
|
185
|
+
const metadataDir = join(root, ".rynx-plugin");
|
|
186
|
+
const metadataInfo = lstatSync(metadataDir);
|
|
187
|
+
if (!metadataInfo.isDirectory() || metadataInfo.isSymbolicLink()) {
|
|
188
|
+
throw new Error(".rynx-plugin must be a regular directory");
|
|
189
|
+
}
|
|
190
|
+
const catalogPath = join(metadataDir, "marketplace.json");
|
|
191
|
+
const info = lstatSync(catalogPath);
|
|
192
|
+
if (!info.isFile() || info.isSymbolicLink() || info.size > 1024 * 1024) {
|
|
193
|
+
throw new Error(".rynx-plugin/marketplace.json must be a regular file under 1 MiB");
|
|
194
|
+
}
|
|
195
|
+
return parsePluginMarketplace(JSON.parse(readFileSync(catalogPath, "utf8")));
|
|
196
|
+
}
|
|
197
|
+
function resolveCatalogSource(marketplace, source) {
|
|
198
|
+
const relativePath = normalizeRelativeCatalogPath(source);
|
|
199
|
+
const parent = marketplace.requestedSource;
|
|
200
|
+
if (parent.type === "git") {
|
|
201
|
+
const subdir = combineSubdirectories(parent.subdir, relativePath);
|
|
202
|
+
return {
|
|
203
|
+
type: "git",
|
|
204
|
+
url: parent.url,
|
|
205
|
+
...(subdir ? { subdir } : {}),
|
|
206
|
+
commit: marketplace.resolvedRevision,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
const catalogRoot = parent.subdir
|
|
210
|
+
? resolve(parent.path, ...parent.subdir.split("/"))
|
|
211
|
+
: parent.path;
|
|
212
|
+
return {
|
|
213
|
+
type: "local",
|
|
214
|
+
path: resolve(catalogRoot, ...relativePath.split("/")),
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function normalizeRelativeCatalogPath(value) {
|
|
218
|
+
if (value === "." || value === "./")
|
|
219
|
+
return ".";
|
|
220
|
+
const normalized = value.startsWith("./") ? value.slice(2) : value;
|
|
221
|
+
if (!normalized ||
|
|
222
|
+
normalized.includes("\\") ||
|
|
223
|
+
normalized.split("/").some((part) => !part || part === "." || part === "..")) {
|
|
224
|
+
throw new Error("relative marketplace plugin path must be a normalized POSIX path");
|
|
225
|
+
}
|
|
226
|
+
return normalized;
|
|
227
|
+
}
|
|
228
|
+
function combineSubdirectories(...parts) {
|
|
229
|
+
const combined = parts.filter((part) => part && part !== ".").join("/");
|
|
230
|
+
if (!combined)
|
|
231
|
+
return undefined;
|
|
232
|
+
const normalized = posix.normalize(combined);
|
|
233
|
+
if (!normalized ||
|
|
234
|
+
normalized.startsWith("../") ||
|
|
235
|
+
normalized.includes("/../") ||
|
|
236
|
+
normalized.startsWith("/")) {
|
|
237
|
+
throw new Error("marketplace plugin path escapes the marketplace source");
|
|
238
|
+
}
|
|
239
|
+
return normalized;
|
|
240
|
+
}
|
|
241
|
+
function serializeSource(source) {
|
|
242
|
+
const params = new URLSearchParams();
|
|
243
|
+
if (source.subdir)
|
|
244
|
+
params.set("path", source.subdir);
|
|
245
|
+
if (source.type === "git") {
|
|
246
|
+
if (source.ref)
|
|
247
|
+
params.set("ref", source.ref);
|
|
248
|
+
if (source.commit)
|
|
249
|
+
params.set("ref", source.commit);
|
|
250
|
+
const fragment = params.toString();
|
|
251
|
+
return `${source.url}${fragment ? `#${fragment}` : ""}`;
|
|
252
|
+
}
|
|
253
|
+
const fragment = params.toString();
|
|
254
|
+
return `${realpathSync(source.path)}${fragment ? `#${fragment}` : ""}`;
|
|
255
|
+
}
|
|
256
|
+
function toRecord(row) {
|
|
257
|
+
return {
|
|
258
|
+
marketplaceId: row.marketplace_id,
|
|
259
|
+
sourceType: row.source_type === "local" ? "local" : "git",
|
|
260
|
+
builtIn: row.built_in !== 0,
|
|
261
|
+
requestedSource: JSON.parse(row.requested_source),
|
|
262
|
+
resolvedRevision: row.resolved_revision,
|
|
263
|
+
sourceFingerprint: row.source_fingerprint,
|
|
264
|
+
catalog: parseStoredMarketplace(JSON.parse(row.catalog)),
|
|
265
|
+
createdAt: row.created_at,
|
|
266
|
+
refreshedAt: row.refreshed_at,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
function githubRepositoryMarketplaceId(source) {
|
|
270
|
+
if (source.type !== "git")
|
|
271
|
+
return undefined;
|
|
272
|
+
let repositoryPath;
|
|
273
|
+
const scp = /^git@github\.com:([^?#]+)$/i.exec(source.url);
|
|
274
|
+
if (scp) {
|
|
275
|
+
repositoryPath = scp[1];
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
try {
|
|
279
|
+
const parsed = new URL(source.url);
|
|
280
|
+
if (parsed.hostname.toLowerCase() !== "github.com")
|
|
281
|
+
return undefined;
|
|
282
|
+
repositoryPath = parsed.pathname.replace(/^\/+|\/+$/g, "");
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
const segments = repositoryPath.replace(/\.git$/i, "").split("/");
|
|
289
|
+
if (segments.length !== 2 || segments.some((segment) => !segment))
|
|
290
|
+
return undefined;
|
|
291
|
+
const id = segments.join("/").toLowerCase();
|
|
292
|
+
return MARKETPLACE_ID_PATTERN.test(id) ? id : undefined;
|
|
293
|
+
}
|
|
294
|
+
function parseStoredMarketplace(value) {
|
|
295
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
296
|
+
delete value.displayName;
|
|
297
|
+
}
|
|
298
|
+
return parsePluginMarketplace(value);
|
|
299
|
+
}
|
package/dist/plugin-package.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type PluginManifestV1 } from "@rynx-ai/plugin-sdk";
|
|
1
|
+
import { type PluginManifestV1, type PluginPackageSourceV1 } from "@rynx-ai/plugin-sdk";
|
|
2
2
|
import type { PluginSource } from "./plugin-store.js";
|
|
3
3
|
export interface PluginPackageInspectionLimits {
|
|
4
4
|
maxFileBytes: number;
|
|
@@ -8,11 +8,15 @@ export interface PluginPackageInspectionLimits {
|
|
|
8
8
|
}
|
|
9
9
|
export declare const DEFAULT_PLUGIN_PACKAGE_INSPECTION_LIMITS: Readonly<PluginPackageInspectionLimits>;
|
|
10
10
|
export interface InspectPluginPackageOptions {
|
|
11
|
-
requireEntries?: boolean;
|
|
12
11
|
signal?: AbortSignal;
|
|
13
|
-
/** Test/internal override; daemon installation always uses the safe defaults. */
|
|
14
12
|
limits?: Partial<PluginPackageInspectionLimits>;
|
|
15
13
|
}
|
|
14
|
+
export interface NormalizedPluginSource {
|
|
15
|
+
type: PluginSource;
|
|
16
|
+
requested: PluginPackageSourceV1;
|
|
17
|
+
normalizedLocation: string;
|
|
18
|
+
subdir: string;
|
|
19
|
+
}
|
|
16
20
|
export interface MaterializePluginPackageRequest {
|
|
17
21
|
spec: string;
|
|
18
22
|
source: PluginSource;
|
|
@@ -20,42 +24,36 @@ export interface MaterializePluginPackageRequest {
|
|
|
20
24
|
onProgress: (line: string) => void;
|
|
21
25
|
signal?: AbortSignal;
|
|
22
26
|
}
|
|
23
|
-
export
|
|
27
|
+
export interface MaterializedPluginPackage {
|
|
28
|
+
requestedSource: PluginPackageSourceV1;
|
|
29
|
+
resolvedRevision: string;
|
|
30
|
+
sourceFingerprint: string;
|
|
31
|
+
}
|
|
32
|
+
export type PluginPackageMaterializer = (request: MaterializePluginPackageRequest) => Promise<MaterializedPluginPackage>;
|
|
24
33
|
export interface InspectedPluginPackage {
|
|
25
34
|
manifest: PluginManifestV1;
|
|
26
|
-
version
|
|
35
|
+
version: string;
|
|
27
36
|
integrity: string;
|
|
28
37
|
}
|
|
29
|
-
/** Classify provenance without fetching or executing anything. */
|
|
30
38
|
export declare function detectPluginSource(spec: string): PluginSource;
|
|
31
|
-
/** Stable provenance for local sources; remote specs are retained verbatim. */
|
|
32
39
|
export declare function normalizePluginSpec(spec: string, source: PluginSource): string;
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
* Local workspace packages are archived with their internal dependency closure
|
|
37
|
-
* and then installed into a disposable npm prefix. Other local, npm, git, and
|
|
38
|
-
* URL specs use the same prefix flow. Every path therefore reaches inspection
|
|
39
|
-
* with runtime dependencies present, while lifecycle scripts remain disabled.
|
|
40
|
-
*/
|
|
40
|
+
/** CLI source syntax: local paths, Git URLs, github:owner/repo, or owner/repo. */
|
|
41
|
+
export declare function parsePluginSourceSpec(spec: string, forced?: PluginSource): NormalizedPluginSource;
|
|
42
|
+
export declare function pluginSourceFingerprint(source: NormalizedPluginSource): string;
|
|
41
43
|
export declare const materializePluginPackage: PluginPackageMaterializer;
|
|
42
44
|
export declare function parseGitSpec(spec: string): {
|
|
43
45
|
url: string;
|
|
44
46
|
ref?: string;
|
|
47
|
+
subdir: string;
|
|
45
48
|
};
|
|
46
|
-
|
|
49
|
+
export declare function normalizeGitUrl(value: string): string;
|
|
47
50
|
export declare function inspectPluginPackage(packageDir: string, options?: InspectPluginPackageOptions): Promise<InspectedPluginPackage>;
|
|
48
|
-
/**
|
|
49
|
-
export declare function
|
|
51
|
+
/** Validate and hash a closed package/catalog snapshot without executing it. */
|
|
52
|
+
export declare function validatePluginPackageSnapshot(packageDir: string, options?: InspectPluginPackageOptions): Promise<string>;
|
|
53
|
+
export declare function resolvePackagePath(packageRoot: string, entry: string, label: string, kind: "file" | "directory"): string;
|
|
50
54
|
export interface RunPluginPackageCommandOptions {
|
|
51
55
|
signal?: AbortSignal;
|
|
52
56
|
cwd?: string;
|
|
53
|
-
/** Internal/test override; production uses a bounded two-second grace. */
|
|
54
57
|
abortGraceMs?: number;
|
|
55
58
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Run one package tool without a shell and tear down its full POSIX process
|
|
58
|
-
* group on cancellation. Windows cannot signal process groups through Node,
|
|
59
|
-
* so it safely degrades to TERM→KILL on the direct child.
|
|
60
|
-
*/
|
|
61
59
|
export declare function runPluginPackageCommand(command: string, args: string[], onProgress: (line: string) => void, options?: RunPluginPackageCommandOptions): Promise<void>;
|