ocx 1.0.6 → 1.0.8
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/index.js +445 -151
- package/dist/index.js.map +15 -11
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -4533,32 +4533,32 @@ var require_fuzzysort = __commonJS((exports, module) => {
|
|
|
4533
4533
|
noResults.total = 0;
|
|
4534
4534
|
var NULL = null;
|
|
4535
4535
|
var noTarget = prepare("");
|
|
4536
|
-
var fastpriorityqueue = (
|
|
4537
|
-
var
|
|
4538
|
-
for (var a4 = 0, v3 =
|
|
4536
|
+
var fastpriorityqueue = (r3) => {
|
|
4537
|
+
var e4 = [], o2 = 0, a3 = {}, v2 = (r4) => {
|
|
4538
|
+
for (var a4 = 0, v3 = e4[a4], c2 = 1;c2 < o2; ) {
|
|
4539
4539
|
var s2 = c2 + 1;
|
|
4540
|
-
a4 = c2, s2 < o2 &&
|
|
4540
|
+
a4 = c2, s2 < o2 && e4[s2]._score < e4[c2]._score && (a4 = s2), e4[a4 - 1 >> 1] = e4[a4], c2 = 1 + (a4 << 1);
|
|
4541
4541
|
}
|
|
4542
|
-
for (var f2 = a4 - 1 >> 1;a4 > 0 && v3._score <
|
|
4543
|
-
|
|
4544
|
-
|
|
4542
|
+
for (var f2 = a4 - 1 >> 1;a4 > 0 && v3._score < e4[f2]._score; f2 = (a4 = f2) - 1 >> 1)
|
|
4543
|
+
e4[a4] = e4[f2];
|
|
4544
|
+
e4[a4] = v3;
|
|
4545
4545
|
};
|
|
4546
|
-
return a3.add = (
|
|
4546
|
+
return a3.add = (r4) => {
|
|
4547
4547
|
var a4 = o2;
|
|
4548
|
-
|
|
4549
|
-
for (var v3 = a4 - 1 >> 1;a4 > 0 &&
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
}, a3.poll = (
|
|
4548
|
+
e4[o2++] = r4;
|
|
4549
|
+
for (var v3 = a4 - 1 >> 1;a4 > 0 && r4._score < e4[v3]._score; v3 = (a4 = v3) - 1 >> 1)
|
|
4550
|
+
e4[a4] = e4[v3];
|
|
4551
|
+
e4[a4] = r4;
|
|
4552
|
+
}, a3.poll = (r4) => {
|
|
4553
4553
|
if (o2 !== 0) {
|
|
4554
|
-
var a4 =
|
|
4555
|
-
return
|
|
4554
|
+
var a4 = e4[0];
|
|
4555
|
+
return e4[0] = e4[--o2], v2(), a4;
|
|
4556
4556
|
}
|
|
4557
|
-
}, a3.peek = (
|
|
4557
|
+
}, a3.peek = (r4) => {
|
|
4558
4558
|
if (o2 !== 0)
|
|
4559
|
-
return
|
|
4560
|
-
}, a3.replaceTop = (
|
|
4561
|
-
|
|
4559
|
+
return e4[0];
|
|
4560
|
+
}, a3.replaceTop = (r4) => {
|
|
4561
|
+
e4[0] = r4, v2();
|
|
4562
4562
|
}, a3;
|
|
4563
4563
|
};
|
|
4564
4564
|
var q2 = fastpriorityqueue();
|
|
@@ -13026,9 +13026,102 @@ var coerce = {
|
|
|
13026
13026
|
date: (arg) => ZodDate.create({ ...arg, coerce: true })
|
|
13027
13027
|
};
|
|
13028
13028
|
var NEVER = INVALID;
|
|
13029
|
+
// src/utils/errors.ts
|
|
13030
|
+
var EXIT_CODES = {
|
|
13031
|
+
SUCCESS: 0,
|
|
13032
|
+
GENERAL: 1,
|
|
13033
|
+
NOT_FOUND: 66,
|
|
13034
|
+
NETWORK: 69,
|
|
13035
|
+
CONFIG: 78,
|
|
13036
|
+
INTEGRITY: 1
|
|
13037
|
+
};
|
|
13038
|
+
|
|
13039
|
+
class OCXError extends Error {
|
|
13040
|
+
code;
|
|
13041
|
+
exitCode;
|
|
13042
|
+
constructor(message, code, exitCode = EXIT_CODES.GENERAL) {
|
|
13043
|
+
super(message);
|
|
13044
|
+
this.code = code;
|
|
13045
|
+
this.exitCode = exitCode;
|
|
13046
|
+
this.name = "OCXError";
|
|
13047
|
+
}
|
|
13048
|
+
}
|
|
13049
|
+
|
|
13050
|
+
class NotFoundError extends OCXError {
|
|
13051
|
+
constructor(message) {
|
|
13052
|
+
super(message, "NOT_FOUND", EXIT_CODES.NOT_FOUND);
|
|
13053
|
+
this.name = "NotFoundError";
|
|
13054
|
+
}
|
|
13055
|
+
}
|
|
13056
|
+
|
|
13057
|
+
class NetworkError extends OCXError {
|
|
13058
|
+
constructor(message) {
|
|
13059
|
+
super(message, "NETWORK_ERROR", EXIT_CODES.NETWORK);
|
|
13060
|
+
this.name = "NetworkError";
|
|
13061
|
+
}
|
|
13062
|
+
}
|
|
13063
|
+
|
|
13064
|
+
class ConfigError extends OCXError {
|
|
13065
|
+
constructor(message) {
|
|
13066
|
+
super(message, "CONFIG_ERROR", EXIT_CODES.CONFIG);
|
|
13067
|
+
this.name = "ConfigError";
|
|
13068
|
+
}
|
|
13069
|
+
}
|
|
13070
|
+
|
|
13071
|
+
class ValidationError extends OCXError {
|
|
13072
|
+
constructor(message) {
|
|
13073
|
+
super(message, "VALIDATION_ERROR", EXIT_CODES.GENERAL);
|
|
13074
|
+
this.name = "ValidationError";
|
|
13075
|
+
}
|
|
13076
|
+
}
|
|
13077
|
+
|
|
13078
|
+
class ConflictError extends OCXError {
|
|
13079
|
+
constructor(message) {
|
|
13080
|
+
super(message, "CONFLICT", EXIT_CODES.GENERAL);
|
|
13081
|
+
this.name = "ConflictError";
|
|
13082
|
+
}
|
|
13083
|
+
}
|
|
13084
|
+
|
|
13085
|
+
class IntegrityError extends OCXError {
|
|
13086
|
+
constructor(component, expected, found) {
|
|
13087
|
+
const message = `Integrity verification failed for "${component}"
|
|
13088
|
+
` + ` Expected: ${expected}
|
|
13089
|
+
` + ` Found: ${found}
|
|
13090
|
+
|
|
13091
|
+
` + `The registry content has changed since this component was locked.
|
|
13092
|
+
` + `This could indicate tampering or an unauthorized update.`;
|
|
13093
|
+
super(message, "INTEGRITY_ERROR", EXIT_CODES.INTEGRITY);
|
|
13094
|
+
this.name = "IntegrityError";
|
|
13095
|
+
}
|
|
13096
|
+
}
|
|
13097
|
+
|
|
13029
13098
|
// src/schemas/registry.ts
|
|
13030
13099
|
var openCodeNameSchema = exports_external.string().min(1, "Name cannot be empty").max(64, "Name cannot exceed 64 characters").regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, {
|
|
13031
|
-
message: "Must be lowercase alphanumeric with single hyphen separators (e.g., 'my-component', '
|
|
13100
|
+
message: "Must be lowercase alphanumeric with single hyphen separators (e.g., 'my-component', 'my-plugin'). Cannot start/end with hyphen or have consecutive hyphens."
|
|
13101
|
+
});
|
|
13102
|
+
var namespaceSchema = openCodeNameSchema;
|
|
13103
|
+
var qualifiedComponentSchema = exports_external.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*\/[a-z0-9]+(-[a-z0-9]+)*$/, {
|
|
13104
|
+
message: 'Must be in format "namespace/component" (e.g., "kdco/librarian"). Both parts must be lowercase alphanumeric with hyphens.'
|
|
13105
|
+
});
|
|
13106
|
+
function parseQualifiedComponent(ref) {
|
|
13107
|
+
if (!ref.includes("/")) {
|
|
13108
|
+
throw new ValidationError(`Invalid component reference: "${ref}". Use format: namespace/component`);
|
|
13109
|
+
}
|
|
13110
|
+
const [namespace, component] = ref.split("/");
|
|
13111
|
+
if (!namespace || !component) {
|
|
13112
|
+
throw new ValidationError(`Invalid component reference: "${ref}". Both namespace and component are required.`);
|
|
13113
|
+
}
|
|
13114
|
+
return { namespace, component };
|
|
13115
|
+
}
|
|
13116
|
+
function createQualifiedComponent(namespace, component) {
|
|
13117
|
+
return `${namespace}/${component}`;
|
|
13118
|
+
}
|
|
13119
|
+
var dependencyRefSchema = exports_external.string().refine((dep) => {
|
|
13120
|
+
const barePattern = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
13121
|
+
const qualifiedPattern = /^[a-z0-9]+(-[a-z0-9]+)*\/[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
13122
|
+
return barePattern.test(dep) || qualifiedPattern.test(dep);
|
|
13123
|
+
}, {
|
|
13124
|
+
message: 'Dependency must be either a bare name (e.g., "utils") or qualified (e.g., "acme/utils")'
|
|
13032
13125
|
});
|
|
13033
13126
|
var componentTypeSchema = exports_external.enum([
|
|
13034
13127
|
"ocx:agent",
|
|
@@ -13052,11 +13145,14 @@ var targetPathSchema = exports_external.string().refine((path3) => path3.startsW
|
|
|
13052
13145
|
var skillTargetSchema = exports_external.string().regex(/^\.opencode\/skill\/[a-z0-9]+(-[a-z0-9]+)*\/SKILL\.md$/, {
|
|
13053
13146
|
message: 'Skill target must match pattern ".opencode/skill/<name>/SKILL.md" where name follows OpenCode naming rules'
|
|
13054
13147
|
});
|
|
13055
|
-
var
|
|
13148
|
+
var mcpServerObjectSchema = exports_external.object({
|
|
13056
13149
|
type: exports_external.enum(["remote", "local"]),
|
|
13057
13150
|
url: exports_external.string().url().optional(),
|
|
13058
13151
|
command: exports_external.array(exports_external.string()).optional(),
|
|
13152
|
+
args: exports_external.array(exports_external.string()).optional(),
|
|
13153
|
+
environment: exports_external.record(exports_external.string()).optional(),
|
|
13059
13154
|
headers: exports_external.record(exports_external.string()).optional(),
|
|
13155
|
+
oauth: exports_external.boolean().optional(),
|
|
13060
13156
|
enabled: exports_external.boolean().default(true)
|
|
13061
13157
|
}).refine((data) => {
|
|
13062
13158
|
if (data.type === "remote" && !data.url) {
|
|
@@ -13069,47 +13165,93 @@ var mcpServerSchema = exports_external.object({
|
|
|
13069
13165
|
}, {
|
|
13070
13166
|
message: "Remote MCP servers require 'url', local servers require 'command'"
|
|
13071
13167
|
});
|
|
13072
|
-
var
|
|
13168
|
+
var mcpServerSchema = exports_external.union([exports_external.string().url(), mcpServerObjectSchema]);
|
|
13169
|
+
var componentFileObjectSchema = exports_external.object({
|
|
13073
13170
|
path: exports_external.string().min(1, "File path cannot be empty"),
|
|
13074
13171
|
target: targetPathSchema
|
|
13075
13172
|
});
|
|
13173
|
+
var componentFileSchema = exports_external.union([
|
|
13174
|
+
exports_external.string().min(1, "File path cannot be empty"),
|
|
13175
|
+
componentFileObjectSchema
|
|
13176
|
+
]);
|
|
13177
|
+
var agentConfigSchema = exports_external.object({
|
|
13178
|
+
tools: exports_external.record(exports_external.boolean()).optional(),
|
|
13179
|
+
temperature: exports_external.number().min(0).max(2).optional(),
|
|
13180
|
+
prompt: exports_external.string().optional(),
|
|
13181
|
+
permission: exports_external.record(exports_external.enum(["allow", "deny"])).optional()
|
|
13182
|
+
});
|
|
13183
|
+
var opencodeConfigSchema = exports_external.object({
|
|
13184
|
+
plugins: exports_external.array(exports_external.string()).optional(),
|
|
13185
|
+
tools: exports_external.record(exports_external.boolean()).optional(),
|
|
13186
|
+
agent: exports_external.record(agentConfigSchema).optional(),
|
|
13187
|
+
instructions: exports_external.array(exports_external.string()).optional()
|
|
13188
|
+
});
|
|
13076
13189
|
var componentManifestSchema = exports_external.object({
|
|
13077
13190
|
name: openCodeNameSchema,
|
|
13078
13191
|
type: componentTypeSchema,
|
|
13079
13192
|
description: exports_external.string().min(1).max(1024),
|
|
13080
13193
|
files: exports_external.array(componentFileSchema),
|
|
13081
|
-
dependencies: exports_external.array(
|
|
13194
|
+
dependencies: exports_external.array(dependencyRefSchema).default([]),
|
|
13082
13195
|
npmDependencies: exports_external.array(exports_external.string()).optional(),
|
|
13083
13196
|
npmDevDependencies: exports_external.array(exports_external.string()).optional(),
|
|
13084
13197
|
mcpServers: exports_external.record(mcpServerSchema).optional(),
|
|
13085
13198
|
mcpScope: exports_external.enum(["agent", "global"]).default("agent"),
|
|
13199
|
+
opencode: opencodeConfigSchema.optional(),
|
|
13086
13200
|
disabledTools: exports_external.array(exports_external.string()).optional()
|
|
13087
13201
|
});
|
|
13202
|
+
function inferTargetPath(sourcePath) {
|
|
13203
|
+
return `.opencode/${sourcePath}`;
|
|
13204
|
+
}
|
|
13205
|
+
function normalizeFile(file) {
|
|
13206
|
+
if (typeof file === "string") {
|
|
13207
|
+
return {
|
|
13208
|
+
path: file,
|
|
13209
|
+
target: inferTargetPath(file)
|
|
13210
|
+
};
|
|
13211
|
+
}
|
|
13212
|
+
return file;
|
|
13213
|
+
}
|
|
13214
|
+
function normalizeMcpServer(server) {
|
|
13215
|
+
if (typeof server === "string") {
|
|
13216
|
+
return {
|
|
13217
|
+
type: "remote",
|
|
13218
|
+
url: server,
|
|
13219
|
+
enabled: true
|
|
13220
|
+
};
|
|
13221
|
+
}
|
|
13222
|
+
return server;
|
|
13223
|
+
}
|
|
13224
|
+
function normalizeComponentManifest(manifest) {
|
|
13225
|
+
return {
|
|
13226
|
+
...manifest,
|
|
13227
|
+
files: manifest.files.map(normalizeFile),
|
|
13228
|
+
mcpServers: manifest.mcpServers ? Object.fromEntries(Object.entries(manifest.mcpServers).map(([name, server]) => [
|
|
13229
|
+
name,
|
|
13230
|
+
normalizeMcpServer(server)
|
|
13231
|
+
])) : undefined
|
|
13232
|
+
};
|
|
13233
|
+
}
|
|
13088
13234
|
var semverRegex = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/;
|
|
13089
13235
|
var registrySchema = exports_external.object({
|
|
13090
13236
|
name: exports_external.string().min(1, "Registry name cannot be empty"),
|
|
13091
|
-
|
|
13237
|
+
namespace: namespaceSchema,
|
|
13092
13238
|
version: exports_external.string().regex(semverRegex, {
|
|
13093
13239
|
message: "Version must be valid semver (e.g., '1.0.0', '2.1.0-beta.1')"
|
|
13094
13240
|
}),
|
|
13095
13241
|
author: exports_external.string().min(1, "Author cannot be empty"),
|
|
13096
13242
|
components: exports_external.array(componentManifestSchema)
|
|
13097
|
-
}).refine((data) => {
|
|
13098
|
-
return data.components.every((c2) => c2.name.startsWith(`${data.prefix}-`));
|
|
13099
|
-
}, {
|
|
13100
|
-
message: "All component names must start with the registry prefix"
|
|
13101
13243
|
}).refine((data) => {
|
|
13102
13244
|
const componentNames = new Set(data.components.map((c2) => c2.name));
|
|
13103
13245
|
for (const component of data.components) {
|
|
13104
13246
|
for (const dep of component.dependencies) {
|
|
13105
|
-
if (!componentNames.has(dep)) {
|
|
13247
|
+
if (!dep.includes("/") && !componentNames.has(dep)) {
|
|
13106
13248
|
return false;
|
|
13107
13249
|
}
|
|
13108
13250
|
}
|
|
13109
13251
|
}
|
|
13110
13252
|
return true;
|
|
13111
13253
|
}, {
|
|
13112
|
-
message: "
|
|
13254
|
+
message: "Bare dependencies must reference components that exist in the registry. Use qualified references (e.g., 'other-registry/component') for cross-namespace dependencies."
|
|
13113
13255
|
});
|
|
13114
13256
|
var packumentSchema = exports_external.object({
|
|
13115
13257
|
name: openCodeNameSchema,
|
|
@@ -13120,7 +13262,7 @@ var packumentSchema = exports_external.object({
|
|
|
13120
13262
|
});
|
|
13121
13263
|
var registryIndexSchema = exports_external.object({
|
|
13122
13264
|
name: exports_external.string(),
|
|
13123
|
-
|
|
13265
|
+
namespace: namespaceSchema,
|
|
13124
13266
|
version: exports_external.string(),
|
|
13125
13267
|
author: exports_external.string(),
|
|
13126
13268
|
components: exports_external.array(exports_external.object({
|
|
@@ -13130,67 +13272,6 @@ var registryIndexSchema = exports_external.object({
|
|
|
13130
13272
|
}))
|
|
13131
13273
|
});
|
|
13132
13274
|
|
|
13133
|
-
// src/utils/errors.ts
|
|
13134
|
-
var EXIT_CODES = {
|
|
13135
|
-
SUCCESS: 0,
|
|
13136
|
-
GENERAL: 1,
|
|
13137
|
-
NOT_FOUND: 66,
|
|
13138
|
-
NETWORK: 69,
|
|
13139
|
-
CONFIG: 78,
|
|
13140
|
-
INTEGRITY: 1
|
|
13141
|
-
};
|
|
13142
|
-
|
|
13143
|
-
class OCXError extends Error {
|
|
13144
|
-
code;
|
|
13145
|
-
exitCode;
|
|
13146
|
-
constructor(message, code, exitCode = EXIT_CODES.GENERAL) {
|
|
13147
|
-
super(message);
|
|
13148
|
-
this.code = code;
|
|
13149
|
-
this.exitCode = exitCode;
|
|
13150
|
-
this.name = "OCXError";
|
|
13151
|
-
}
|
|
13152
|
-
}
|
|
13153
|
-
|
|
13154
|
-
class NotFoundError extends OCXError {
|
|
13155
|
-
constructor(message) {
|
|
13156
|
-
super(message, "NOT_FOUND", EXIT_CODES.NOT_FOUND);
|
|
13157
|
-
this.name = "NotFoundError";
|
|
13158
|
-
}
|
|
13159
|
-
}
|
|
13160
|
-
|
|
13161
|
-
class NetworkError extends OCXError {
|
|
13162
|
-
constructor(message) {
|
|
13163
|
-
super(message, "NETWORK_ERROR", EXIT_CODES.NETWORK);
|
|
13164
|
-
this.name = "NetworkError";
|
|
13165
|
-
}
|
|
13166
|
-
}
|
|
13167
|
-
|
|
13168
|
-
class ConfigError extends OCXError {
|
|
13169
|
-
constructor(message) {
|
|
13170
|
-
super(message, "CONFIG_ERROR", EXIT_CODES.CONFIG);
|
|
13171
|
-
this.name = "ConfigError";
|
|
13172
|
-
}
|
|
13173
|
-
}
|
|
13174
|
-
|
|
13175
|
-
class ValidationError extends OCXError {
|
|
13176
|
-
constructor(message) {
|
|
13177
|
-
super(message, "VALIDATION_ERROR", EXIT_CODES.GENERAL);
|
|
13178
|
-
this.name = "ValidationError";
|
|
13179
|
-
}
|
|
13180
|
-
}
|
|
13181
|
-
class IntegrityError extends OCXError {
|
|
13182
|
-
constructor(component, expected, found) {
|
|
13183
|
-
const message = `Integrity verification failed for "${component}"
|
|
13184
|
-
` + ` Expected: ${expected}
|
|
13185
|
-
` + ` Found: ${found}
|
|
13186
|
-
|
|
13187
|
-
` + `The registry content has changed since this component was locked.
|
|
13188
|
-
` + `This could indicate tampering or an unauthorized update.`;
|
|
13189
|
-
super(message, "INTEGRITY_ERROR", EXIT_CODES.INTEGRITY);
|
|
13190
|
-
this.name = "IntegrityError";
|
|
13191
|
-
}
|
|
13192
|
-
}
|
|
13193
|
-
|
|
13194
13275
|
// src/registry/fetcher.ts
|
|
13195
13276
|
var cache = new Map;
|
|
13196
13277
|
async function fetchWithCache(url, parse) {
|
|
@@ -13252,7 +13333,58 @@ async function fetchFileContent(baseUrl, componentName, filePath) {
|
|
|
13252
13333
|
return response.text();
|
|
13253
13334
|
}
|
|
13254
13335
|
|
|
13336
|
+
// ../../node_modules/.bun/remeda@2.33.0/node_modules/remeda/dist/lazyDataLastImpl-DtF3cihj.js
|
|
13337
|
+
function e2(e3, t2, n2) {
|
|
13338
|
+
let r2 = (n3) => e3(n3, ...t2);
|
|
13339
|
+
return n2 === undefined ? r2 : Object.assign(r2, { lazy: n2, lazyArgs: t2 });
|
|
13340
|
+
}
|
|
13341
|
+
|
|
13342
|
+
// ../../node_modules/.bun/remeda@2.33.0/node_modules/remeda/dist/purry-GjwKKIlp.js
|
|
13343
|
+
function t2(t3, n2, r2) {
|
|
13344
|
+
let i2 = t3.length - n2.length;
|
|
13345
|
+
if (i2 === 0)
|
|
13346
|
+
return t3(...n2);
|
|
13347
|
+
if (i2 === 1)
|
|
13348
|
+
return e2(t3, n2, r2);
|
|
13349
|
+
throw Error(`Wrong number of arguments`);
|
|
13350
|
+
}
|
|
13351
|
+
|
|
13352
|
+
// ../../node_modules/.bun/remeda@2.33.0/node_modules/remeda/dist/isPlainObject.js
|
|
13353
|
+
function e3(e4) {
|
|
13354
|
+
if (typeof e4 != `object` || !e4)
|
|
13355
|
+
return false;
|
|
13356
|
+
let t3 = Object.getPrototypeOf(e4);
|
|
13357
|
+
return t3 === null || t3 === Object.prototype;
|
|
13358
|
+
}
|
|
13359
|
+
|
|
13360
|
+
// ../../node_modules/.bun/remeda@2.33.0/node_modules/remeda/dist/mergeDeep.js
|
|
13361
|
+
function n2(...t3) {
|
|
13362
|
+
return t2(r2, t3);
|
|
13363
|
+
}
|
|
13364
|
+
function r2(e4, n3) {
|
|
13365
|
+
let i2 = { ...e4, ...n3 };
|
|
13366
|
+
for (let a3 in n3) {
|
|
13367
|
+
if (!(a3 in e4))
|
|
13368
|
+
continue;
|
|
13369
|
+
let { [a3]: o2 } = e4;
|
|
13370
|
+
if (!e3(o2))
|
|
13371
|
+
continue;
|
|
13372
|
+
let { [a3]: s2 } = n3;
|
|
13373
|
+
e3(s2) && (i2[a3] = r2(o2, s2));
|
|
13374
|
+
}
|
|
13375
|
+
return i2;
|
|
13376
|
+
}
|
|
13377
|
+
|
|
13255
13378
|
// src/registry/resolver.ts
|
|
13379
|
+
function parseComponentRef(ref, defaultNamespace) {
|
|
13380
|
+
if (ref.includes("/")) {
|
|
13381
|
+
return parseQualifiedComponent(ref);
|
|
13382
|
+
}
|
|
13383
|
+
if (defaultNamespace) {
|
|
13384
|
+
return { namespace: defaultNamespace, component: ref };
|
|
13385
|
+
}
|
|
13386
|
+
throw new ValidationError(`Component '${ref}' must include a namespace (e.g., 'kdco/${ref}')`);
|
|
13387
|
+
}
|
|
13256
13388
|
async function resolveDependencies(registries, componentNames) {
|
|
13257
13389
|
const resolved = new Map;
|
|
13258
13390
|
const visiting = new Set;
|
|
@@ -13261,41 +13393,45 @@ async function resolveDependencies(registries, componentNames) {
|
|
|
13261
13393
|
const npmDeps = new Set;
|
|
13262
13394
|
const npmDevDeps = new Set;
|
|
13263
13395
|
const disabledTools = new Set;
|
|
13264
|
-
|
|
13265
|
-
|
|
13396
|
+
const plugins = new Set;
|
|
13397
|
+
const agentConfigs = {};
|
|
13398
|
+
const instructionsSet = new Set;
|
|
13399
|
+
async function resolve2(componentNamespace, componentName, path3 = []) {
|
|
13400
|
+
const qualifiedName = createQualifiedComponent(componentNamespace, componentName);
|
|
13401
|
+
if (resolved.has(qualifiedName)) {
|
|
13266
13402
|
return;
|
|
13267
13403
|
}
|
|
13268
|
-
if (visiting.has(
|
|
13269
|
-
const cycle = [...path3,
|
|
13404
|
+
if (visiting.has(qualifiedName)) {
|
|
13405
|
+
const cycle = [...path3, qualifiedName].join(" \u2192 ");
|
|
13270
13406
|
throw new ValidationError(`Circular dependency detected: ${cycle}`);
|
|
13271
13407
|
}
|
|
13272
|
-
visiting.add(
|
|
13273
|
-
|
|
13274
|
-
|
|
13275
|
-
|
|
13276
|
-
for (const [regName, regConfig] of registryEntries) {
|
|
13277
|
-
try {
|
|
13278
|
-
const manifest = await fetchComponent(regConfig.url, name);
|
|
13279
|
-
component = manifest;
|
|
13280
|
-
foundRegistry = { name: regName, url: regConfig.url };
|
|
13281
|
-
break;
|
|
13282
|
-
} catch (_err) {}
|
|
13408
|
+
visiting.add(qualifiedName);
|
|
13409
|
+
const regConfig = registries[componentNamespace];
|
|
13410
|
+
if (!regConfig) {
|
|
13411
|
+
throw new ConfigError(`Registry '${componentNamespace}' not configured. Add it to ocx.jsonc registries.`);
|
|
13283
13412
|
}
|
|
13284
|
-
|
|
13285
|
-
|
|
13413
|
+
let component;
|
|
13414
|
+
try {
|
|
13415
|
+
component = await fetchComponent(regConfig.url, componentName);
|
|
13416
|
+
} catch (_err) {
|
|
13417
|
+
throw new OCXError(`Component '${componentName}' not found in registry '${componentNamespace}'.`, "NOT_FOUND");
|
|
13286
13418
|
}
|
|
13287
13419
|
for (const dep of component.dependencies) {
|
|
13288
|
-
|
|
13289
|
-
|
|
13290
|
-
|
|
13291
|
-
|
|
13292
|
-
|
|
13293
|
-
|
|
13420
|
+
const depRef = parseComponentRef(dep, componentNamespace);
|
|
13421
|
+
await resolve2(depRef.namespace, depRef.component, [...path3, qualifiedName]);
|
|
13422
|
+
}
|
|
13423
|
+
const normalizedComponent = normalizeComponentManifest(component);
|
|
13424
|
+
resolved.set(qualifiedName, {
|
|
13425
|
+
...normalizedComponent,
|
|
13426
|
+
namespace: componentNamespace,
|
|
13427
|
+
registryName: componentNamespace,
|
|
13428
|
+
baseUrl: regConfig.url,
|
|
13429
|
+
qualifiedName
|
|
13294
13430
|
});
|
|
13295
|
-
visiting.delete(
|
|
13296
|
-
if (
|
|
13431
|
+
visiting.delete(qualifiedName);
|
|
13432
|
+
if (normalizedComponent.mcpServers) {
|
|
13297
13433
|
const serverNames = [];
|
|
13298
|
-
for (const [serverName, config2] of Object.entries(
|
|
13434
|
+
for (const [serverName, config2] of Object.entries(normalizedComponent.mcpServers)) {
|
|
13299
13435
|
mcpServers[serverName] = config2;
|
|
13300
13436
|
serverNames.push(serverName);
|
|
13301
13437
|
}
|
|
@@ -13322,9 +13458,34 @@ async function resolveDependencies(registries, componentNames) {
|
|
|
13322
13458
|
disabledTools.add(tool);
|
|
13323
13459
|
}
|
|
13324
13460
|
}
|
|
13461
|
+
if (component.opencode) {
|
|
13462
|
+
if (component.opencode.plugins) {
|
|
13463
|
+
for (const plugin of component.opencode.plugins) {
|
|
13464
|
+
plugins.add(plugin);
|
|
13465
|
+
}
|
|
13466
|
+
}
|
|
13467
|
+
if (component.opencode.agent) {
|
|
13468
|
+
for (const [agentName, config2] of Object.entries(component.opencode.agent)) {
|
|
13469
|
+
agentConfigs[agentName] = n2(agentConfigs[agentName] ?? {}, config2);
|
|
13470
|
+
}
|
|
13471
|
+
}
|
|
13472
|
+
if (component.opencode.instructions) {
|
|
13473
|
+
for (const instruction of component.opencode.instructions) {
|
|
13474
|
+
instructionsSet.add(instruction);
|
|
13475
|
+
}
|
|
13476
|
+
}
|
|
13477
|
+
if (component.opencode.tools) {
|
|
13478
|
+
for (const [tool, enabled] of Object.entries(component.opencode.tools)) {
|
|
13479
|
+
if (enabled === false) {
|
|
13480
|
+
disabledTools.add(tool);
|
|
13481
|
+
}
|
|
13482
|
+
}
|
|
13483
|
+
}
|
|
13484
|
+
}
|
|
13325
13485
|
}
|
|
13326
13486
|
for (const name of componentNames) {
|
|
13327
|
-
|
|
13487
|
+
const ref = parseComponentRef(name);
|
|
13488
|
+
await resolve2(ref.namespace, ref.component);
|
|
13328
13489
|
}
|
|
13329
13490
|
const components = Array.from(resolved.values());
|
|
13330
13491
|
const installOrder = Array.from(resolved.keys());
|
|
@@ -13335,7 +13496,10 @@ async function resolveDependencies(registries, componentNames) {
|
|
|
13335
13496
|
agentMcpBindings,
|
|
13336
13497
|
npmDependencies: Array.from(npmDeps),
|
|
13337
13498
|
npmDevDependencies: Array.from(npmDevDeps),
|
|
13338
|
-
disabledTools: Array.from(disabledTools)
|
|
13499
|
+
disabledTools: Array.from(disabledTools),
|
|
13500
|
+
plugins: Array.from(plugins),
|
|
13501
|
+
agentConfigs,
|
|
13502
|
+
instructions: Array.from(instructionsSet)
|
|
13339
13503
|
};
|
|
13340
13504
|
}
|
|
13341
13505
|
|
|
@@ -14651,13 +14815,13 @@ function applyEdits(text2, edits) {
|
|
|
14651
14815
|
});
|
|
14652
14816
|
let lastModifiedOffset = text2.length;
|
|
14653
14817
|
for (let i2 = sortedEdits.length - 1;i2 >= 0; i2--) {
|
|
14654
|
-
let
|
|
14655
|
-
if (
|
|
14656
|
-
text2 = applyEdit(text2,
|
|
14818
|
+
let e4 = sortedEdits[i2];
|
|
14819
|
+
if (e4.offset + e4.length <= lastModifiedOffset) {
|
|
14820
|
+
text2 = applyEdit(text2, e4);
|
|
14657
14821
|
} else {
|
|
14658
14822
|
throw new Error("Overlapping edit");
|
|
14659
14823
|
}
|
|
14660
|
-
lastModifiedOffset =
|
|
14824
|
+
lastModifiedOffset = e4.offset;
|
|
14661
14825
|
}
|
|
14662
14826
|
return text2;
|
|
14663
14827
|
}
|
|
@@ -14677,23 +14841,29 @@ var installedComponentSchema = exports_external.object({
|
|
|
14677
14841
|
registry: exports_external.string(),
|
|
14678
14842
|
version: exports_external.string(),
|
|
14679
14843
|
hash: exports_external.string(),
|
|
14680
|
-
|
|
14681
|
-
installedAt: exports_external.string()
|
|
14844
|
+
files: exports_external.array(exports_external.string()),
|
|
14845
|
+
installedAt: exports_external.string(),
|
|
14846
|
+
alias: exports_external.string().optional()
|
|
14682
14847
|
});
|
|
14683
14848
|
var ocxLockSchema = exports_external.object({
|
|
14684
14849
|
lockVersion: exports_external.literal(1),
|
|
14685
|
-
installed: exports_external.record(installedComponentSchema).default({})
|
|
14850
|
+
installed: exports_external.record(qualifiedComponentSchema, installedComponentSchema).default({})
|
|
14686
14851
|
});
|
|
14687
14852
|
var opencodeMcpSchema = exports_external.record(mcpServerSchema);
|
|
14688
14853
|
var opencodeAgentSchema = exports_external.object({
|
|
14689
14854
|
disable: exports_external.boolean().optional(),
|
|
14690
|
-
tools: exports_external.record(exports_external.boolean()).optional()
|
|
14855
|
+
tools: exports_external.record(exports_external.boolean()).optional(),
|
|
14856
|
+
temperature: exports_external.number().min(0).max(2).optional(),
|
|
14857
|
+
prompt: exports_external.string().optional(),
|
|
14858
|
+
permission: exports_external.record(exports_external.enum(["allow", "deny"])).optional()
|
|
14691
14859
|
});
|
|
14692
14860
|
var opencodeConfigPatchSchema = exports_external.object({
|
|
14693
14861
|
default_agent: exports_external.string().optional(),
|
|
14694
14862
|
mcp: opencodeMcpSchema.optional(),
|
|
14695
14863
|
tools: exports_external.record(exports_external.boolean()).optional(),
|
|
14696
|
-
agent: exports_external.record(opencodeAgentSchema).optional()
|
|
14864
|
+
agent: exports_external.record(opencodeAgentSchema).optional(),
|
|
14865
|
+
plugin: exports_external.array(exports_external.string()).optional(),
|
|
14866
|
+
instructions: exports_external.array(exports_external.string()).optional()
|
|
14697
14867
|
});
|
|
14698
14868
|
var CONFIG_FILE = "ocx.jsonc";
|
|
14699
14869
|
var LOCK_FILE = "ocx.lock";
|
|
@@ -14826,6 +14996,66 @@ function applyDefaultAgent(content, config2, defaultAgent) {
|
|
|
14826
14996
|
const edits = modify(content, ["default_agent"], defaultAgent, JSONC_OPTIONS);
|
|
14827
14997
|
return applyEdits(content, edits);
|
|
14828
14998
|
}
|
|
14999
|
+
function applyPlugins(content, config2, plugins) {
|
|
15000
|
+
const added = [];
|
|
15001
|
+
let updatedContent = content;
|
|
15002
|
+
const existingPlugins = config2.plugin ?? [];
|
|
15003
|
+
for (const plugin of plugins) {
|
|
15004
|
+
if (existingPlugins.includes(plugin)) {
|
|
15005
|
+
continue;
|
|
15006
|
+
}
|
|
15007
|
+
const newIndex = existingPlugins.length + added.length;
|
|
15008
|
+
const edits = modify(updatedContent, ["plugin", newIndex], plugin, JSONC_OPTIONS);
|
|
15009
|
+
updatedContent = applyEdits(updatedContent, edits);
|
|
15010
|
+
added.push(plugin);
|
|
15011
|
+
}
|
|
15012
|
+
return { content: updatedContent, added };
|
|
15013
|
+
}
|
|
15014
|
+
function applyAgentConfigs(content, existingConfig, agentConfigs) {
|
|
15015
|
+
let updatedContent = content;
|
|
15016
|
+
const agentsConfigured = [];
|
|
15017
|
+
for (const [agentName, componentAgentConfig] of Object.entries(agentConfigs)) {
|
|
15018
|
+
const existingAgentConfig = existingConfig.agent?.[agentName] ?? {};
|
|
15019
|
+
const merged = n2(componentAgentConfig, existingAgentConfig);
|
|
15020
|
+
if (merged.tools) {
|
|
15021
|
+
for (const [toolPattern, enabled] of Object.entries(merged.tools)) {
|
|
15022
|
+
const edits = modify(updatedContent, ["agent", agentName, "tools", toolPattern], enabled, JSONC_OPTIONS);
|
|
15023
|
+
updatedContent = applyEdits(updatedContent, edits);
|
|
15024
|
+
}
|
|
15025
|
+
}
|
|
15026
|
+
if (merged.temperature !== undefined) {
|
|
15027
|
+
const edits = modify(updatedContent, ["agent", agentName, "temperature"], merged.temperature, JSONC_OPTIONS);
|
|
15028
|
+
updatedContent = applyEdits(updatedContent, edits);
|
|
15029
|
+
}
|
|
15030
|
+
if (merged.prompt) {
|
|
15031
|
+
const edits = modify(updatedContent, ["agent", agentName, "prompt"], merged.prompt, JSONC_OPTIONS);
|
|
15032
|
+
updatedContent = applyEdits(updatedContent, edits);
|
|
15033
|
+
}
|
|
15034
|
+
if (merged.permission) {
|
|
15035
|
+
for (const [pattern, permission] of Object.entries(merged.permission)) {
|
|
15036
|
+
const edits = modify(updatedContent, ["agent", agentName, "permission", pattern], permission, JSONC_OPTIONS);
|
|
15037
|
+
updatedContent = applyEdits(updatedContent, edits);
|
|
15038
|
+
}
|
|
15039
|
+
}
|
|
15040
|
+
agentsConfigured.push(agentName);
|
|
15041
|
+
}
|
|
15042
|
+
return { content: updatedContent, agentsConfigured };
|
|
15043
|
+
}
|
|
15044
|
+
function applyInstructions(content, config2, instructions) {
|
|
15045
|
+
const added = [];
|
|
15046
|
+
let updatedContent = content;
|
|
15047
|
+
const existingInstructions = config2.instructions ?? [];
|
|
15048
|
+
for (const instruction of instructions) {
|
|
15049
|
+
if (existingInstructions.includes(instruction)) {
|
|
15050
|
+
continue;
|
|
15051
|
+
}
|
|
15052
|
+
const newIndex = existingInstructions.length + added.length;
|
|
15053
|
+
const edits = modify(updatedContent, ["instructions", newIndex], instruction, JSONC_OPTIONS);
|
|
15054
|
+
updatedContent = applyEdits(updatedContent, edits);
|
|
15055
|
+
added.push(instruction);
|
|
15056
|
+
}
|
|
15057
|
+
return { content: updatedContent, added };
|
|
15058
|
+
}
|
|
14829
15059
|
async function updateOpencodeConfig(cwd, options2) {
|
|
14830
15060
|
const existing = await readOpencodeConfig(cwd);
|
|
14831
15061
|
let content;
|
|
@@ -14846,6 +15076,8 @@ async function updateOpencodeConfig(cwd, options2) {
|
|
|
14846
15076
|
let mcpSkipped = [];
|
|
14847
15077
|
let agentsConfigured = [];
|
|
14848
15078
|
let toolsDisabled = [];
|
|
15079
|
+
let pluginsAdded = [];
|
|
15080
|
+
let instructionsAdded = [];
|
|
14849
15081
|
if (options2.mcpServers && Object.keys(options2.mcpServers).length > 0) {
|
|
14850
15082
|
const result = applyMcpServers(content, config2, options2.mcpServers);
|
|
14851
15083
|
content = result.content;
|
|
@@ -14869,6 +15101,24 @@ async function updateOpencodeConfig(cwd, options2) {
|
|
|
14869
15101
|
content = applyDisabledTools(content, options2.disabledTools);
|
|
14870
15102
|
toolsDisabled = options2.disabledTools;
|
|
14871
15103
|
}
|
|
15104
|
+
if (options2.plugins && options2.plugins.length > 0) {
|
|
15105
|
+
const updatedConfig = parse2(content, [], { allowTrailingComma: true });
|
|
15106
|
+
const result = applyPlugins(content, updatedConfig, options2.plugins);
|
|
15107
|
+
content = result.content;
|
|
15108
|
+
pluginsAdded = result.added;
|
|
15109
|
+
}
|
|
15110
|
+
if (options2.agentConfigs && Object.keys(options2.agentConfigs).length > 0) {
|
|
15111
|
+
const updatedConfig = parse2(content, [], { allowTrailingComma: true });
|
|
15112
|
+
const result = applyAgentConfigs(content, updatedConfig, options2.agentConfigs);
|
|
15113
|
+
content = result.content;
|
|
15114
|
+
agentsConfigured = [...new Set([...agentsConfigured, ...result.agentsConfigured])];
|
|
15115
|
+
}
|
|
15116
|
+
if (options2.instructions && options2.instructions.length > 0) {
|
|
15117
|
+
const updatedConfig = parse2(content, [], { allowTrailingComma: true });
|
|
15118
|
+
const result = applyInstructions(content, updatedConfig, options2.instructions);
|
|
15119
|
+
content = result.content;
|
|
15120
|
+
instructionsAdded = result.added;
|
|
15121
|
+
}
|
|
14872
15122
|
await writeOpencodeConfig(configPath, content);
|
|
14873
15123
|
return {
|
|
14874
15124
|
path: configPath,
|
|
@@ -14876,7 +15126,9 @@ async function updateOpencodeConfig(cwd, options2) {
|
|
|
14876
15126
|
mcpAdded,
|
|
14877
15127
|
mcpSkipped,
|
|
14878
15128
|
agentsConfigured,
|
|
14879
|
-
toolsDisabled
|
|
15129
|
+
toolsDisabled,
|
|
15130
|
+
pluginsAdded,
|
|
15131
|
+
instructionsAdded
|
|
14880
15132
|
};
|
|
14881
15133
|
}
|
|
14882
15134
|
|
|
@@ -16454,28 +16706,48 @@ async function runAdd(componentNames, options3) {
|
|
|
16454
16706
|
files.push({ path: file.path, content: Buffer.from(content) });
|
|
16455
16707
|
}
|
|
16456
16708
|
const computedHash = await hashBundle(files);
|
|
16457
|
-
const existingEntry = lock.installed[component.
|
|
16709
|
+
const existingEntry = lock.installed[component.qualifiedName];
|
|
16458
16710
|
if (existingEntry && existingEntry.hash !== computedHash) {
|
|
16459
|
-
throw new IntegrityError(component.
|
|
16711
|
+
throw new IntegrityError(component.qualifiedName, existingEntry.hash, computedHash);
|
|
16712
|
+
}
|
|
16713
|
+
for (const file of component.files) {
|
|
16714
|
+
const targetPath = join2(cwd, file.target);
|
|
16715
|
+
if (existsSync2(targetPath)) {
|
|
16716
|
+
const conflictingComponent = findComponentByFile(lock, file.target);
|
|
16717
|
+
if (conflictingComponent && conflictingComponent !== component.qualifiedName) {
|
|
16718
|
+
throw new ConflictError(`File conflict: ${file.target} already exists (installed by '${conflictingComponent}').
|
|
16719
|
+
|
|
16720
|
+
` + `To resolve:
|
|
16721
|
+
` + ` 1. Remove existing: rm ${file.target}
|
|
16722
|
+
` + ` 2. Or rename it manually and update references
|
|
16723
|
+
` + ` 3. Then run: ocx add ${component.qualifiedName}`);
|
|
16724
|
+
}
|
|
16725
|
+
}
|
|
16460
16726
|
}
|
|
16461
16727
|
await installComponent(component, files, cwd);
|
|
16462
16728
|
const index = await fetchRegistryIndex(component.baseUrl);
|
|
16463
|
-
lock.installed[component.
|
|
16729
|
+
lock.installed[component.qualifiedName] = {
|
|
16464
16730
|
registry: component.registryName,
|
|
16465
16731
|
version: index.version,
|
|
16466
16732
|
hash: computedHash,
|
|
16467
|
-
|
|
16733
|
+
files: component.files.map((f2) => f2.target),
|
|
16468
16734
|
installedAt: new Date().toISOString()
|
|
16469
16735
|
};
|
|
16470
16736
|
}
|
|
16471
16737
|
installSpin?.succeed(`Installed ${resolved.components.length} components`);
|
|
16472
16738
|
const hasMcpChanges = Object.keys(resolved.mcpServers).length > 0 || resolved.agentMcpBindings.length > 0;
|
|
16473
16739
|
const hasDisabledTools = resolved.disabledTools.length > 0;
|
|
16474
|
-
|
|
16740
|
+
const hasPlugins = resolved.plugins.length > 0;
|
|
16741
|
+
const hasAgentConfigs = Object.keys(resolved.agentConfigs).length > 0;
|
|
16742
|
+
const hasInstructions = resolved.instructions.length > 0;
|
|
16743
|
+
if (hasMcpChanges || hasDisabledTools || hasPlugins || hasAgentConfigs || hasInstructions) {
|
|
16475
16744
|
const result = await updateOpencodeConfig(cwd, {
|
|
16476
16745
|
mcpServers: resolved.mcpServers,
|
|
16477
16746
|
agentMcpBindings: resolved.agentMcpBindings,
|
|
16478
|
-
disabledTools: resolved.disabledTools
|
|
16747
|
+
disabledTools: resolved.disabledTools,
|
|
16748
|
+
plugins: resolved.plugins,
|
|
16749
|
+
agentConfigs: resolved.agentConfigs,
|
|
16750
|
+
instructions: resolved.instructions
|
|
16479
16751
|
});
|
|
16480
16752
|
if (result.mcpSkipped.length > 0 && !options3.quiet) {
|
|
16481
16753
|
for (const name of result.mcpSkipped) {
|
|
@@ -16491,6 +16763,15 @@ async function runAdd(componentNames, options3) {
|
|
|
16491
16763
|
if (!options3.quiet && result.toolsDisabled.length > 0) {
|
|
16492
16764
|
logger.info(`Disabled ${result.toolsDisabled.length} tools: ${result.toolsDisabled.join(", ")}`);
|
|
16493
16765
|
}
|
|
16766
|
+
if (!options3.quiet && result.pluginsAdded.length > 0) {
|
|
16767
|
+
logger.info(`Added ${result.pluginsAdded.length} plugins: ${result.pluginsAdded.join(", ")}`);
|
|
16768
|
+
}
|
|
16769
|
+
if (!options3.quiet && result.agentsConfigured.length > 0) {
|
|
16770
|
+
logger.info(`Configured ${result.agentsConfigured.length} agents: ${result.agentsConfigured.join(", ")}`);
|
|
16771
|
+
}
|
|
16772
|
+
if (!options3.quiet && result.instructionsAdded.length > 0) {
|
|
16773
|
+
logger.info(`Added ${result.instructionsAdded.length} instructions`);
|
|
16774
|
+
}
|
|
16494
16775
|
}
|
|
16495
16776
|
const hasNpmDeps = resolved.npmDependencies.length > 0;
|
|
16496
16777
|
const hasNpmDevDeps = resolved.npmDevDependencies.length > 0;
|
|
@@ -16535,9 +16816,6 @@ async function installComponent(component, files, cwd) {
|
|
|
16535
16816
|
await writeFile(targetPath, file.content);
|
|
16536
16817
|
}
|
|
16537
16818
|
}
|
|
16538
|
-
function getTargetPath(component) {
|
|
16539
|
-
return component.files[0]?.target ?? `.opencode/${component.type}/${component.name}`;
|
|
16540
|
-
}
|
|
16541
16819
|
async function hashContent(content) {
|
|
16542
16820
|
return createHash("sha256").update(content).digest("hex");
|
|
16543
16821
|
}
|
|
@@ -16593,6 +16871,14 @@ async function installNpmDependencies(dependencies, devDependencies, cwd, option
|
|
|
16593
16871
|
await run(parseNi, [...devDependencies, "-D"], { cwd });
|
|
16594
16872
|
}
|
|
16595
16873
|
}
|
|
16874
|
+
function findComponentByFile(lock, filePath) {
|
|
16875
|
+
for (const [qualifiedName, entry] of Object.entries(lock.installed)) {
|
|
16876
|
+
if (entry.files.includes(filePath)) {
|
|
16877
|
+
return qualifiedName;
|
|
16878
|
+
}
|
|
16879
|
+
}
|
|
16880
|
+
return null;
|
|
16881
|
+
}
|
|
16596
16882
|
|
|
16597
16883
|
// src/commands/build.ts
|
|
16598
16884
|
import { mkdir as mkdir2 } from "fs/promises";
|
|
@@ -16619,7 +16905,7 @@ function registerBuildCommand(program2) {
|
|
|
16619
16905
|
if (!parseResult.success) {
|
|
16620
16906
|
if (!options3.json) {
|
|
16621
16907
|
spinner2.fail("Registry validation failed");
|
|
16622
|
-
const errors3 = parseResult.error.errors.map((
|
|
16908
|
+
const errors3 = parseResult.error.errors.map((e4) => ` ${e4.path.join(".")}: ${e4.message}`);
|
|
16623
16909
|
for (const err of errors3) {
|
|
16624
16910
|
console.log(kleur_default.red(err));
|
|
16625
16911
|
}
|
|
@@ -16642,7 +16928,8 @@ function registerBuildCommand(program2) {
|
|
|
16642
16928
|
};
|
|
16643
16929
|
const packumentPath = join3(componentsDir, `${component.name}.json`);
|
|
16644
16930
|
await Bun.write(packumentPath, JSON.stringify(packument, null, 2));
|
|
16645
|
-
for (const
|
|
16931
|
+
for (const rawFile of component.files) {
|
|
16932
|
+
const file = normalizeFile(rawFile);
|
|
16646
16933
|
const sourceFilePath = join3(sourcePath, "files", file.path);
|
|
16647
16934
|
const destFilePath = join3(componentsDir, component.name, file.path);
|
|
16648
16935
|
const destFileDir = dirname3(destFilePath);
|
|
@@ -16666,7 +16953,7 @@ function registerBuildCommand(program2) {
|
|
|
16666
16953
|
}
|
|
16667
16954
|
const index = {
|
|
16668
16955
|
name: registry.name,
|
|
16669
|
-
|
|
16956
|
+
namespace: registry.namespace,
|
|
16670
16957
|
version: registry.version,
|
|
16671
16958
|
author: registry.author,
|
|
16672
16959
|
components: registry.components.map((c2) => ({
|
|
@@ -17534,7 +17821,11 @@ function registerDiffCommand(program2) {
|
|
|
17534
17821
|
}
|
|
17535
17822
|
continue;
|
|
17536
17823
|
}
|
|
17537
|
-
|
|
17824
|
+
if (!installed.files || installed.files.length === 0) {
|
|
17825
|
+
logger.warn(`No files recorded for component '${name}'`);
|
|
17826
|
+
continue;
|
|
17827
|
+
}
|
|
17828
|
+
const localPath = `${options3.cwd}/${installed.files[0]}`;
|
|
17538
17829
|
const localFile = Bun.file(localPath);
|
|
17539
17830
|
if (!await localFile.exists()) {
|
|
17540
17831
|
results.push({ name, hasChanges: true, diff: "Local file missing" });
|
|
@@ -17547,13 +17838,16 @@ function registerDiffCommand(program2) {
|
|
|
17547
17838
|
continue;
|
|
17548
17839
|
}
|
|
17549
17840
|
try {
|
|
17550
|
-
const
|
|
17551
|
-
const
|
|
17552
|
-
|
|
17841
|
+
const parsed = parseQualifiedComponent(name);
|
|
17842
|
+
const componentName = parsed.component;
|
|
17843
|
+
const upstream = await fetchComponent(registryConfig.url, componentName);
|
|
17844
|
+
const rawUpstreamFile = upstream.files[0];
|
|
17845
|
+
if (!rawUpstreamFile) {
|
|
17553
17846
|
results.push({ name, hasChanges: false });
|
|
17554
17847
|
continue;
|
|
17555
17848
|
}
|
|
17556
|
-
const
|
|
17849
|
+
const upstreamFile = normalizeFile(rawUpstreamFile);
|
|
17850
|
+
const upstreamContent = await fetchFileContent(registryConfig.url, componentName, upstreamFile.path);
|
|
17557
17851
|
if (localContent === upstreamContent) {
|
|
17558
17852
|
results.push({ name, hasChanges: false });
|
|
17559
17853
|
} else {
|
|
@@ -17801,7 +18095,7 @@ function registerSearchCommand(program2) {
|
|
|
17801
18095
|
}
|
|
17802
18096
|
for (const comp of index.components) {
|
|
17803
18097
|
allComponents.push({
|
|
17804
|
-
name: comp.name
|
|
18098
|
+
name: `${index.namespace}/${comp.name}`,
|
|
17805
18099
|
description: comp.description,
|
|
17806
18100
|
type: comp.type,
|
|
17807
18101
|
registry: registryName
|
|
@@ -17822,7 +18116,7 @@ function registerSearchCommand(program2) {
|
|
|
17822
18116
|
keys: ["name", "description"],
|
|
17823
18117
|
limit
|
|
17824
18118
|
});
|
|
17825
|
-
results = fuzzyResults.map((
|
|
18119
|
+
results = fuzzyResults.map((r3) => r3.obj);
|
|
17826
18120
|
} else {
|
|
17827
18121
|
results = results.slice(0, limit);
|
|
17828
18122
|
}
|
|
@@ -17845,7 +18139,7 @@ function registerSearchCommand(program2) {
|
|
|
17845
18139
|
}
|
|
17846
18140
|
|
|
17847
18141
|
// src/index.ts
|
|
17848
|
-
var version2 = "1.0.
|
|
18142
|
+
var version2 = "1.0.8";
|
|
17849
18143
|
async function main2() {
|
|
17850
18144
|
const program2 = new Command().name("ocx").description("OpenCode Extensions - Install agents, skills, plugins, and commands").version(version2);
|
|
17851
18145
|
registerInitCommand(program2);
|
|
@@ -17860,4 +18154,4 @@ main2().catch((err) => {
|
|
|
17860
18154
|
handleError(err);
|
|
17861
18155
|
});
|
|
17862
18156
|
|
|
17863
|
-
//# debugId=
|
|
18157
|
+
//# debugId=4504091B3609ACE764756E2164756E21
|