orionfold-relay 0.17.0 → 0.19.0
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/cli.js +643 -383
- package/package.json +1 -1
- package/src/app/api/license/[id]/route.ts +32 -0
- package/src/app/api/license/route.ts +85 -0
- package/src/app/api/packs/install/route.ts +82 -0
- package/src/app/apps/page.tsx +6 -0
- package/src/app/packs/page.tsx +155 -0
- package/src/app/settings/page.tsx +2 -0
- package/src/components/packs/pack-install-button.tsx +108 -0
- package/src/components/settings/license-section.tsx +345 -0
- package/src/components/shell/nav-items.ts +6 -1
- package/src/lib/apps/app-schedule-id.ts +37 -0
- package/src/lib/apps/manifest-trigger-dispatch.ts +57 -0
- package/src/lib/apps/registry.ts +27 -1
- package/src/lib/chat/tools/plugin-spec-tools.ts +2 -1
- package/src/lib/packs/catalog.ts +122 -0
- package/src/lib/packs/cli.ts +4 -3
- package/src/lib/packs/format.ts +8 -0
- package/src/lib/packs/install.ts +143 -23
- package/src/lib/packs/templates/relay-agency-pro/base/blueprints/relay-agency-pro--client-audit-export.yaml +53 -0
- package/src/lib/packs/templates/relay-agency-pro/base/blueprints/relay-agency-pro--cre-renewal-engine.yaml +93 -0
- package/src/lib/packs/templates/relay-agency-pro/base/blueprints/relay-agency-pro--intake-pipeline.yaml +69 -0
- package/src/lib/packs/templates/relay-agency-pro/base/blueprints/relay-agency-pro--month-end-close.yaml +72 -0
- package/src/lib/packs/templates/relay-agency-pro/base/blueprints/relay-agency-pro--new-business.yaml +84 -0
- package/src/lib/packs/templates/relay-agency-pro/base/manifest.yaml +120 -0
- package/src/lib/packs/templates/relay-agency-pro/base/profiles/relay-agency-pro--cre-renewal-analyst/SKILL.md +69 -0
- package/src/lib/packs/templates/relay-agency-pro/base/profiles/relay-agency-pro--cre-renewal-analyst/profile.yaml +19 -0
- package/src/lib/packs/templates/relay-agency-pro/base/profiles/relay-agency-pro--finance-controller/SKILL.md +32 -0
- package/src/lib/packs/templates/relay-agency-pro/base/profiles/relay-agency-pro--finance-controller/profile.yaml +17 -0
- package/src/lib/packs/templates/relay-agency-pro/base/profiles/relay-agency-pro--governance-auditor/SKILL.md +28 -0
- package/src/lib/packs/templates/relay-agency-pro/base/profiles/relay-agency-pro--governance-auditor/profile.yaml +17 -0
- package/src/lib/packs/templates/relay-agency-pro/base/profiles/relay-agency-pro--intake-coordinator/SKILL.md +28 -0
- package/src/lib/packs/templates/relay-agency-pro/base/profiles/relay-agency-pro--intake-coordinator/profile.yaml +17 -0
- package/src/lib/packs/templates/relay-agency-pro/base/profiles/relay-agency-pro--proposal-writer/SKILL.md +19 -0
- package/src/lib/packs/templates/relay-agency-pro/base/profiles/relay-agency-pro--proposal-writer/profile.yaml +17 -0
- package/src/lib/packs/templates/relay-agency-pro/base/profiles/relay-agency-pro--prospect-researcher/SKILL.md +20 -0
- package/src/lib/packs/templates/relay-agency-pro/base/profiles/relay-agency-pro--prospect-researcher/profile.yaml +19 -0
- package/src/lib/packs/templates/relay-agency-pro/base/profiles/relay-agency-pro--sensitive-client-analyst/SKILL.md +24 -0
- package/src/lib/packs/templates/relay-agency-pro/base/profiles/relay-agency-pro--sensitive-client-analyst/profile.yaml +21 -0
- package/src/lib/packs/templates/relay-agency-pro/pack.yaml +23 -0
- package/src/lib/plugins/examples/echo-server/plugin.yaml +1 -1
- package/src/lib/plugins/examples/finance-pack/plugin.yaml +1 -1
- package/src/lib/plugins/examples/reading-radar/plugin.yaml +1 -1
- package/src/lib/plugins/registry.ts +7 -11
- package/src/lib/plugins/sdk/types.ts +8 -0
- package/src/lib/schedules/scheduler.ts +118 -2
package/dist/cli.js
CHANGED
|
@@ -1177,14 +1177,16 @@ var init_detect = __esm({
|
|
|
1177
1177
|
var types_exports = {};
|
|
1178
1178
|
__export(types_exports, {
|
|
1179
1179
|
CAPABILITY_VALUES: () => CAPABILITY_VALUES,
|
|
1180
|
+
CURRENT_PLUGIN_API_VERSION: () => CURRENT_PLUGIN_API_VERSION,
|
|
1180
1181
|
ORIGIN_VALUES: () => ORIGIN_VALUES,
|
|
1181
1182
|
PluginManifestSchema: () => PluginManifestSchema
|
|
1182
1183
|
});
|
|
1183
1184
|
import { z } from "zod";
|
|
1184
|
-
var CAPABILITY_VALUES, ORIGIN_VALUES, PrimitivesBundleManifestSchema, ChatToolsPluginManifestSchema, PluginManifestSchema;
|
|
1185
|
+
var CURRENT_PLUGIN_API_VERSION, CAPABILITY_VALUES, ORIGIN_VALUES, PrimitivesBundleManifestSchema, ChatToolsPluginManifestSchema, PluginManifestSchema;
|
|
1185
1186
|
var init_types = __esm({
|
|
1186
1187
|
"src/lib/plugins/sdk/types.ts"() {
|
|
1187
1188
|
"use strict";
|
|
1189
|
+
CURRENT_PLUGIN_API_VERSION = "0.19";
|
|
1188
1190
|
CAPABILITY_VALUES = ["fs", "net", "child_process", "env"];
|
|
1189
1191
|
ORIGIN_VALUES = ["ainative-internal", "third-party"];
|
|
1190
1192
|
PrimitivesBundleManifestSchema = z.object({
|
|
@@ -1230,16 +1232,16 @@ function computeHash(content) {
|
|
|
1230
1232
|
function safePreview(content) {
|
|
1231
1233
|
return content.slice(0, MAX_PREVIEW_CHARS).trim();
|
|
1232
1234
|
}
|
|
1233
|
-
function safeStat(
|
|
1235
|
+
function safeStat(path21) {
|
|
1234
1236
|
try {
|
|
1235
|
-
return statSync2(
|
|
1237
|
+
return statSync2(path21);
|
|
1236
1238
|
} catch {
|
|
1237
1239
|
return null;
|
|
1238
1240
|
}
|
|
1239
1241
|
}
|
|
1240
|
-
function safeReadFile(
|
|
1242
|
+
function safeReadFile(path21) {
|
|
1241
1243
|
try {
|
|
1242
|
-
return readFileSync4(
|
|
1244
|
+
return readFileSync4(path21, "utf-8");
|
|
1243
1245
|
} catch {
|
|
1244
1246
|
return null;
|
|
1245
1247
|
}
|
|
@@ -3456,7 +3458,8 @@ async function deleteAppCascade(appId, options = {}) {
|
|
|
3456
3458
|
filesRemoved: false,
|
|
3457
3459
|
projectRemoved: false,
|
|
3458
3460
|
profilesRemoved: 0,
|
|
3459
|
-
blueprintsRemoved: 0
|
|
3461
|
+
blueprintsRemoved: 0,
|
|
3462
|
+
schedulesRemoved: 0
|
|
3460
3463
|
};
|
|
3461
3464
|
const resolvedApps = path2.resolve(appsDir);
|
|
3462
3465
|
const rootDir = path2.resolve(appsDir, appId);
|
|
@@ -3476,7 +3479,23 @@ async function deleteAppCascade(appId, options = {}) {
|
|
|
3476
3479
|
const filesRemoved = deleteApp(appId, appsDir);
|
|
3477
3480
|
const profilesRemoved = sweepNamespacedProfiles(profilesDir, appId);
|
|
3478
3481
|
const blueprintsRemoved = sweepNamespacedBlueprints(blueprintsDir, appId);
|
|
3479
|
-
|
|
3482
|
+
let schedulesRemoved = 0;
|
|
3483
|
+
try {
|
|
3484
|
+
const { db: db3 } = await Promise.resolve().then(() => (init_db(), db_exports));
|
|
3485
|
+
const { schedules: schedules2 } = await Promise.resolve().then(() => (init_schema(), schema_exports));
|
|
3486
|
+
const { like: like8 } = await import("drizzle-orm");
|
|
3487
|
+
const result = db3.delete(schedules2).where(like8(schedules2.id, `app:${appId}:%`)).run();
|
|
3488
|
+
schedulesRemoved = result.changes;
|
|
3489
|
+
} catch (err2) {
|
|
3490
|
+
console.error(`[registry] schedule sweep failed for app "${appId}":`, err2);
|
|
3491
|
+
}
|
|
3492
|
+
return {
|
|
3493
|
+
projectRemoved,
|
|
3494
|
+
filesRemoved,
|
|
3495
|
+
profilesRemoved,
|
|
3496
|
+
blueprintsRemoved,
|
|
3497
|
+
schedulesRemoved
|
|
3498
|
+
};
|
|
3480
3499
|
}
|
|
3481
3500
|
var AppArtifactRefSchema, AppBlueprintRefSchema, KitIdSchema, BindingRefSchema, LeafKpiSourceSchema, RatioKpiSourceSchema, KpiSourceSchema, KpiSpecSchema, ViewSchema, AppTableRefSchema, AppScheduleRefSchema, AppManifestSchema, DOW, APPS_CACHE_TTL_MS, appsCache, appsDetailCache, SLUG_RE;
|
|
3482
3501
|
var init_registry = __esm({
|
|
@@ -3717,6 +3736,14 @@ var init_format = __esm({
|
|
|
3717
3736
|
* The string is the unit of entitlement, version- and pack-id-agnostic.
|
|
3718
3737
|
*/
|
|
3719
3738
|
entitlement: z3.string().min(1).optional(),
|
|
3739
|
+
/**
|
|
3740
|
+
* Premium display copy (D6). Offline strings rendered on the locked
|
|
3741
|
+
* gallery card — the Website still owns actual pricing. Meaningful only
|
|
3742
|
+
* alongside `entitlement`; harmless on a free pack.
|
|
3743
|
+
*/
|
|
3744
|
+
price: z3.string().min(1).optional(),
|
|
3745
|
+
/** Get-license CTA target on the locked card. */
|
|
3746
|
+
purchaseUrl: z3.url().optional(),
|
|
3720
3747
|
/** Customer slugs seeded via ensureCustomer at install. */
|
|
3721
3748
|
customers: z3.array(z3.string()).default([])
|
|
3722
3749
|
}).strict();
|
|
@@ -3731,6 +3758,82 @@ var init_format = __esm({
|
|
|
3731
3758
|
}
|
|
3732
3759
|
});
|
|
3733
3760
|
|
|
3761
|
+
// src/lib/packs/catalog.ts
|
|
3762
|
+
var catalog_exports = {};
|
|
3763
|
+
__export(catalog_exports, {
|
|
3764
|
+
UnknownPackNameError: () => UnknownPackNameError,
|
|
3765
|
+
findPackTemplate: () => findPackTemplate,
|
|
3766
|
+
listPackTemplates: () => listPackTemplates,
|
|
3767
|
+
packTemplatesDir: () => packTemplatesDir,
|
|
3768
|
+
resolvePackSource: () => resolvePackSource
|
|
3769
|
+
});
|
|
3770
|
+
import fs4 from "fs";
|
|
3771
|
+
import path4 from "path";
|
|
3772
|
+
function packTemplatesDir(opts2 = {}) {
|
|
3773
|
+
return opts2.templatesDir ?? path4.join(
|
|
3774
|
+
getAppRoot(import.meta.dirname, 3),
|
|
3775
|
+
"src",
|
|
3776
|
+
"lib",
|
|
3777
|
+
"packs",
|
|
3778
|
+
"templates"
|
|
3779
|
+
);
|
|
3780
|
+
}
|
|
3781
|
+
function listPackTemplates(opts2 = {}) {
|
|
3782
|
+
const dir = packTemplatesDir(opts2);
|
|
3783
|
+
if (!fs4.existsSync(dir)) return [];
|
|
3784
|
+
const out = [];
|
|
3785
|
+
for (const entry of fs4.readdirSync(dir, { withFileTypes: true })) {
|
|
3786
|
+
if (!entry.isDirectory()) continue;
|
|
3787
|
+
const templateDir = path4.join(dir, entry.name);
|
|
3788
|
+
try {
|
|
3789
|
+
const pack = parsePack(templateDir);
|
|
3790
|
+
out.push({
|
|
3791
|
+
id: pack.meta.id,
|
|
3792
|
+
dir: templateDir,
|
|
3793
|
+
meta: pack.meta,
|
|
3794
|
+
primitivesSummary: buildPrimitivesSummary(pack.manifest)
|
|
3795
|
+
});
|
|
3796
|
+
} catch (err2) {
|
|
3797
|
+
out.push({
|
|
3798
|
+
id: entry.name,
|
|
3799
|
+
dir: templateDir,
|
|
3800
|
+
error: err2 instanceof Error ? err2.message : String(err2)
|
|
3801
|
+
});
|
|
3802
|
+
}
|
|
3803
|
+
}
|
|
3804
|
+
return out.sort((a, b) => a.id.localeCompare(b.id));
|
|
3805
|
+
}
|
|
3806
|
+
function findPackTemplate(id, opts2 = {}) {
|
|
3807
|
+
const match = listPackTemplates(opts2).find((t) => t.id === id);
|
|
3808
|
+
return match && !match.error ? match : null;
|
|
3809
|
+
}
|
|
3810
|
+
function resolvePackSource(source, opts2 = {}) {
|
|
3811
|
+
if (fs4.existsSync(path4.resolve(source))) return source;
|
|
3812
|
+
if (!BARE_NAME.test(source)) return source;
|
|
3813
|
+
const template = findPackTemplate(source, opts2);
|
|
3814
|
+
if (template) return template.dir;
|
|
3815
|
+
const ids = listPackTemplates(opts2).filter((t) => !t.error).map((t) => t.id);
|
|
3816
|
+
throw new UnknownPackNameError(
|
|
3817
|
+
`Unknown pack "${source}". Bundled packs: ${ids.length ? ids.join(", ") : "(none)"}. Otherwise pass a folder path or git URL.`
|
|
3818
|
+
);
|
|
3819
|
+
}
|
|
3820
|
+
var UnknownPackNameError, BARE_NAME;
|
|
3821
|
+
var init_catalog = __esm({
|
|
3822
|
+
"src/lib/packs/catalog.ts"() {
|
|
3823
|
+
"use strict";
|
|
3824
|
+
init_app_root();
|
|
3825
|
+
init_registry();
|
|
3826
|
+
init_format();
|
|
3827
|
+
UnknownPackNameError = class extends Error {
|
|
3828
|
+
constructor(message) {
|
|
3829
|
+
super(message);
|
|
3830
|
+
this.name = "UnknownPackNameError";
|
|
3831
|
+
}
|
|
3832
|
+
};
|
|
3833
|
+
BARE_NAME = /^[a-z0-9][a-z0-9-]*$/;
|
|
3834
|
+
}
|
|
3835
|
+
});
|
|
3836
|
+
|
|
3734
3837
|
// src/lib/licensing/canonicalize.ts
|
|
3735
3838
|
function canonicalize(v) {
|
|
3736
3839
|
if (Array.isArray(v)) {
|
|
@@ -3914,7 +4017,7 @@ __export(load_exports, {
|
|
|
3914
4017
|
LicenseLoadError: () => LicenseLoadError,
|
|
3915
4018
|
loadLicense: () => loadLicense
|
|
3916
4019
|
});
|
|
3917
|
-
import
|
|
4020
|
+
import fs5 from "fs";
|
|
3918
4021
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3919
4022
|
function assertEnvelope(value, origin) {
|
|
3920
4023
|
if (!value || typeof value !== "object") {
|
|
@@ -3962,7 +4065,7 @@ async function loadLicense(urlOrPath) {
|
|
|
3962
4065
|
const filePath = urlOrPath.startsWith("file://") ? fileURLToPath3(urlOrPath) : urlOrPath;
|
|
3963
4066
|
let text2;
|
|
3964
4067
|
try {
|
|
3965
|
-
text2 =
|
|
4068
|
+
text2 = fs5.readFileSync(filePath, "utf-8");
|
|
3966
4069
|
} catch (err2) {
|
|
3967
4070
|
throw new LicenseLoadError(
|
|
3968
4071
|
`Could not read license file at ${filePath}.`,
|
|
@@ -3997,10 +4100,10 @@ __export(store_exports, {
|
|
|
3997
4100
|
removeLicense: () => removeLicense,
|
|
3998
4101
|
saveLicense: () => saveLicense
|
|
3999
4102
|
});
|
|
4000
|
-
import
|
|
4001
|
-
import
|
|
4103
|
+
import fs6 from "fs";
|
|
4104
|
+
import path5 from "path";
|
|
4002
4105
|
function licensesDir(opts2 = {}) {
|
|
4003
|
-
return opts2.dir ??
|
|
4106
|
+
return opts2.dir ?? path5.join(getAinativeDataDir(), "licenses");
|
|
4004
4107
|
}
|
|
4005
4108
|
function readIdentity(payload) {
|
|
4006
4109
|
const raw = payload.issued_to && typeof payload.issued_to === "object" ? payload.issued_to : {};
|
|
@@ -4012,7 +4115,7 @@ function readIdentity(payload) {
|
|
|
4012
4115
|
}
|
|
4013
4116
|
function buildInfo(payload, filePath, valid, reason) {
|
|
4014
4117
|
return {
|
|
4015
|
-
licenseId: String(payload.license_id ??
|
|
4118
|
+
licenseId: String(payload.license_id ?? path5.basename(filePath, FILE_SUFFIX)),
|
|
4016
4119
|
filePath,
|
|
4017
4120
|
valid,
|
|
4018
4121
|
...reason ? { reason } : {},
|
|
@@ -4051,14 +4154,14 @@ function saveLicense(envelope, opts2 = {}) {
|
|
|
4051
4154
|
throw new LicenseStoreError(`License not saved: ${term.detail}`);
|
|
4052
4155
|
}
|
|
4053
4156
|
const dir = licensesDir(opts2);
|
|
4054
|
-
const filePath =
|
|
4157
|
+
const filePath = path5.join(dir, `${licenseId}${FILE_SUFFIX}`);
|
|
4055
4158
|
try {
|
|
4056
|
-
|
|
4057
|
-
const tmp =
|
|
4058
|
-
|
|
4159
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
4160
|
+
const tmp = path5.join(dir, `.${licenseId}.${process.pid}.tmp`);
|
|
4161
|
+
fs6.writeFileSync(tmp, JSON.stringify(envelope, null, 2) + "\n", {
|
|
4059
4162
|
mode: 384
|
|
4060
4163
|
});
|
|
4061
|
-
|
|
4164
|
+
fs6.renameSync(tmp, filePath);
|
|
4062
4165
|
} catch (err2) {
|
|
4063
4166
|
throw new LicenseStoreError(
|
|
4064
4167
|
`Could not write license to ${filePath}: ${err2 instanceof Error ? err2.message : String(err2)}`,
|
|
@@ -4070,7 +4173,7 @@ function saveLicense(envelope, opts2 = {}) {
|
|
|
4070
4173
|
function readEnvelope(filePath) {
|
|
4071
4174
|
let text2;
|
|
4072
4175
|
try {
|
|
4073
|
-
text2 =
|
|
4176
|
+
text2 = fs6.readFileSync(filePath, "utf-8");
|
|
4074
4177
|
} catch (err2) {
|
|
4075
4178
|
return {
|
|
4076
4179
|
error: `unreadable: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
@@ -4089,11 +4192,11 @@ function readEnvelope(filePath) {
|
|
|
4089
4192
|
function listLicenses(opts2 = {}) {
|
|
4090
4193
|
const dir = licensesDir(opts2);
|
|
4091
4194
|
const now = opts2.now ?? /* @__PURE__ */ new Date();
|
|
4092
|
-
if (!
|
|
4195
|
+
if (!fs6.existsSync(dir)) return [];
|
|
4093
4196
|
const out = [];
|
|
4094
|
-
for (const file of
|
|
4197
|
+
for (const file of fs6.readdirSync(dir).sort()) {
|
|
4095
4198
|
if (!file.endsWith(FILE_SUFFIX)) continue;
|
|
4096
|
-
const filePath =
|
|
4199
|
+
const filePath = path5.join(dir, file);
|
|
4097
4200
|
const read = readEnvelope(filePath);
|
|
4098
4201
|
if ("error" in read) {
|
|
4099
4202
|
out.push(buildInfo({}, filePath, false, read.error));
|
|
@@ -4120,10 +4223,10 @@ function listLicenses(opts2 = {}) {
|
|
|
4120
4223
|
function findEntitledLicense(entitlement, opts2 = {}) {
|
|
4121
4224
|
const dir = licensesDir(opts2);
|
|
4122
4225
|
const now = opts2.now ?? /* @__PURE__ */ new Date();
|
|
4123
|
-
if (!
|
|
4124
|
-
for (const file of
|
|
4226
|
+
if (!fs6.existsSync(dir)) return null;
|
|
4227
|
+
for (const file of fs6.readdirSync(dir).sort()) {
|
|
4125
4228
|
if (!file.endsWith(FILE_SUFFIX)) continue;
|
|
4126
|
-
const filePath =
|
|
4229
|
+
const filePath = path5.join(dir, file);
|
|
4127
4230
|
const read = readEnvelope(filePath);
|
|
4128
4231
|
if ("error" in read) continue;
|
|
4129
4232
|
try {
|
|
@@ -4149,10 +4252,10 @@ function findEntitledLicense(entitlement, opts2 = {}) {
|
|
|
4149
4252
|
}
|
|
4150
4253
|
function removeLicense(licenseId, opts2 = {}) {
|
|
4151
4254
|
if (!SAFE_ID.test(licenseId)) return false;
|
|
4152
|
-
const filePath =
|
|
4153
|
-
if (!
|
|
4255
|
+
const filePath = path5.join(licensesDir(opts2), `${licenseId}${FILE_SUFFIX}`);
|
|
4256
|
+
if (!fs6.existsSync(filePath)) return false;
|
|
4154
4257
|
try {
|
|
4155
|
-
|
|
4258
|
+
fs6.rmSync(filePath);
|
|
4156
4259
|
} catch (err2) {
|
|
4157
4260
|
throw new LicenseStoreError(
|
|
4158
4261
|
`Could not remove license ${licenseId}: ${err2 instanceof Error ? err2.message : String(err2)}`,
|
|
@@ -4211,8 +4314,8 @@ __export(compose_integration_exports, {
|
|
|
4211
4314
|
extractAppIdFromArtifactId: () => extractAppIdFromArtifactId,
|
|
4212
4315
|
upsertAppManifest: () => upsertAppManifest
|
|
4213
4316
|
});
|
|
4214
|
-
import
|
|
4215
|
-
import
|
|
4317
|
+
import fs7 from "fs";
|
|
4318
|
+
import path6 from "path";
|
|
4216
4319
|
import yaml3 from "js-yaml";
|
|
4217
4320
|
import { eq as eq3 } from "drizzle-orm";
|
|
4218
4321
|
function titleCase(slug) {
|
|
@@ -4233,10 +4336,10 @@ async function ensureAppProject(appId, appsDir = getAinativeAppsDir()) {
|
|
|
4233
4336
|
return { projectId: appId, created: true };
|
|
4234
4337
|
}
|
|
4235
4338
|
function resolveAppName(appId, appsDir) {
|
|
4236
|
-
const manifestPath =
|
|
4237
|
-
if (
|
|
4339
|
+
const manifestPath = path6.join(appsDir, appId, "manifest.yaml");
|
|
4340
|
+
if (fs7.existsSync(manifestPath)) {
|
|
4238
4341
|
try {
|
|
4239
|
-
const parsed = yaml3.load(
|
|
4342
|
+
const parsed = yaml3.load(fs7.readFileSync(manifestPath, "utf-8"));
|
|
4240
4343
|
const result = AppManifestSchema.safeParse(parsed);
|
|
4241
4344
|
if (result.success) return result.data.name;
|
|
4242
4345
|
} catch {
|
|
@@ -4245,13 +4348,13 @@ function resolveAppName(appId, appsDir) {
|
|
|
4245
4348
|
return titleCase(appId);
|
|
4246
4349
|
}
|
|
4247
4350
|
function upsertAppManifest(appId, artifact, displayName, appsDir = getAinativeAppsDir()) {
|
|
4248
|
-
const appDir2 =
|
|
4249
|
-
const manifestPath =
|
|
4250
|
-
|
|
4351
|
+
const appDir2 = path6.join(appsDir, appId);
|
|
4352
|
+
const manifestPath = path6.join(appDir2, "manifest.yaml");
|
|
4353
|
+
fs7.mkdirSync(appDir2, { recursive: true });
|
|
4251
4354
|
let manifest = emptyManifest(appId, displayName);
|
|
4252
|
-
if (
|
|
4355
|
+
if (fs7.existsSync(manifestPath)) {
|
|
4253
4356
|
try {
|
|
4254
|
-
const parsed = yaml3.load(
|
|
4357
|
+
const parsed = yaml3.load(fs7.readFileSync(manifestPath, "utf-8"));
|
|
4255
4358
|
const result = AppManifestSchema.safeParse(parsed);
|
|
4256
4359
|
if (result.success) manifest = result.data;
|
|
4257
4360
|
} catch {
|
|
@@ -4266,7 +4369,7 @@ function upsertAppManifest(appId, artifact, displayName, appsDir = getAinativeAp
|
|
|
4266
4369
|
if (artifact.runs) entry.runs = artifact.runs;
|
|
4267
4370
|
arr.push(entry);
|
|
4268
4371
|
}
|
|
4269
|
-
|
|
4372
|
+
fs7.writeFileSync(manifestPath, yaml3.dump(manifest));
|
|
4270
4373
|
invalidateAppsCache();
|
|
4271
4374
|
return manifest;
|
|
4272
4375
|
}
|
|
@@ -4622,8 +4725,8 @@ var init_blueprint = __esm({
|
|
|
4622
4725
|
});
|
|
4623
4726
|
|
|
4624
4727
|
// src/lib/agents/runtime/catalog.ts
|
|
4625
|
-
var
|
|
4626
|
-
__export(
|
|
4728
|
+
var catalog_exports2 = {};
|
|
4729
|
+
__export(catalog_exports2, {
|
|
4627
4730
|
DEFAULT_AGENT_RUNTIME: () => DEFAULT_AGENT_RUNTIME,
|
|
4628
4731
|
SUPPORTED_AGENT_RUNTIMES: () => SUPPORTED_AGENT_RUNTIMES,
|
|
4629
4732
|
getRuntimeCapabilities: () => getRuntimeCapabilities,
|
|
@@ -4655,7 +4758,7 @@ function listRuntimeCatalog() {
|
|
|
4655
4758
|
return SUPPORTED_AGENT_RUNTIMES.map((runtimeId) => RUNTIME_CATALOG[runtimeId]);
|
|
4656
4759
|
}
|
|
4657
4760
|
var SUPPORTED_AGENT_RUNTIMES, DEFAULT_AGENT_RUNTIME, RUNTIME_CATALOG;
|
|
4658
|
-
var
|
|
4761
|
+
var init_catalog2 = __esm({
|
|
4659
4762
|
"src/lib/agents/runtime/catalog.ts"() {
|
|
4660
4763
|
"use strict";
|
|
4661
4764
|
SUPPORTED_AGENT_RUNTIMES = [
|
|
@@ -4869,7 +4972,7 @@ var runtimeIdSchema, profileTestsSchema, canUseToolPolicySchema, profileRuntimeO
|
|
|
4869
4972
|
var init_profile = __esm({
|
|
4870
4973
|
"src/lib/validators/profile.ts"() {
|
|
4871
4974
|
"use strict";
|
|
4872
|
-
|
|
4975
|
+
init_catalog2();
|
|
4873
4976
|
runtimeIdSchema = z5.enum(SUPPORTED_AGENT_RUNTIMES);
|
|
4874
4977
|
profileTestsSchema = z5.array(
|
|
4875
4978
|
z5.object({
|
|
@@ -4991,29 +5094,29 @@ function resolveProfileRuntimePayload(profile, runtimeId) {
|
|
|
4991
5094
|
var init_compatibility = __esm({
|
|
4992
5095
|
"src/lib/agents/profiles/compatibility.ts"() {
|
|
4993
5096
|
"use strict";
|
|
4994
|
-
|
|
5097
|
+
init_catalog2();
|
|
4995
5098
|
}
|
|
4996
5099
|
});
|
|
4997
5100
|
|
|
4998
5101
|
// src/lib/agents/profiles/project-profiles.ts
|
|
4999
|
-
import
|
|
5000
|
-
import
|
|
5102
|
+
import fs8 from "fs";
|
|
5103
|
+
import path7 from "path";
|
|
5001
5104
|
import yaml4 from "js-yaml";
|
|
5002
5105
|
function getProjectSkillsSignature(skillsDir) {
|
|
5003
|
-
if (!
|
|
5004
|
-
const entries =
|
|
5106
|
+
if (!fs8.existsSync(skillsDir)) return "missing";
|
|
5107
|
+
const entries = fs8.readdirSync(skillsDir, { withFileTypes: true }).filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name));
|
|
5005
5108
|
const parts = [];
|
|
5006
5109
|
for (const entry of entries) {
|
|
5007
|
-
const dir =
|
|
5110
|
+
const dir = path7.join(skillsDir, entry.name);
|
|
5008
5111
|
parts.push(entry.name);
|
|
5009
|
-
const yamlPath =
|
|
5010
|
-
if (
|
|
5011
|
-
const s =
|
|
5112
|
+
const yamlPath = path7.join(dir, "profile.yaml");
|
|
5113
|
+
if (fs8.existsSync(yamlPath)) {
|
|
5114
|
+
const s = fs8.statSync(yamlPath);
|
|
5012
5115
|
parts.push(`yaml:${s.mtimeMs}:${s.size}`);
|
|
5013
5116
|
}
|
|
5014
|
-
const skillPath =
|
|
5015
|
-
if (
|
|
5016
|
-
const s =
|
|
5117
|
+
const skillPath = path7.join(dir, "SKILL.md");
|
|
5118
|
+
if (fs8.existsSync(skillPath)) {
|
|
5119
|
+
const s = fs8.statSync(skillPath);
|
|
5017
5120
|
parts.push(`skill:${s.mtimeMs}:${s.size}`);
|
|
5018
5121
|
}
|
|
5019
5122
|
}
|
|
@@ -5034,8 +5137,8 @@ function parseFrontmatter(content) {
|
|
|
5034
5137
|
return fm;
|
|
5035
5138
|
}
|
|
5036
5139
|
function generateMinimalProfile(skillDir, dirName, projectDir) {
|
|
5037
|
-
const skillPath =
|
|
5038
|
-
const skillMd =
|
|
5140
|
+
const skillPath = path7.join(skillDir, "SKILL.md");
|
|
5141
|
+
const skillMd = fs8.readFileSync(skillPath, "utf-8");
|
|
5039
5142
|
const fm = parseFrontmatter(skillMd);
|
|
5040
5143
|
return {
|
|
5041
5144
|
id: dirName,
|
|
@@ -5052,20 +5155,20 @@ function generateMinimalProfile(skillDir, dirName, projectDir) {
|
|
|
5052
5155
|
};
|
|
5053
5156
|
}
|
|
5054
5157
|
function scanProjectProfiles(projectDir) {
|
|
5055
|
-
const skillsDir =
|
|
5056
|
-
if (!
|
|
5158
|
+
const skillsDir = path7.join(projectDir, ".claude", "skills");
|
|
5159
|
+
if (!fs8.existsSync(skillsDir)) return [];
|
|
5057
5160
|
const signature = getProjectSkillsSignature(skillsDir);
|
|
5058
5161
|
const cached = projectProfileCache.get(projectDir);
|
|
5059
5162
|
if (cached && cached.signature === signature) return cached.profiles;
|
|
5060
5163
|
const profiles = [];
|
|
5061
|
-
for (const entry of
|
|
5164
|
+
for (const entry of fs8.readdirSync(skillsDir, { withFileTypes: true })) {
|
|
5062
5165
|
if (!entry.isDirectory()) continue;
|
|
5063
|
-
const dir =
|
|
5064
|
-
const yamlPath =
|
|
5065
|
-
const skillPath =
|
|
5066
|
-
if (
|
|
5166
|
+
const dir = path7.join(skillsDir, entry.name);
|
|
5167
|
+
const yamlPath = path7.join(dir, "profile.yaml");
|
|
5168
|
+
const skillPath = path7.join(dir, "SKILL.md");
|
|
5169
|
+
if (fs8.existsSync(yamlPath) && fs8.existsSync(skillPath)) {
|
|
5067
5170
|
try {
|
|
5068
|
-
const rawYaml =
|
|
5171
|
+
const rawYaml = fs8.readFileSync(yamlPath, "utf-8");
|
|
5069
5172
|
const parsed = yaml4.load(rawYaml);
|
|
5070
5173
|
const result = ProfileConfigSchema.safeParse(parsed);
|
|
5071
5174
|
if (!result.success) {
|
|
@@ -5076,7 +5179,7 @@ function scanProjectProfiles(projectDir) {
|
|
|
5076
5179
|
continue;
|
|
5077
5180
|
}
|
|
5078
5181
|
const config = result.data;
|
|
5079
|
-
const skillMd =
|
|
5182
|
+
const skillMd = fs8.readFileSync(skillPath, "utf-8");
|
|
5080
5183
|
const descMatch = skillMd.match(
|
|
5081
5184
|
/^---\s*\n[\s\S]*?description:\s*(.+?)\s*\n[\s\S]*?---/
|
|
5082
5185
|
);
|
|
@@ -5110,7 +5213,7 @@ function scanProjectProfiles(projectDir) {
|
|
|
5110
5213
|
err2
|
|
5111
5214
|
);
|
|
5112
5215
|
}
|
|
5113
|
-
} else if (
|
|
5216
|
+
} else if (fs8.existsSync(skillPath)) {
|
|
5114
5217
|
try {
|
|
5115
5218
|
profiles.push(generateMinimalProfile(dir, entry.name, projectDir));
|
|
5116
5219
|
} catch (err2) {
|
|
@@ -5136,7 +5239,7 @@ var init_project_profiles = __esm({
|
|
|
5136
5239
|
|
|
5137
5240
|
// src/lib/environment/profile-linker.ts
|
|
5138
5241
|
import { eq as eq6, and as and2, isNull } from "drizzle-orm";
|
|
5139
|
-
import
|
|
5242
|
+
import path8 from "path";
|
|
5140
5243
|
var init_profile_linker = __esm({
|
|
5141
5244
|
"src/lib/environment/profile-linker.ts"() {
|
|
5142
5245
|
"use strict";
|
|
@@ -5187,23 +5290,23 @@ var init_data = __esm({
|
|
|
5187
5290
|
});
|
|
5188
5291
|
|
|
5189
5292
|
// src/lib/agents/profiles/app-manifest-source.ts
|
|
5190
|
-
import
|
|
5191
|
-
import
|
|
5293
|
+
import fs9 from "fs";
|
|
5294
|
+
import path9 from "path";
|
|
5192
5295
|
import yaml5 from "js-yaml";
|
|
5193
5296
|
function titleCase2(slug) {
|
|
5194
5297
|
return slug.split("-").filter(Boolean).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
|
|
5195
5298
|
}
|
|
5196
5299
|
function loadAppManifestProfiles(appsDir, profilesDir, builtinsDir) {
|
|
5197
|
-
if (!
|
|
5300
|
+
if (!fs9.existsSync(appsDir)) return [];
|
|
5198
5301
|
const synthesized = /* @__PURE__ */ new Map();
|
|
5199
|
-
for (const entry of
|
|
5302
|
+
for (const entry of fs9.readdirSync(appsDir, { withFileTypes: true })) {
|
|
5200
5303
|
if (!entry.isDirectory()) continue;
|
|
5201
5304
|
const appId = entry.name;
|
|
5202
|
-
const manifestPath =
|
|
5203
|
-
if (!
|
|
5305
|
+
const manifestPath = path9.join(appsDir, appId, "manifest.yaml");
|
|
5306
|
+
if (!fs9.existsSync(manifestPath)) continue;
|
|
5204
5307
|
let manifest;
|
|
5205
5308
|
try {
|
|
5206
|
-
const parsed = yaml5.load(
|
|
5309
|
+
const parsed = yaml5.load(fs9.readFileSync(manifestPath, "utf-8"));
|
|
5207
5310
|
manifest = AppManifestSchema.safeParse(parsed);
|
|
5208
5311
|
} catch (err2) {
|
|
5209
5312
|
console.warn(`[app-manifest-source] Malformed manifest for ${appId}:`, err2);
|
|
@@ -5215,9 +5318,9 @@ function loadAppManifestProfiles(appsDir, profilesDir, builtinsDir) {
|
|
|
5215
5318
|
}
|
|
5216
5319
|
for (const profileRef of manifest.data.profiles ?? []) {
|
|
5217
5320
|
const profileId = profileRef.id;
|
|
5218
|
-
const userYaml =
|
|
5219
|
-
const builtinYaml =
|
|
5220
|
-
if (
|
|
5321
|
+
const userYaml = path9.join(profilesDir, profileId, "profile.yaml");
|
|
5322
|
+
const builtinYaml = path9.join(builtinsDir, profileId, "profile.yaml");
|
|
5323
|
+
if (fs9.existsSync(userYaml) || fs9.existsSync(builtinYaml)) continue;
|
|
5221
5324
|
const existing = synthesized.get(profileId);
|
|
5222
5325
|
if (existing) {
|
|
5223
5326
|
if (!existing.tags.includes(appId)) {
|
|
@@ -5248,7 +5351,7 @@ function loadAppManifestProfiles(appsDir, profilesDir, builtinsDir) {
|
|
|
5248
5351
|
var init_app_manifest_source = __esm({
|
|
5249
5352
|
"src/lib/agents/profiles/app-manifest-source.ts"() {
|
|
5250
5353
|
"use strict";
|
|
5251
|
-
|
|
5354
|
+
init_catalog2();
|
|
5252
5355
|
init_registry();
|
|
5253
5356
|
}
|
|
5254
5357
|
});
|
|
@@ -5273,29 +5376,29 @@ __export(registry_exports2, {
|
|
|
5273
5376
|
scanProfilesIntoMap: () => scanProfilesIntoMap,
|
|
5274
5377
|
updateProfile: () => updateProfile
|
|
5275
5378
|
});
|
|
5276
|
-
import
|
|
5379
|
+
import fs10 from "fs";
|
|
5277
5380
|
import { homedir as homedir3 } from "os";
|
|
5278
|
-
import
|
|
5381
|
+
import path10 from "path";
|
|
5279
5382
|
import yaml6 from "js-yaml";
|
|
5280
5383
|
import { eq as eq8, and as and4 } from "drizzle-orm";
|
|
5281
5384
|
function getBuiltinsDir() {
|
|
5282
5385
|
return BUILTINS_DIR;
|
|
5283
5386
|
}
|
|
5284
5387
|
function getDirectorySignatureParts(baseDir) {
|
|
5285
|
-
if (!
|
|
5286
|
-
const entries =
|
|
5388
|
+
if (!fs10.existsSync(baseDir)) return [];
|
|
5389
|
+
const entries = fs10.readdirSync(baseDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).sort((a, b) => a.name.localeCompare(b.name));
|
|
5287
5390
|
const parts = [];
|
|
5288
5391
|
for (const entry of entries) {
|
|
5289
|
-
const dir =
|
|
5290
|
-
const yamlPath =
|
|
5291
|
-
const skillPath =
|
|
5392
|
+
const dir = path10.join(baseDir, entry.name);
|
|
5393
|
+
const yamlPath = path10.join(dir, "profile.yaml");
|
|
5394
|
+
const skillPath = path10.join(dir, "SKILL.md");
|
|
5292
5395
|
parts.push(entry.name);
|
|
5293
|
-
if (
|
|
5294
|
-
const stats =
|
|
5396
|
+
if (fs10.existsSync(yamlPath)) {
|
|
5397
|
+
const stats = fs10.statSync(yamlPath);
|
|
5295
5398
|
parts.push(`yaml:${stats.mtimeMs}:${stats.size}`);
|
|
5296
5399
|
}
|
|
5297
|
-
if (
|
|
5298
|
-
const stats =
|
|
5400
|
+
if (fs10.existsSync(skillPath)) {
|
|
5401
|
+
const stats = fs10.statSync(skillPath);
|
|
5299
5402
|
parts.push(`skill:${stats.mtimeMs}:${stats.size}`);
|
|
5300
5403
|
}
|
|
5301
5404
|
}
|
|
@@ -5303,14 +5406,14 @@ function getDirectorySignatureParts(baseDir) {
|
|
|
5303
5406
|
}
|
|
5304
5407
|
function getAppsDirectorySignature() {
|
|
5305
5408
|
const appsDir = getAinativeAppsDir();
|
|
5306
|
-
if (!
|
|
5409
|
+
if (!fs10.existsSync(appsDir)) return "no-apps";
|
|
5307
5410
|
const parts = [];
|
|
5308
|
-
const entries =
|
|
5411
|
+
const entries = fs10.readdirSync(appsDir, { withFileTypes: true }).filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name));
|
|
5309
5412
|
for (const entry of entries) {
|
|
5310
|
-
const manifestPath =
|
|
5413
|
+
const manifestPath = path10.join(appsDir, entry.name, "manifest.yaml");
|
|
5311
5414
|
parts.push(entry.name);
|
|
5312
|
-
if (
|
|
5313
|
-
const stats =
|
|
5415
|
+
if (fs10.existsSync(manifestPath)) {
|
|
5416
|
+
const stats = fs10.statSync(manifestPath);
|
|
5314
5417
|
parts.push(`manifest:${stats.mtimeMs}:${stats.size}`);
|
|
5315
5418
|
}
|
|
5316
5419
|
}
|
|
@@ -5333,17 +5436,17 @@ function getSkillsDirectorySignature() {
|
|
|
5333
5436
|
}
|
|
5334
5437
|
function ensureBuiltins() {
|
|
5335
5438
|
const builtinsDir = getBuiltinsDir();
|
|
5336
|
-
if (!
|
|
5337
|
-
|
|
5338
|
-
for (const entry of
|
|
5439
|
+
if (!fs10.existsSync(builtinsDir)) return;
|
|
5440
|
+
fs10.mkdirSync(SKILLS_DIR, { recursive: true });
|
|
5441
|
+
for (const entry of fs10.readdirSync(builtinsDir, { withFileTypes: true })) {
|
|
5339
5442
|
if (!entry.isDirectory()) continue;
|
|
5340
|
-
const targetDir =
|
|
5341
|
-
const targetYaml =
|
|
5342
|
-
const srcYaml =
|
|
5343
|
-
if (
|
|
5443
|
+
const targetDir = path10.join(SKILLS_DIR, entry.name);
|
|
5444
|
+
const targetYaml = path10.join(targetDir, "profile.yaml");
|
|
5445
|
+
const srcYaml = path10.join(builtinsDir, entry.name, "profile.yaml");
|
|
5446
|
+
if (fs10.existsSync(targetYaml)) {
|
|
5344
5447
|
try {
|
|
5345
|
-
const source = yaml6.load(
|
|
5346
|
-
const target = yaml6.load(
|
|
5448
|
+
const source = yaml6.load(fs10.readFileSync(srcYaml, "utf-8")) ?? {};
|
|
5449
|
+
const target = yaml6.load(fs10.readFileSync(targetYaml, "utf-8")) ?? {};
|
|
5347
5450
|
let changed = false;
|
|
5348
5451
|
if (source.supportedRuntimes !== void 0 && target.supportedRuntimes === void 0) {
|
|
5349
5452
|
target.supportedRuntimes = source.supportedRuntimes;
|
|
@@ -5362,29 +5465,29 @@ function ensureBuiltins() {
|
|
|
5362
5465
|
changed = true;
|
|
5363
5466
|
}
|
|
5364
5467
|
if (changed) {
|
|
5365
|
-
|
|
5468
|
+
fs10.writeFileSync(targetYaml, yaml6.dump(target));
|
|
5366
5469
|
}
|
|
5367
5470
|
} catch {
|
|
5368
5471
|
}
|
|
5369
5472
|
continue;
|
|
5370
5473
|
}
|
|
5371
|
-
|
|
5372
|
-
const srcDir =
|
|
5373
|
-
for (const file of
|
|
5374
|
-
|
|
5474
|
+
fs10.mkdirSync(targetDir, { recursive: true });
|
|
5475
|
+
const srcDir = path10.join(builtinsDir, entry.name);
|
|
5476
|
+
for (const file of fs10.readdirSync(srcDir)) {
|
|
5477
|
+
fs10.copyFileSync(path10.join(srcDir, file), path10.join(targetDir, file));
|
|
5375
5478
|
}
|
|
5376
5479
|
}
|
|
5377
5480
|
}
|
|
5378
5481
|
function scanProfilesFromDir(baseDir, profiles, options = {}) {
|
|
5379
|
-
if (!
|
|
5380
|
-
for (const entry of
|
|
5482
|
+
if (!fs10.existsSync(baseDir)) return;
|
|
5483
|
+
for (const entry of fs10.readdirSync(baseDir, { withFileTypes: true })) {
|
|
5381
5484
|
if (!entry.isDirectory()) continue;
|
|
5382
|
-
const dir =
|
|
5383
|
-
const yamlPath =
|
|
5384
|
-
const skillPath =
|
|
5385
|
-
if (!
|
|
5485
|
+
const dir = path10.join(baseDir, entry.name);
|
|
5486
|
+
const yamlPath = path10.join(dir, "profile.yaml");
|
|
5487
|
+
const skillPath = path10.join(dir, "SKILL.md");
|
|
5488
|
+
if (!fs10.existsSync(yamlPath)) continue;
|
|
5386
5489
|
try {
|
|
5387
|
-
const rawYaml =
|
|
5490
|
+
const rawYaml = fs10.readFileSync(yamlPath, "utf-8");
|
|
5388
5491
|
const parsed = yaml6.load(rawYaml);
|
|
5389
5492
|
const result = ProfileConfigSchema.safeParse(parsed);
|
|
5390
5493
|
if (!result.success) {
|
|
@@ -5395,7 +5498,7 @@ function scanProfilesFromDir(baseDir, profiles, options = {}) {
|
|
|
5395
5498
|
continue;
|
|
5396
5499
|
}
|
|
5397
5500
|
const config = result.data;
|
|
5398
|
-
const skillMd =
|
|
5501
|
+
const skillMd = fs10.existsSync(skillPath) ? fs10.readFileSync(skillPath, "utf-8") : "";
|
|
5399
5502
|
const descMatch = skillMd.match(
|
|
5400
5503
|
/^---\s*\n[\s\S]*?description:\s*(.+?)\s*\n[\s\S]*?---/
|
|
5401
5504
|
);
|
|
@@ -5485,20 +5588,20 @@ function reloadProfiles() {
|
|
|
5485
5588
|
profileCacheSignature = null;
|
|
5486
5589
|
}
|
|
5487
5590
|
function isBuiltin(id) {
|
|
5488
|
-
return
|
|
5591
|
+
return fs10.existsSync(path10.join(getBuiltinsDir(), id, "profile.yaml"));
|
|
5489
5592
|
}
|
|
5490
5593
|
function createProfile(config, skillMd) {
|
|
5491
5594
|
const result = ProfileConfigSchema.safeParse(config);
|
|
5492
5595
|
if (!result.success) {
|
|
5493
5596
|
throw new Error(`Invalid profile: ${result.error.issues.map((i) => i.message).join(", ")}`);
|
|
5494
5597
|
}
|
|
5495
|
-
const dir =
|
|
5496
|
-
if (
|
|
5598
|
+
const dir = path10.join(SKILLS_DIR, config.id);
|
|
5599
|
+
if (fs10.existsSync(path10.join(dir, "profile.yaml"))) {
|
|
5497
5600
|
throw new Error(`Profile "${config.id}" already exists`);
|
|
5498
5601
|
}
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
|
|
5602
|
+
fs10.mkdirSync(dir, { recursive: true });
|
|
5603
|
+
fs10.writeFileSync(path10.join(dir, "profile.yaml"), yaml6.dump(config));
|
|
5604
|
+
fs10.writeFileSync(path10.join(dir, "SKILL.md"), skillMd);
|
|
5502
5605
|
reloadProfiles();
|
|
5503
5606
|
invalidateLatestScan();
|
|
5504
5607
|
}
|
|
@@ -5507,13 +5610,13 @@ function createPromotedProfile(config, skillMd) {
|
|
|
5507
5610
|
if (!result.success) {
|
|
5508
5611
|
throw new Error(`Invalid profile: ${result.error.issues.map((i) => i.message).join(", ")}`);
|
|
5509
5612
|
}
|
|
5510
|
-
const dir =
|
|
5511
|
-
if (
|
|
5613
|
+
const dir = path10.join(PROMOTED_PROFILES_DIR, config.id);
|
|
5614
|
+
if (fs10.existsSync(path10.join(dir, "profile.yaml"))) {
|
|
5512
5615
|
throw new Error(`Profile "${config.id}" already exists`);
|
|
5513
5616
|
}
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
|
|
5617
|
+
fs10.mkdirSync(dir, { recursive: true });
|
|
5618
|
+
fs10.writeFileSync(path10.join(dir, "profile.yaml"), yaml6.dump(config));
|
|
5619
|
+
fs10.writeFileSync(path10.join(dir, "SKILL.md"), skillMd);
|
|
5517
5620
|
reloadProfiles();
|
|
5518
5621
|
invalidateLatestScan();
|
|
5519
5622
|
}
|
|
@@ -5525,14 +5628,14 @@ function updateProfile(id, config, skillMd) {
|
|
|
5525
5628
|
if (!result.success) {
|
|
5526
5629
|
throw new Error(`Invalid profile: ${result.error.issues.map((i) => i.message).join(", ")}`);
|
|
5527
5630
|
}
|
|
5528
|
-
const skillsDir =
|
|
5529
|
-
const promotedDir =
|
|
5530
|
-
const dir =
|
|
5631
|
+
const skillsDir = path10.join(SKILLS_DIR, id);
|
|
5632
|
+
const promotedDir = path10.join(PROMOTED_PROFILES_DIR, id);
|
|
5633
|
+
const dir = fs10.existsSync(skillsDir) ? skillsDir : fs10.existsSync(promotedDir) ? promotedDir : null;
|
|
5531
5634
|
if (!dir) {
|
|
5532
5635
|
throw new Error(`Profile "${id}" not found`);
|
|
5533
5636
|
}
|
|
5534
|
-
|
|
5535
|
-
|
|
5637
|
+
fs10.writeFileSync(path10.join(dir, "profile.yaml"), yaml6.dump(config));
|
|
5638
|
+
fs10.writeFileSync(path10.join(dir, "SKILL.md"), skillMd);
|
|
5536
5639
|
reloadProfiles();
|
|
5537
5640
|
invalidateLatestScan();
|
|
5538
5641
|
}
|
|
@@ -5540,13 +5643,13 @@ function deleteProfile(id) {
|
|
|
5540
5643
|
if (isBuiltin(id)) {
|
|
5541
5644
|
throw new Error("Cannot delete built-in profiles");
|
|
5542
5645
|
}
|
|
5543
|
-
const skillsDir =
|
|
5544
|
-
const promotedDir =
|
|
5545
|
-
const dir =
|
|
5646
|
+
const skillsDir = path10.join(SKILLS_DIR, id);
|
|
5647
|
+
const promotedDir = path10.join(PROMOTED_PROFILES_DIR, id);
|
|
5648
|
+
const dir = fs10.existsSync(skillsDir) ? skillsDir : fs10.existsSync(promotedDir) ? promotedDir : null;
|
|
5546
5649
|
if (!dir) {
|
|
5547
5650
|
throw new Error(`Profile "${id}" not found`);
|
|
5548
5651
|
}
|
|
5549
|
-
|
|
5652
|
+
fs10.rmSync(dir, { recursive: true, force: true });
|
|
5550
5653
|
reloadProfiles();
|
|
5551
5654
|
invalidateLatestScan();
|
|
5552
5655
|
}
|
|
@@ -5630,7 +5733,7 @@ var init_registry2 = __esm({
|
|
|
5630
5733
|
init_ainative_paths();
|
|
5631
5734
|
init_app_manifest_source();
|
|
5632
5735
|
init_app_root();
|
|
5633
|
-
BUILTINS_DIR =
|
|
5736
|
+
BUILTINS_DIR = path10.resolve(
|
|
5634
5737
|
getAppRoot(import.meta.dirname, 4),
|
|
5635
5738
|
"src",
|
|
5636
5739
|
"lib",
|
|
@@ -5638,7 +5741,7 @@ var init_registry2 = __esm({
|
|
|
5638
5741
|
"profiles",
|
|
5639
5742
|
"builtins"
|
|
5640
5743
|
);
|
|
5641
|
-
SKILLS_DIR =
|
|
5744
|
+
SKILLS_DIR = path10.join(
|
|
5642
5745
|
process.env.HOME ?? process.env.USERPROFILE ?? homedir3(),
|
|
5643
5746
|
".claude",
|
|
5644
5747
|
"skills"
|
|
@@ -5666,16 +5769,16 @@ __export(registry_exports3, {
|
|
|
5666
5769
|
reloadBlueprints: () => reloadBlueprints,
|
|
5667
5770
|
validateBlueprintRefs: () => validateBlueprintRefs
|
|
5668
5771
|
});
|
|
5669
|
-
import
|
|
5670
|
-
import
|
|
5772
|
+
import fs11 from "fs";
|
|
5773
|
+
import path11 from "path";
|
|
5671
5774
|
import yaml7 from "js-yaml";
|
|
5672
5775
|
function scanDirectory(dir, isBuiltin2) {
|
|
5673
5776
|
const blueprints = /* @__PURE__ */ new Map();
|
|
5674
|
-
if (!
|
|
5675
|
-
for (const file of
|
|
5777
|
+
if (!fs11.existsSync(dir)) return blueprints;
|
|
5778
|
+
for (const file of fs11.readdirSync(dir)) {
|
|
5676
5779
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml")) continue;
|
|
5677
5780
|
try {
|
|
5678
|
-
const content =
|
|
5781
|
+
const content = fs11.readFileSync(path11.join(dir, file), "utf-8");
|
|
5679
5782
|
const parsed = yaml7.load(content);
|
|
5680
5783
|
const result = BlueprintSchema.safeParse(parsed);
|
|
5681
5784
|
if (!result.success) {
|
|
@@ -5729,12 +5832,12 @@ function createBlueprint(yamlContent) {
|
|
|
5729
5832
|
`Invalid blueprint: ${result.error.issues.map((i) => i.message).join(", ")}`
|
|
5730
5833
|
);
|
|
5731
5834
|
}
|
|
5732
|
-
|
|
5733
|
-
const filePath =
|
|
5734
|
-
if (
|
|
5835
|
+
fs11.mkdirSync(USER_BLUEPRINTS_DIR, { recursive: true });
|
|
5836
|
+
const filePath = path11.join(USER_BLUEPRINTS_DIR, `${result.data.id}.yaml`);
|
|
5837
|
+
if (fs11.existsSync(filePath)) {
|
|
5735
5838
|
throw new Error(`Blueprint "${result.data.id}" already exists`);
|
|
5736
5839
|
}
|
|
5737
|
-
|
|
5840
|
+
fs11.writeFileSync(filePath, yamlContent);
|
|
5738
5841
|
reloadBlueprints();
|
|
5739
5842
|
return { ...result.data, isBuiltin: false };
|
|
5740
5843
|
}
|
|
@@ -5742,11 +5845,11 @@ function deleteBlueprint(id) {
|
|
|
5742
5845
|
if (isBuiltinBlueprint(id)) {
|
|
5743
5846
|
throw new Error("Cannot delete built-in blueprints");
|
|
5744
5847
|
}
|
|
5745
|
-
const filePath =
|
|
5746
|
-
if (!
|
|
5848
|
+
const filePath = path11.join(USER_BLUEPRINTS_DIR, `${id}.yaml`);
|
|
5849
|
+
if (!fs11.existsSync(filePath)) {
|
|
5747
5850
|
throw new Error(`Blueprint "${id}" not found`);
|
|
5748
5851
|
}
|
|
5749
|
-
|
|
5852
|
+
fs11.unlinkSync(filePath);
|
|
5750
5853
|
reloadBlueprints();
|
|
5751
5854
|
}
|
|
5752
5855
|
function getUserBlueprintsDir() {
|
|
@@ -5805,7 +5908,7 @@ var init_registry3 = __esm({
|
|
|
5805
5908
|
init_ainative_paths();
|
|
5806
5909
|
init_app_root();
|
|
5807
5910
|
init_registry2();
|
|
5808
|
-
BUILTINS_DIR2 =
|
|
5911
|
+
BUILTINS_DIR2 = path11.resolve(
|
|
5809
5912
|
getAppRoot(import.meta.dirname, 4),
|
|
5810
5913
|
"src",
|
|
5811
5914
|
"lib",
|
|
@@ -6667,18 +6770,18 @@ var init_processor = __esm({
|
|
|
6667
6770
|
});
|
|
6668
6771
|
|
|
6669
6772
|
// src/lib/documents/output-scanner.ts
|
|
6670
|
-
import
|
|
6671
|
-
import
|
|
6773
|
+
import path12 from "path";
|
|
6774
|
+
import fs12 from "fs/promises";
|
|
6672
6775
|
import { and as and6, eq as eq14 } from "drizzle-orm";
|
|
6673
6776
|
function getTaskOutputDirectory(taskId) {
|
|
6674
|
-
return
|
|
6777
|
+
return path12.join(TASK_OUTPUTS_DIR, taskId);
|
|
6675
6778
|
}
|
|
6676
6779
|
async function prepareTaskOutputDirectory(taskId, options = {}) {
|
|
6677
6780
|
const outputDir = getTaskOutputDirectory(taskId);
|
|
6678
6781
|
if (options.clearExisting) {
|
|
6679
|
-
await
|
|
6782
|
+
await fs12.rm(outputDir, { recursive: true, force: true });
|
|
6680
6783
|
}
|
|
6681
|
-
await
|
|
6784
|
+
await fs12.mkdir(outputDir, { recursive: true });
|
|
6682
6785
|
return outputDir;
|
|
6683
6786
|
}
|
|
6684
6787
|
function buildTaskOutputInstructions(taskId) {
|
|
@@ -6691,10 +6794,10 @@ function buildTaskOutputInstructions(taskId) {
|
|
|
6691
6794
|
].join("\n");
|
|
6692
6795
|
}
|
|
6693
6796
|
async function listFilesRecursively(rootDir) {
|
|
6694
|
-
const entries = await
|
|
6797
|
+
const entries = await fs12.readdir(rootDir, { withFileTypes: true });
|
|
6695
6798
|
const files = await Promise.all(
|
|
6696
6799
|
entries.map(async (entry) => {
|
|
6697
|
-
const resolved =
|
|
6800
|
+
const resolved = path12.join(rootDir, entry.name);
|
|
6698
6801
|
if (entry.isDirectory()) {
|
|
6699
6802
|
return listFilesRecursively(resolved);
|
|
6700
6803
|
}
|
|
@@ -6704,13 +6807,13 @@ async function listFilesRecursively(rootDir) {
|
|
|
6704
6807
|
return files.flat();
|
|
6705
6808
|
}
|
|
6706
6809
|
function resolveOutputMimeType(filename) {
|
|
6707
|
-
return OUTPUT_MIME_TYPES[
|
|
6810
|
+
return OUTPUT_MIME_TYPES[path12.extname(filename).toLowerCase()] ?? null;
|
|
6708
6811
|
}
|
|
6709
6812
|
function normalizeRelativePath(value) {
|
|
6710
|
-
return value.split(
|
|
6813
|
+
return value.split(path12.sep).join("/");
|
|
6711
6814
|
}
|
|
6712
6815
|
function buildArchivedFilename(relativePath, version) {
|
|
6713
|
-
const parsed =
|
|
6816
|
+
const parsed = path12.parse(relativePath);
|
|
6714
6817
|
const sanitizedBase = parsed.name.replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
6715
6818
|
const nestedPrefix = parsed.dir ? `${parsed.dir.replace(/[\\/]+/g, "__")}__` : "";
|
|
6716
6819
|
return `${nestedPrefix}${sanitizedBase || "output"}-v${version}${parsed.ext}`;
|
|
@@ -6722,7 +6825,7 @@ async function scanTaskOutputDocuments(taskId) {
|
|
|
6722
6825
|
throw new Error(`Task ${taskId} not found`);
|
|
6723
6826
|
}
|
|
6724
6827
|
try {
|
|
6725
|
-
await
|
|
6828
|
+
await fs12.access(outputDir);
|
|
6726
6829
|
} catch {
|
|
6727
6830
|
return [];
|
|
6728
6831
|
}
|
|
@@ -6742,22 +6845,22 @@ async function scanTaskOutputDocuments(taskId) {
|
|
|
6742
6845
|
const discoveredFiles = await listFilesRecursively(outputDir);
|
|
6743
6846
|
const registeredDocumentIds = [];
|
|
6744
6847
|
for (const sourcePath of discoveredFiles) {
|
|
6745
|
-
const relativePath = normalizeRelativePath(
|
|
6848
|
+
const relativePath = normalizeRelativePath(path12.relative(outputDir, sourcePath));
|
|
6746
6849
|
const mimeType = resolveOutputMimeType(relativePath);
|
|
6747
6850
|
if (!mimeType) {
|
|
6748
6851
|
continue;
|
|
6749
6852
|
}
|
|
6750
|
-
const stats = await
|
|
6853
|
+
const stats = await fs12.stat(sourcePath);
|
|
6751
6854
|
if (!stats.isFile()) {
|
|
6752
6855
|
continue;
|
|
6753
6856
|
}
|
|
6754
6857
|
const nextVersion = (versionMap.get(relativePath) ?? 0) + 1;
|
|
6755
6858
|
versionMap.set(relativePath, nextVersion);
|
|
6756
|
-
const archiveDir =
|
|
6757
|
-
await
|
|
6859
|
+
const archiveDir = path12.join(OUTPUT_ARCHIVE_DIR, taskId);
|
|
6860
|
+
await fs12.mkdir(archiveDir, { recursive: true });
|
|
6758
6861
|
const archivedFilename = buildArchivedFilename(relativePath, nextVersion);
|
|
6759
|
-
const archivedPath =
|
|
6760
|
-
await
|
|
6862
|
+
const archivedPath = path12.join(archiveDir, archivedFilename);
|
|
6863
|
+
await fs12.copyFile(sourcePath, archivedPath);
|
|
6761
6864
|
const documentId = crypto.randomUUID();
|
|
6762
6865
|
const now = /* @__PURE__ */ new Date();
|
|
6763
6866
|
await db.insert(documents).values({
|
|
@@ -6788,8 +6891,8 @@ var init_output_scanner = __esm({
|
|
|
6788
6891
|
init_schema();
|
|
6789
6892
|
init_env();
|
|
6790
6893
|
init_processor();
|
|
6791
|
-
TASK_OUTPUTS_DIR =
|
|
6792
|
-
OUTPUT_ARCHIVE_DIR =
|
|
6894
|
+
TASK_OUTPUTS_DIR = path12.join(dataDir(), "outputs");
|
|
6895
|
+
OUTPUT_ARCHIVE_DIR = path12.join(dataDir(), "documents", "output");
|
|
6793
6896
|
OUTPUT_MIME_TYPES = {
|
|
6794
6897
|
".md": "text/markdown",
|
|
6795
6898
|
".txt": "text/plain",
|
|
@@ -6849,7 +6952,7 @@ var CHAT_MODELS;
|
|
|
6849
6952
|
var init_types2 = __esm({
|
|
6850
6953
|
"src/lib/chat/types.ts"() {
|
|
6851
6954
|
"use strict";
|
|
6852
|
-
|
|
6955
|
+
init_catalog2();
|
|
6853
6956
|
CHAT_MODELS = [
|
|
6854
6957
|
// Anthropic — uses SDK short names
|
|
6855
6958
|
{ id: "haiku", label: "Haiku", provider: "anthropic", tier: "Fast", costLabel: "$" },
|
|
@@ -6861,7 +6964,7 @@ var init_types2 = __esm({
|
|
|
6861
6964
|
{ id: "gpt-5.4", label: "GPT-5.4", provider: "openai", tier: "Best", costLabel: "$$$" }
|
|
6862
6965
|
];
|
|
6863
6966
|
try {
|
|
6864
|
-
const { listRuntimeCatalog: listRuntimeCatalog2 } = (
|
|
6967
|
+
const { listRuntimeCatalog: listRuntimeCatalog2 } = (init_catalog2(), __toCommonJS(catalog_exports2));
|
|
6865
6968
|
const allSupportedModels = /* @__PURE__ */ new Set();
|
|
6866
6969
|
for (const runtime of listRuntimeCatalog2()) {
|
|
6867
6970
|
for (const model of runtime.models.supported) {
|
|
@@ -7920,7 +8023,7 @@ var init_ledger = __esm({
|
|
|
7920
8023
|
});
|
|
7921
8024
|
|
|
7922
8025
|
// src/lib/plugins/classify-trust.ts
|
|
7923
|
-
import
|
|
8026
|
+
import path13 from "path";
|
|
7924
8027
|
import os from "os";
|
|
7925
8028
|
function classifyPluginTrust(manifest, rootDir, opts2 = {}) {
|
|
7926
8029
|
if (manifest.kind === "primitives-bundle") return "self";
|
|
@@ -7934,9 +8037,9 @@ function classifyPluginTrust(manifest, rootDir, opts2 = {}) {
|
|
|
7934
8037
|
if (manifest.author === currentUser) return "self";
|
|
7935
8038
|
}
|
|
7936
8039
|
const appsBase = opts2.appsBaseDir ?? getAinativeAppsDir();
|
|
7937
|
-
const normalizedRoot =
|
|
7938
|
-
const normalizedApps =
|
|
7939
|
-
const sep =
|
|
8040
|
+
const normalizedRoot = path13.resolve(rootDir);
|
|
8041
|
+
const normalizedApps = path13.resolve(appsBase);
|
|
8042
|
+
const sep = path13.sep;
|
|
7940
8043
|
if (normalizedRoot === normalizedApps || normalizedRoot.startsWith(normalizedApps + sep)) {
|
|
7941
8044
|
return "self";
|
|
7942
8045
|
}
|
|
@@ -7957,15 +8060,15 @@ __export(transport_dispatch_exports, {
|
|
|
7957
8060
|
validateStdioMcp: () => validateStdioMcp
|
|
7958
8061
|
});
|
|
7959
8062
|
import { spawn } from "child_process";
|
|
7960
|
-
import
|
|
7961
|
-
import
|
|
8063
|
+
import fs13 from "fs";
|
|
8064
|
+
import path14 from "path";
|
|
7962
8065
|
import readline from "readline";
|
|
7963
8066
|
function logToFile2(line) {
|
|
7964
8067
|
try {
|
|
7965
8068
|
const logsDir = getAinativeLogsDir();
|
|
7966
|
-
|
|
7967
|
-
|
|
7968
|
-
|
|
8069
|
+
fs13.mkdirSync(logsDir, { recursive: true });
|
|
8070
|
+
fs13.appendFileSync(
|
|
8071
|
+
path14.join(logsDir, "plugins.log"),
|
|
7969
8072
|
`${(/* @__PURE__ */ new Date()).toISOString()} ${line}
|
|
7970
8073
|
`
|
|
7971
8074
|
);
|
|
@@ -8100,14 +8203,14 @@ async function validateInProcessSdk(config, pluginId, serverName) {
|
|
|
8100
8203
|
};
|
|
8101
8204
|
}
|
|
8102
8205
|
const absPath = config.entry;
|
|
8103
|
-
if (!
|
|
8206
|
+
if (!path14.isAbsolute(absPath)) {
|
|
8104
8207
|
return {
|
|
8105
8208
|
ok: false,
|
|
8106
8209
|
reason: "sdk_invalid_export",
|
|
8107
8210
|
detail: `entry must be absolute path, got: ${absPath}`
|
|
8108
8211
|
};
|
|
8109
8212
|
}
|
|
8110
|
-
const ext =
|
|
8213
|
+
const ext = path14.extname(absPath);
|
|
8111
8214
|
if (ext === ".ts") {
|
|
8112
8215
|
return {
|
|
8113
8216
|
ok: false,
|
|
@@ -8226,8 +8329,8 @@ __export(mcp_loader_exports, {
|
|
|
8226
8329
|
loadPluginMcpServers: () => loadPluginMcpServers,
|
|
8227
8330
|
reloadPluginMcpRegistrations: () => reloadPluginMcpRegistrations
|
|
8228
8331
|
});
|
|
8229
|
-
import
|
|
8230
|
-
import
|
|
8332
|
+
import fs14 from "fs";
|
|
8333
|
+
import path15 from "path";
|
|
8231
8334
|
import os2 from "os";
|
|
8232
8335
|
import yaml8 from "js-yaml";
|
|
8233
8336
|
function __resetDockerBootSweepForTests() {
|
|
@@ -8236,9 +8339,9 @@ function __resetDockerBootSweepForTests() {
|
|
|
8236
8339
|
function logToFile3(line) {
|
|
8237
8340
|
try {
|
|
8238
8341
|
const logsDir = getAinativeLogsDir();
|
|
8239
|
-
|
|
8240
|
-
|
|
8241
|
-
|
|
8342
|
+
fs14.mkdirSync(logsDir, { recursive: true });
|
|
8343
|
+
fs14.appendFileSync(
|
|
8344
|
+
path15.join(logsDir, "plugins.log"),
|
|
8242
8345
|
`${(/* @__PURE__ */ new Date()).toISOString()} ${line}
|
|
8243
8346
|
`
|
|
8244
8347
|
);
|
|
@@ -8263,10 +8366,10 @@ function isRelativeCommand(command) {
|
|
|
8263
8366
|
}
|
|
8264
8367
|
async function scanPlugin(pluginDir, pluginId) {
|
|
8265
8368
|
const registrations = [];
|
|
8266
|
-
const pluginYamlPath =
|
|
8369
|
+
const pluginYamlPath = path15.join(pluginDir, "plugin.yaml");
|
|
8267
8370
|
let pluginYamlContent;
|
|
8268
8371
|
try {
|
|
8269
|
-
pluginYamlContent =
|
|
8372
|
+
pluginYamlContent = fs14.readFileSync(pluginYamlPath, "utf-8");
|
|
8270
8373
|
} catch {
|
|
8271
8374
|
return { registrations };
|
|
8272
8375
|
}
|
|
@@ -8288,7 +8391,7 @@ async function scanPlugin(pluginDir, pluginId) {
|
|
|
8288
8391
|
if (manifest.kind !== "chat-tools") {
|
|
8289
8392
|
return { registrations };
|
|
8290
8393
|
}
|
|
8291
|
-
const mcpJsonPath =
|
|
8394
|
+
const mcpJsonPath = path15.join(pluginDir, ".mcp.json");
|
|
8292
8395
|
const mcpServers = parseMcpConfigFile(mcpJsonPath);
|
|
8293
8396
|
if (mcpServers === null) {
|
|
8294
8397
|
logToFile3(
|
|
@@ -8392,8 +8495,8 @@ async function scanPlugin(pluginDir, pluginId) {
|
|
|
8392
8495
|
const resolvedEnv = resolveEnvTemplates(rawEntry.env, context);
|
|
8393
8496
|
let resolvedCommand;
|
|
8394
8497
|
if (isRelativeCommand(rawCommand)) {
|
|
8395
|
-
const absCommand =
|
|
8396
|
-
if (!
|
|
8498
|
+
const absCommand = path15.resolve(pluginDir, rawCommand);
|
|
8499
|
+
if (!fs14.existsSync(absCommand)) {
|
|
8397
8500
|
logToFile3(
|
|
8398
8501
|
`[mcp-loader] plugin ${pluginId} server "${serverName}": command "${rawCommand}" not found at ${absCommand} (server_not_found)`
|
|
8399
8502
|
);
|
|
@@ -8487,8 +8590,8 @@ async function scanPlugin(pluginDir, pluginId) {
|
|
|
8487
8590
|
});
|
|
8488
8591
|
continue;
|
|
8489
8592
|
}
|
|
8490
|
-
const absEntry =
|
|
8491
|
-
if (!
|
|
8593
|
+
const absEntry = path15.resolve(pluginDir, entryField);
|
|
8594
|
+
if (!fs14.existsSync(absEntry)) {
|
|
8492
8595
|
logToFile3(
|
|
8493
8596
|
`[mcp-loader] plugin ${pluginId} server "${serverName}": entry "${entryField}" not found at ${absEntry} (sdk_entry_not_found)`
|
|
8494
8597
|
);
|
|
@@ -8557,9 +8660,9 @@ async function listPluginMcpRegistrations(opts2) {
|
|
|
8557
8660
|
const features = getRuntimeFeatures(opts2.runtime);
|
|
8558
8661
|
if (!features.supportsPluginMcpServers) {
|
|
8559
8662
|
const pluginsDir2 = getAinativePluginsDir();
|
|
8560
|
-
if (
|
|
8663
|
+
if (fs14.existsSync(pluginsDir2)) {
|
|
8561
8664
|
try {
|
|
8562
|
-
for (const entry of
|
|
8665
|
+
for (const entry of fs14.readdirSync(pluginsDir2).sort()) {
|
|
8563
8666
|
const logKey = `${entry}@${opts2.runtime}@${pluginsDir2}`;
|
|
8564
8667
|
if (!ollamaSkipLogged.has(logKey)) {
|
|
8565
8668
|
ollamaSkipLogged.add(logKey);
|
|
@@ -8582,22 +8685,22 @@ async function listPluginMcpRegistrations(opts2) {
|
|
|
8582
8685
|
}
|
|
8583
8686
|
}
|
|
8584
8687
|
const pluginsDir = getAinativePluginsDir();
|
|
8585
|
-
if (!
|
|
8688
|
+
if (!fs14.existsSync(pluginsDir)) {
|
|
8586
8689
|
return [];
|
|
8587
8690
|
}
|
|
8588
8691
|
let pluginDirEntries;
|
|
8589
8692
|
try {
|
|
8590
|
-
pluginDirEntries =
|
|
8693
|
+
pluginDirEntries = fs14.readdirSync(pluginsDir).sort();
|
|
8591
8694
|
} catch {
|
|
8592
8695
|
logToFile3(`[mcp-loader] could not read plugins directory: ${pluginsDir}`);
|
|
8593
8696
|
return [];
|
|
8594
8697
|
}
|
|
8595
8698
|
const allRegistrations = [];
|
|
8596
8699
|
for (const entry of pluginDirEntries) {
|
|
8597
|
-
const pluginDir =
|
|
8700
|
+
const pluginDir = path15.join(pluginsDir, entry);
|
|
8598
8701
|
let stat2;
|
|
8599
8702
|
try {
|
|
8600
|
-
stat2 =
|
|
8703
|
+
stat2 = fs14.statSync(pluginDir);
|
|
8601
8704
|
} catch {
|
|
8602
8705
|
continue;
|
|
8603
8706
|
}
|
|
@@ -8622,18 +8725,18 @@ async function loadPluginMcpServers(opts2) {
|
|
|
8622
8725
|
}
|
|
8623
8726
|
function hasAnyDockerConfinedPlugin() {
|
|
8624
8727
|
const pluginsDir = getAinativePluginsDir();
|
|
8625
|
-
if (!
|
|
8728
|
+
if (!fs14.existsSync(pluginsDir)) return false;
|
|
8626
8729
|
let entries;
|
|
8627
8730
|
try {
|
|
8628
|
-
entries =
|
|
8731
|
+
entries = fs14.readdirSync(pluginsDir);
|
|
8629
8732
|
} catch {
|
|
8630
8733
|
return false;
|
|
8631
8734
|
}
|
|
8632
8735
|
for (const entry of entries) {
|
|
8633
|
-
const pluginYamlPath =
|
|
8736
|
+
const pluginYamlPath = path15.join(pluginsDir, entry, "plugin.yaml");
|
|
8634
8737
|
let content;
|
|
8635
8738
|
try {
|
|
8636
|
-
content =
|
|
8739
|
+
content = fs14.readFileSync(pluginYamlPath, "utf-8");
|
|
8637
8740
|
} catch {
|
|
8638
8741
|
continue;
|
|
8639
8742
|
}
|
|
@@ -8653,26 +8756,26 @@ function hasAnyDockerConfinedPlugin() {
|
|
|
8653
8756
|
function buildSafeModeRegistrations() {
|
|
8654
8757
|
const out = [];
|
|
8655
8758
|
const pluginsDir = getAinativePluginsDir();
|
|
8656
|
-
if (!
|
|
8759
|
+
if (!fs14.existsSync(pluginsDir)) return out;
|
|
8657
8760
|
let entries;
|
|
8658
8761
|
try {
|
|
8659
|
-
entries =
|
|
8762
|
+
entries = fs14.readdirSync(pluginsDir).sort();
|
|
8660
8763
|
} catch {
|
|
8661
8764
|
return out;
|
|
8662
8765
|
}
|
|
8663
8766
|
for (const entry of entries) {
|
|
8664
|
-
const pluginDir =
|
|
8767
|
+
const pluginDir = path15.join(pluginsDir, entry);
|
|
8665
8768
|
let stat2;
|
|
8666
8769
|
try {
|
|
8667
|
-
stat2 =
|
|
8770
|
+
stat2 = fs14.statSync(pluginDir);
|
|
8668
8771
|
} catch {
|
|
8669
8772
|
continue;
|
|
8670
8773
|
}
|
|
8671
8774
|
if (!stat2.isDirectory()) continue;
|
|
8672
|
-
const pluginYamlPath =
|
|
8775
|
+
const pluginYamlPath = path15.join(pluginDir, "plugin.yaml");
|
|
8673
8776
|
let content;
|
|
8674
8777
|
try {
|
|
8675
|
-
content =
|
|
8778
|
+
content = fs14.readFileSync(pluginYamlPath, "utf-8");
|
|
8676
8779
|
} catch {
|
|
8677
8780
|
continue;
|
|
8678
8781
|
}
|
|
@@ -8739,7 +8842,7 @@ var init_mcp_loader = __esm({
|
|
|
8739
8842
|
init_types();
|
|
8740
8843
|
init_capability_check();
|
|
8741
8844
|
init_mcp_config();
|
|
8742
|
-
|
|
8845
|
+
init_catalog2();
|
|
8743
8846
|
init_ainative_paths();
|
|
8744
8847
|
init_transport_dispatch();
|
|
8745
8848
|
init_wrap();
|
|
@@ -8765,17 +8868,17 @@ __export(capability_check_exports, {
|
|
|
8765
8868
|
writePluginsLock: () => writePluginsLock
|
|
8766
8869
|
});
|
|
8767
8870
|
import crypto3 from "crypto";
|
|
8768
|
-
import
|
|
8871
|
+
import fs15 from "fs";
|
|
8769
8872
|
import os3 from "os";
|
|
8770
|
-
import
|
|
8873
|
+
import path16 from "path";
|
|
8771
8874
|
import yaml9 from "js-yaml";
|
|
8772
8875
|
import { z as z6 } from "zod";
|
|
8773
8876
|
function logToFile4(line) {
|
|
8774
8877
|
try {
|
|
8775
8878
|
const logsDir = getAinativeLogsDir();
|
|
8776
|
-
|
|
8777
|
-
|
|
8778
|
-
|
|
8879
|
+
fs15.mkdirSync(logsDir, { recursive: true });
|
|
8880
|
+
fs15.appendFileSync(
|
|
8881
|
+
path16.join(logsDir, "plugins.log"),
|
|
8779
8882
|
`${(/* @__PURE__ */ new Date()).toISOString()} ${line}
|
|
8780
8883
|
`
|
|
8781
8884
|
);
|
|
@@ -8815,12 +8918,12 @@ function deriveManifestHash(pluginYamlContent) {
|
|
|
8815
8918
|
}
|
|
8816
8919
|
function readPluginsLock() {
|
|
8817
8920
|
const lockPath = getAinativePluginsLockPath();
|
|
8818
|
-
if (!
|
|
8921
|
+
if (!fs15.existsSync(lockPath)) {
|
|
8819
8922
|
return { version: 1, accepted: {} };
|
|
8820
8923
|
}
|
|
8821
8924
|
let raw;
|
|
8822
8925
|
try {
|
|
8823
|
-
raw = yaml9.load(
|
|
8926
|
+
raw = yaml9.load(fs15.readFileSync(lockPath, "utf-8"));
|
|
8824
8927
|
} catch (err2) {
|
|
8825
8928
|
logToFile4(
|
|
8826
8929
|
`[capability-check] WARN: plugins.lock is not valid YAML \u2014 treating as empty. Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
@@ -8839,31 +8942,31 @@ function readPluginsLock() {
|
|
|
8839
8942
|
function writePluginsLock(pluginId, entry) {
|
|
8840
8943
|
const lockPath = getAinativePluginsLockPath();
|
|
8841
8944
|
const bakPath = lockPath + ".bak";
|
|
8842
|
-
const lockDir =
|
|
8843
|
-
|
|
8945
|
+
const lockDir = path16.dirname(lockPath);
|
|
8946
|
+
fs15.mkdirSync(lockDir, { recursive: true });
|
|
8844
8947
|
const current = readPluginsLock();
|
|
8845
8948
|
current.accepted[pluginId] = entry;
|
|
8846
8949
|
const newContent = yaml9.dump(current, { lineWidth: -1 });
|
|
8847
|
-
if (
|
|
8848
|
-
|
|
8950
|
+
if (fs15.existsSync(lockPath)) {
|
|
8951
|
+
fs15.copyFileSync(lockPath, bakPath);
|
|
8849
8952
|
try {
|
|
8850
|
-
|
|
8953
|
+
fs15.chmodSync(bakPath, 384);
|
|
8851
8954
|
} catch {
|
|
8852
8955
|
}
|
|
8853
8956
|
}
|
|
8854
8957
|
const tmpPath = `${lockPath}.tmp-${crypto3.randomBytes(6).toString("hex")}`;
|
|
8855
8958
|
try {
|
|
8856
|
-
|
|
8857
|
-
|
|
8959
|
+
fs15.writeFileSync(tmpPath, newContent, { mode: 384 });
|
|
8960
|
+
fs15.renameSync(tmpPath, lockPath);
|
|
8858
8961
|
} catch (err2) {
|
|
8859
8962
|
try {
|
|
8860
|
-
|
|
8963
|
+
fs15.unlinkSync(tmpPath);
|
|
8861
8964
|
} catch {
|
|
8862
8965
|
}
|
|
8863
8966
|
throw err2;
|
|
8864
8967
|
}
|
|
8865
8968
|
try {
|
|
8866
|
-
|
|
8969
|
+
fs15.chmodSync(lockPath, 384);
|
|
8867
8970
|
} catch {
|
|
8868
8971
|
}
|
|
8869
8972
|
}
|
|
@@ -8874,28 +8977,28 @@ function removePluginsLockEntry(pluginId) {
|
|
|
8874
8977
|
if (!(pluginId in current.accepted)) return;
|
|
8875
8978
|
delete current.accepted[pluginId];
|
|
8876
8979
|
const newContent = yaml9.dump(current, { lineWidth: -1 });
|
|
8877
|
-
const lockDir =
|
|
8878
|
-
|
|
8879
|
-
if (
|
|
8880
|
-
|
|
8980
|
+
const lockDir = path16.dirname(lockPath);
|
|
8981
|
+
fs15.mkdirSync(lockDir, { recursive: true });
|
|
8982
|
+
if (fs15.existsSync(lockPath)) {
|
|
8983
|
+
fs15.copyFileSync(lockPath, bakPath);
|
|
8881
8984
|
try {
|
|
8882
|
-
|
|
8985
|
+
fs15.chmodSync(bakPath, 384);
|
|
8883
8986
|
} catch {
|
|
8884
8987
|
}
|
|
8885
8988
|
}
|
|
8886
8989
|
const tmpPath = `${lockPath}.tmp-${crypto3.randomBytes(6).toString("hex")}`;
|
|
8887
8990
|
try {
|
|
8888
|
-
|
|
8889
|
-
|
|
8991
|
+
fs15.writeFileSync(tmpPath, newContent, { mode: 384 });
|
|
8992
|
+
fs15.renameSync(tmpPath, lockPath);
|
|
8890
8993
|
} catch (err2) {
|
|
8891
8994
|
try {
|
|
8892
|
-
|
|
8995
|
+
fs15.unlinkSync(tmpPath);
|
|
8893
8996
|
} catch {
|
|
8894
8997
|
}
|
|
8895
8998
|
throw err2;
|
|
8896
8999
|
}
|
|
8897
9000
|
try {
|
|
8898
|
-
|
|
9001
|
+
fs15.chmodSync(lockPath, 384);
|
|
8899
9002
|
} catch {
|
|
8900
9003
|
}
|
|
8901
9004
|
}
|
|
@@ -8981,9 +9084,9 @@ function getPluginToolApprovalMode(pluginId, toolName, defaultFromManifest) {
|
|
|
8981
9084
|
}
|
|
8982
9085
|
function readManifestDefaultApproval(pluginId) {
|
|
8983
9086
|
try {
|
|
8984
|
-
const pluginYamlPath =
|
|
8985
|
-
if (!
|
|
8986
|
-
const content =
|
|
9087
|
+
const pluginYamlPath = path16.join(getAinativePluginsDir(), pluginId, "plugin.yaml");
|
|
9088
|
+
if (!fs15.existsSync(pluginYamlPath)) return void 0;
|
|
9089
|
+
const content = fs15.readFileSync(pluginYamlPath, "utf-8");
|
|
8987
9090
|
const raw = yaml9.load(content);
|
|
8988
9091
|
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return void 0;
|
|
8989
9092
|
const record = raw;
|
|
@@ -9075,13 +9178,13 @@ async function revokePluginCapabilities(pluginId) {
|
|
|
9075
9178
|
}
|
|
9076
9179
|
async function grantPluginCapabilities(pluginId, opts2) {
|
|
9077
9180
|
const { getAinativePluginsDir: getDir } = await Promise.resolve().then(() => (init_ainative_paths(), ainative_paths_exports));
|
|
9078
|
-
const pluginYamlPath =
|
|
9079
|
-
if (!
|
|
9181
|
+
const pluginYamlPath = path16.join(getDir(), pluginId, "plugin.yaml");
|
|
9182
|
+
if (!fs15.existsSync(pluginYamlPath)) {
|
|
9080
9183
|
return { granted: false, reason: "not_found" };
|
|
9081
9184
|
}
|
|
9082
9185
|
let content;
|
|
9083
9186
|
try {
|
|
9084
|
-
content =
|
|
9187
|
+
content = fs15.readFileSync(pluginYamlPath, "utf-8");
|
|
9085
9188
|
} catch (err2) {
|
|
9086
9189
|
return {
|
|
9087
9190
|
granted: false,
|
|
@@ -9472,7 +9575,7 @@ var RetryableRuntimeLaunchError;
|
|
|
9472
9575
|
var init_launch_failure = __esm({
|
|
9473
9576
|
"src/lib/agents/runtime/launch-failure.ts"() {
|
|
9474
9577
|
"use strict";
|
|
9475
|
-
|
|
9578
|
+
init_catalog2();
|
|
9476
9579
|
RetryableRuntimeLaunchError = class extends Error {
|
|
9477
9580
|
runtimeId;
|
|
9478
9581
|
cause;
|
|
@@ -9764,7 +9867,7 @@ var init_router = __esm({
|
|
|
9764
9867
|
"use strict";
|
|
9765
9868
|
init_registry2();
|
|
9766
9869
|
init_compatibility();
|
|
9767
|
-
|
|
9870
|
+
init_catalog2();
|
|
9768
9871
|
init_task_dispatch();
|
|
9769
9872
|
RUNTIME_KEYWORD_SIGNALS = {
|
|
9770
9873
|
// File/code operations → claude-code (needs filesystem)
|
|
@@ -10094,7 +10197,7 @@ var init_task_tools = __esm({
|
|
|
10094
10197
|
init_db();
|
|
10095
10198
|
init_schema();
|
|
10096
10199
|
init_helpers2();
|
|
10097
|
-
|
|
10200
|
+
init_catalog2();
|
|
10098
10201
|
init_registry2();
|
|
10099
10202
|
VALID_TASK_STATUSES = [
|
|
10100
10203
|
"planned",
|
|
@@ -10325,7 +10428,7 @@ function workflowTools(ctx) {
|
|
|
10325
10428
|
args.definition = JSON.stringify(parsedDef);
|
|
10326
10429
|
let runtimeId = null;
|
|
10327
10430
|
if (args.runtime) {
|
|
10328
|
-
const { isAgentRuntimeId: isAgentRuntimeId2 } = await Promise.resolve().then(() => (
|
|
10431
|
+
const { isAgentRuntimeId: isAgentRuntimeId2 } = await Promise.resolve().then(() => (init_catalog2(), catalog_exports2));
|
|
10329
10432
|
if (!isAgentRuntimeId2(args.runtime)) {
|
|
10330
10433
|
return err(`Invalid runtime "${args.runtime}". Use list_runtimes to see available options.`);
|
|
10331
10434
|
}
|
|
@@ -11848,9 +11951,9 @@ function buildPermissionSummary(toolName, input) {
|
|
|
11848
11951
|
}
|
|
11849
11952
|
}
|
|
11850
11953
|
if (toolName === "Read" || toolName === "Write" || toolName === "Edit" || toolName === "read" || toolName === "write" || toolName === "edit") {
|
|
11851
|
-
const
|
|
11852
|
-
if (typeof
|
|
11853
|
-
return truncate(
|
|
11954
|
+
const path21 = input.file_path ?? input.path;
|
|
11955
|
+
if (typeof path21 === "string" && path21.trim().length > 0) {
|
|
11956
|
+
return truncate(path21.trim());
|
|
11854
11957
|
}
|
|
11855
11958
|
}
|
|
11856
11959
|
if (toolName?.startsWith("mcp__")) {
|
|
@@ -11884,9 +11987,9 @@ function getPermissionDetailEntries(toolName, input) {
|
|
|
11884
11987
|
}
|
|
11885
11988
|
}
|
|
11886
11989
|
if (toolName === "Read" || toolName === "Write" || toolName === "Edit" || toolName === "read" || toolName === "write" || toolName === "edit") {
|
|
11887
|
-
const
|
|
11888
|
-
if (typeof
|
|
11889
|
-
return [{ label: "Path", value:
|
|
11990
|
+
const path21 = input.file_path ?? input.path;
|
|
11991
|
+
if (typeof path21 === "string") {
|
|
11992
|
+
return [{ label: "Path", value: path21 }];
|
|
11890
11993
|
}
|
|
11891
11994
|
}
|
|
11892
11995
|
return Object.entries(input).slice(0, 6).map(([key, value]) => ({
|
|
@@ -12174,16 +12277,16 @@ __export(registry_exports4, {
|
|
|
12174
12277
|
reloadSchedules: () => reloadSchedules,
|
|
12175
12278
|
validateScheduleRefs: () => validateScheduleRefs
|
|
12176
12279
|
});
|
|
12177
|
-
import
|
|
12178
|
-
import
|
|
12280
|
+
import fs16 from "fs";
|
|
12281
|
+
import path17 from "path";
|
|
12179
12282
|
import yaml10 from "js-yaml";
|
|
12180
12283
|
function scanDirectory2(dir) {
|
|
12181
12284
|
const schedules2 = /* @__PURE__ */ new Map();
|
|
12182
|
-
if (!
|
|
12183
|
-
for (const file of
|
|
12285
|
+
if (!fs16.existsSync(dir)) return schedules2;
|
|
12286
|
+
for (const file of fs16.readdirSync(dir)) {
|
|
12184
12287
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml")) continue;
|
|
12185
12288
|
try {
|
|
12186
|
-
const content =
|
|
12289
|
+
const content = fs16.readFileSync(path17.join(dir, file), "utf-8");
|
|
12187
12290
|
const parsed = yaml10.load(content);
|
|
12188
12291
|
const result = ScheduleSpecSchema.safeParse(parsed);
|
|
12189
12292
|
if (!result.success) {
|
|
@@ -12239,12 +12342,12 @@ function createScheduleFromYaml(yamlContent) {
|
|
|
12239
12342
|
`Invalid schedule: ${result.error.issues.map((i) => i.message).join(", ")}`
|
|
12240
12343
|
);
|
|
12241
12344
|
}
|
|
12242
|
-
|
|
12243
|
-
const filePath =
|
|
12244
|
-
if (
|
|
12345
|
+
fs16.mkdirSync(USER_DIR, { recursive: true });
|
|
12346
|
+
const filePath = path17.join(USER_DIR, `${result.data.id}.yaml`);
|
|
12347
|
+
if (fs16.existsSync(filePath)) {
|
|
12245
12348
|
throw new Error(`Schedule "${result.data.id}" already exists`);
|
|
12246
12349
|
}
|
|
12247
|
-
|
|
12350
|
+
fs16.writeFileSync(filePath, yamlContent);
|
|
12248
12351
|
reloadSchedules();
|
|
12249
12352
|
return result.data;
|
|
12250
12353
|
}
|
|
@@ -12296,11 +12399,11 @@ function deleteSchedule(id) {
|
|
|
12296
12399
|
if (isBuiltinSchedule(id)) {
|
|
12297
12400
|
throw new Error("Cannot delete built-in schedules");
|
|
12298
12401
|
}
|
|
12299
|
-
const filePath =
|
|
12300
|
-
if (!
|
|
12402
|
+
const filePath = path17.join(USER_DIR, `${id}.yaml`);
|
|
12403
|
+
if (!fs16.existsSync(filePath)) {
|
|
12301
12404
|
throw new Error(`Schedule "${id}" not found`);
|
|
12302
12405
|
}
|
|
12303
|
-
|
|
12406
|
+
fs16.unlinkSync(filePath);
|
|
12304
12407
|
reloadSchedules();
|
|
12305
12408
|
}
|
|
12306
12409
|
var BUILTINS_DIR3, USER_DIR, scheduleCache, builtinIdsCache, pluginScheduleIndex;
|
|
@@ -12310,7 +12413,7 @@ var init_registry5 = __esm({
|
|
|
12310
12413
|
init_schedule_spec();
|
|
12311
12414
|
init_ainative_paths();
|
|
12312
12415
|
init_app_root();
|
|
12313
|
-
BUILTINS_DIR3 =
|
|
12416
|
+
BUILTINS_DIR3 = path17.resolve(
|
|
12314
12417
|
getAppRoot(import.meta.dirname, 4),
|
|
12315
12418
|
"src",
|
|
12316
12419
|
"lib",
|
|
@@ -12325,6 +12428,14 @@ var init_registry5 = __esm({
|
|
|
12325
12428
|
});
|
|
12326
12429
|
|
|
12327
12430
|
// src/lib/schedules/installer.ts
|
|
12431
|
+
var installer_exports = {};
|
|
12432
|
+
__export(installer_exports, {
|
|
12433
|
+
installPluginSchedules: () => installPluginSchedules,
|
|
12434
|
+
installSchedulesFromSpecs: () => installSchedulesFromSpecs,
|
|
12435
|
+
listInstalledPluginScheduleIds: () => listInstalledPluginScheduleIds,
|
|
12436
|
+
removeOrphanSchedules: () => removeOrphanSchedules,
|
|
12437
|
+
removePluginSchedules: () => removePluginSchedules
|
|
12438
|
+
});
|
|
12328
12439
|
import { and as and16, like as like5, notInArray } from "drizzle-orm";
|
|
12329
12440
|
function pluginScheduleId(pluginId, scheduleId) {
|
|
12330
12441
|
return `${PLUGIN_SCHEDULE_PREFIX}${pluginId}:${scheduleId}`;
|
|
@@ -12422,6 +12533,10 @@ function removeOrphanSchedules(pluginId, keepIds) {
|
|
|
12422
12533
|
db.delete(schedules).where(and16(like5(schedules.id, pattern), notInArray(schedules.id, keepIds))).run();
|
|
12423
12534
|
}
|
|
12424
12535
|
}
|
|
12536
|
+
function listInstalledPluginScheduleIds(pluginId) {
|
|
12537
|
+
const pattern = `${PLUGIN_SCHEDULE_PREFIX}${pluginId}:%`;
|
|
12538
|
+
return db.select({ id: schedules.id }).from(schedules).where(like5(schedules.id, pattern)).all().map((r) => r.id);
|
|
12539
|
+
}
|
|
12425
12540
|
var PLUGIN_SCHEDULE_PREFIX;
|
|
12426
12541
|
var init_installer = __esm({
|
|
12427
12542
|
"src/lib/schedules/installer.ts"() {
|
|
@@ -12444,8 +12559,8 @@ __export(registry_exports5, {
|
|
|
12444
12559
|
reloadPlugins: () => reloadPlugins,
|
|
12445
12560
|
scanBundleSection: () => scanBundleSection
|
|
12446
12561
|
});
|
|
12447
|
-
import
|
|
12448
|
-
import
|
|
12562
|
+
import fs17 from "fs";
|
|
12563
|
+
import path18 from "path";
|
|
12449
12564
|
import yaml11 from "js-yaml";
|
|
12450
12565
|
import { z as z16 } from "zod";
|
|
12451
12566
|
function isSupportedApiVersion(apiVersion) {
|
|
@@ -12454,9 +12569,9 @@ function isSupportedApiVersion(apiVersion) {
|
|
|
12454
12569
|
function logToFile5(line) {
|
|
12455
12570
|
try {
|
|
12456
12571
|
const logsDir = getAinativeLogsDir();
|
|
12457
|
-
|
|
12458
|
-
|
|
12459
|
-
|
|
12572
|
+
fs17.mkdirSync(logsDir, { recursive: true });
|
|
12573
|
+
fs17.appendFileSync(
|
|
12574
|
+
path18.join(logsDir, "plugins.log"),
|
|
12460
12575
|
`${(/* @__PURE__ */ new Date()).toISOString()} ${line}
|
|
12461
12576
|
`
|
|
12462
12577
|
);
|
|
@@ -12464,11 +12579,11 @@ function logToFile5(line) {
|
|
|
12464
12579
|
}
|
|
12465
12580
|
}
|
|
12466
12581
|
function readManifest(rootDir) {
|
|
12467
|
-
const manifestPath =
|
|
12468
|
-
if (!
|
|
12582
|
+
const manifestPath = path18.join(rootDir, "plugin.yaml");
|
|
12583
|
+
if (!fs17.existsSync(manifestPath)) return { error: "missing plugin.yaml" };
|
|
12469
12584
|
let raw;
|
|
12470
12585
|
try {
|
|
12471
|
-
raw = yaml11.load(
|
|
12586
|
+
raw = yaml11.load(fs17.readFileSync(manifestPath, "utf-8"));
|
|
12472
12587
|
} catch (err2) {
|
|
12473
12588
|
return { error: `yaml_parse: ${err2 instanceof Error ? err2.message : String(err2)}` };
|
|
12474
12589
|
}
|
|
@@ -12480,16 +12595,16 @@ function readManifest(rootDir) {
|
|
|
12480
12595
|
}
|
|
12481
12596
|
function discoverBundleRoots() {
|
|
12482
12597
|
const baseDir = getAinativePluginsDir();
|
|
12483
|
-
if (!
|
|
12484
|
-
return
|
|
12598
|
+
if (!fs17.existsSync(baseDir)) return [];
|
|
12599
|
+
return fs17.readdirSync(baseDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => path18.join(baseDir, e.name)).sort();
|
|
12485
12600
|
}
|
|
12486
12601
|
function scanBundleSection(opts2) {
|
|
12487
|
-
const dir =
|
|
12488
|
-
if (!
|
|
12602
|
+
const dir = path18.join(opts2.rootDir, opts2.section);
|
|
12603
|
+
if (!fs17.existsSync(dir)) return [];
|
|
12489
12604
|
const out = [];
|
|
12490
|
-
for (const file of
|
|
12605
|
+
for (const file of fs17.readdirSync(dir)) {
|
|
12491
12606
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml")) continue;
|
|
12492
|
-
const filePath =
|
|
12607
|
+
const filePath = path18.join(dir, file);
|
|
12493
12608
|
try {
|
|
12494
12609
|
const result = opts2.parseFile(filePath);
|
|
12495
12610
|
if (result !== null) out.push(result);
|
|
@@ -12500,8 +12615,8 @@ function scanBundleSection(opts2) {
|
|
|
12500
12615
|
return out;
|
|
12501
12616
|
}
|
|
12502
12617
|
function scanBundleProfiles(rootDir, pluginId) {
|
|
12503
|
-
const profilesDir =
|
|
12504
|
-
if (!
|
|
12618
|
+
const profilesDir = path18.join(rootDir, "profiles");
|
|
12619
|
+
if (!fs17.existsSync(profilesDir)) return [];
|
|
12505
12620
|
const tmp = /* @__PURE__ */ new Map();
|
|
12506
12621
|
scanProfilesIntoMap(profilesDir, tmp, { namespace: pluginId });
|
|
12507
12622
|
return Array.from(tmp.entries()).map(([id, profile]) => ({
|
|
@@ -12514,9 +12629,9 @@ function scanBundleBlueprints(rootDir, pluginId, siblingProfileIds) {
|
|
|
12514
12629
|
rootDir,
|
|
12515
12630
|
section: "blueprints",
|
|
12516
12631
|
parseFile: (filePath) => {
|
|
12517
|
-
const file =
|
|
12632
|
+
const file = path18.basename(filePath);
|
|
12518
12633
|
try {
|
|
12519
|
-
const raw = yaml11.load(
|
|
12634
|
+
const raw = yaml11.load(fs17.readFileSync(filePath, "utf-8"));
|
|
12520
12635
|
const parsed = BlueprintSchema.safeParse(raw);
|
|
12521
12636
|
if (!parsed.success) {
|
|
12522
12637
|
logToFile5(`skip blueprint ${pluginId}/${file}: ${parsed.error.issues.map((i) => i.message).join("; ")}`);
|
|
@@ -12542,9 +12657,9 @@ function scanBundleTables(rootDir, pluginId) {
|
|
|
12542
12657
|
rootDir,
|
|
12543
12658
|
section: "tables",
|
|
12544
12659
|
parseFile: (filePath) => {
|
|
12545
|
-
const file =
|
|
12660
|
+
const file = path18.basename(filePath);
|
|
12546
12661
|
try {
|
|
12547
|
-
const raw = yaml11.load(
|
|
12662
|
+
const raw = yaml11.load(fs17.readFileSync(filePath, "utf-8"));
|
|
12548
12663
|
const parsed = PluginTableSchema.safeParse(raw);
|
|
12549
12664
|
if (!parsed.success) {
|
|
12550
12665
|
logToFile5(`skip table ${pluginId}/${file}: ${parsed.error.issues.map((i) => i.message).join("; ")}`);
|
|
@@ -12563,9 +12678,9 @@ function scanBundleSchedules(rootDir, pluginId) {
|
|
|
12563
12678
|
rootDir,
|
|
12564
12679
|
section: "schedules",
|
|
12565
12680
|
parseFile: (filePath) => {
|
|
12566
|
-
const file =
|
|
12681
|
+
const file = path18.basename(filePath);
|
|
12567
12682
|
try {
|
|
12568
|
-
const raw = yaml11.load(
|
|
12683
|
+
const raw = yaml11.load(fs17.readFileSync(filePath, "utf-8"));
|
|
12569
12684
|
const parsed = ScheduleSpecSchema.safeParse(raw);
|
|
12570
12685
|
if (!parsed.success) {
|
|
12571
12686
|
logToFile5(`skip schedule ${pluginId}/${file}: ${parsed.error.issues.map((i) => i.message).join("; ")}`);
|
|
@@ -12652,7 +12767,7 @@ async function scanPlugins() {
|
|
|
12652
12767
|
for (const rootDir of discoverBundleRoots()) {
|
|
12653
12768
|
const { manifest, error } = readManifest(rootDir);
|
|
12654
12769
|
if (!manifest) {
|
|
12655
|
-
const fallbackId =
|
|
12770
|
+
const fallbackId = path18.basename(rootDir);
|
|
12656
12771
|
result.push({
|
|
12657
12772
|
id: fallbackId,
|
|
12658
12773
|
manifest: { id: fallbackId, version: "0.0.0", apiVersion: "0.0", kind: "primitives-bundle" },
|
|
@@ -12776,7 +12891,7 @@ var init_registry6 = __esm({
|
|
|
12776
12891
|
init_registry5();
|
|
12777
12892
|
init_installer();
|
|
12778
12893
|
init_schedule_spec();
|
|
12779
|
-
SUPPORTED_API_VERSIONS = /* @__PURE__ */ new Set([
|
|
12894
|
+
SUPPORTED_API_VERSIONS = /* @__PURE__ */ new Set([CURRENT_PLUGIN_API_VERSION, "0.18"]);
|
|
12780
12895
|
pluginCache = null;
|
|
12781
12896
|
lastLoadedPluginIds = /* @__PURE__ */ new Set();
|
|
12782
12897
|
PluginTableSchema = z16.object({
|
|
@@ -12819,8 +12934,8 @@ function pluginTools(_ctx) {
|
|
|
12819
12934
|
Promise.resolve().then(() => (init_ainative_paths(), ainative_paths_exports)),
|
|
12820
12935
|
Promise.resolve().then(() => (init_types(), types_exports))
|
|
12821
12936
|
]);
|
|
12822
|
-
const
|
|
12823
|
-
const
|
|
12937
|
+
const fs20 = await import("fs");
|
|
12938
|
+
const path21 = await import("path");
|
|
12824
12939
|
const yaml13 = await import("js-yaml");
|
|
12825
12940
|
const kind5 = listPlugins2();
|
|
12826
12941
|
const registrations = await listPluginMcpRegistrations2();
|
|
@@ -12837,13 +12952,13 @@ function pluginTools(_ctx) {
|
|
|
12837
12952
|
let manifestHash;
|
|
12838
12953
|
let capabilityAcceptStatus = "pending";
|
|
12839
12954
|
try {
|
|
12840
|
-
const pluginYamlPath =
|
|
12955
|
+
const pluginYamlPath = path21.join(
|
|
12841
12956
|
pluginsDir,
|
|
12842
12957
|
pluginId,
|
|
12843
12958
|
"plugin.yaml"
|
|
12844
12959
|
);
|
|
12845
|
-
if (
|
|
12846
|
-
const content =
|
|
12960
|
+
if (fs20.existsSync(pluginYamlPath)) {
|
|
12961
|
+
const content = fs20.readFileSync(pluginYamlPath, "utf-8");
|
|
12847
12962
|
const rawManifest = yaml13.load(content);
|
|
12848
12963
|
if (rawManifest !== null && typeof rawManifest === "object" && !Array.isArray(rawManifest)) {
|
|
12849
12964
|
const record = rawManifest;
|
|
@@ -12856,7 +12971,7 @@ function pluginTools(_ctx) {
|
|
|
12856
12971
|
try {
|
|
12857
12972
|
manifestHash = deriveManifestHash2(content);
|
|
12858
12973
|
const parsed = PluginManifestSchema2.safeParse(rawManifest);
|
|
12859
|
-
const pluginRootDir =
|
|
12974
|
+
const pluginRootDir = path21.join(pluginsDir, pluginId);
|
|
12860
12975
|
const check = isCapabilityAccepted2(
|
|
12861
12976
|
pluginId,
|
|
12862
12977
|
manifestHash,
|
|
@@ -15576,7 +15691,7 @@ var init_runtime_tools = __esm({
|
|
|
15576
15691
|
"use strict";
|
|
15577
15692
|
init_tool_registry();
|
|
15578
15693
|
init_helpers2();
|
|
15579
|
-
|
|
15694
|
+
init_catalog2();
|
|
15580
15695
|
}
|
|
15581
15696
|
});
|
|
15582
15697
|
|
|
@@ -16690,7 +16805,7 @@ async function activateSkill(args) {
|
|
|
16690
16805
|
return { kind: "error", message: `Conversation not found: ${conversationId}` };
|
|
16691
16806
|
}
|
|
16692
16807
|
if (mode === "add") {
|
|
16693
|
-
const { getRuntimeFeatures: getRuntimeFeatures2 } = await Promise.resolve().then(() => (
|
|
16808
|
+
const { getRuntimeFeatures: getRuntimeFeatures2 } = await Promise.resolve().then(() => (init_catalog2(), catalog_exports2));
|
|
16694
16809
|
let features;
|
|
16695
16810
|
try {
|
|
16696
16811
|
features = getRuntimeFeatures2(
|
|
@@ -17011,8 +17126,8 @@ var init_schedule_spec_tools = __esm({
|
|
|
17011
17126
|
|
|
17012
17127
|
// src/lib/chat/tools/plugin-spec-tools.ts
|
|
17013
17128
|
import { z as z27 } from "zod";
|
|
17014
|
-
import * as
|
|
17015
|
-
import * as
|
|
17129
|
+
import * as fs18 from "fs";
|
|
17130
|
+
import * as path19 from "path";
|
|
17016
17131
|
function validateId(id) {
|
|
17017
17132
|
if (id.length < 2) {
|
|
17018
17133
|
throw new PluginSpecInvalidIdError(id, "must be at least 2 chars");
|
|
@@ -17040,7 +17155,7 @@ function renderPluginYaml(input) {
|
|
|
17040
17155
|
``,
|
|
17041
17156
|
`id: ${input.id}`,
|
|
17042
17157
|
`version: 0.1.0`,
|
|
17043
|
-
`apiVersion: "
|
|
17158
|
+
`apiVersion: "${CURRENT_PLUGIN_API_VERSION}"`,
|
|
17044
17159
|
`kind: chat-tools`,
|
|
17045
17160
|
`name: ${JSON.stringify(input.name)}`,
|
|
17046
17161
|
`description: ${JSON.stringify(input.description)}`,
|
|
@@ -17275,20 +17390,20 @@ directory at load time \u2014 you do not need to edit that path.
|
|
|
17275
17390
|
function scaffoldPluginSpec(input) {
|
|
17276
17391
|
validateId(input.id);
|
|
17277
17392
|
const pluginsDir = getAinativePluginsDir();
|
|
17278
|
-
const pluginDir =
|
|
17279
|
-
const tmpDir =
|
|
17280
|
-
if (
|
|
17393
|
+
const pluginDir = path19.join(pluginsDir, input.id);
|
|
17394
|
+
const tmpDir = path19.join(pluginsDir, `${input.id}.tmp-${Date.now()}`);
|
|
17395
|
+
if (fs18.existsSync(pluginDir)) {
|
|
17281
17396
|
throw new PluginSpecAlreadyExistsError(pluginDir);
|
|
17282
17397
|
}
|
|
17283
17398
|
try {
|
|
17284
|
-
|
|
17285
|
-
|
|
17286
|
-
|
|
17399
|
+
fs18.mkdirSync(tmpDir, { recursive: true });
|
|
17400
|
+
fs18.writeFileSync(
|
|
17401
|
+
path19.join(tmpDir, "plugin.yaml"),
|
|
17287
17402
|
renderPluginYaml(input),
|
|
17288
17403
|
"utf-8"
|
|
17289
17404
|
);
|
|
17290
|
-
|
|
17291
|
-
|
|
17405
|
+
fs18.writeFileSync(
|
|
17406
|
+
path19.join(tmpDir, ".mcp.json"),
|
|
17292
17407
|
renderMcpJson({
|
|
17293
17408
|
id: input.id,
|
|
17294
17409
|
transport: input.transport,
|
|
@@ -17296,8 +17411,8 @@ function scaffoldPluginSpec(input) {
|
|
|
17296
17411
|
}),
|
|
17297
17412
|
"utf-8"
|
|
17298
17413
|
);
|
|
17299
|
-
|
|
17300
|
-
|
|
17414
|
+
fs18.writeFileSync(
|
|
17415
|
+
path19.join(tmpDir, "server.py"),
|
|
17301
17416
|
renderServerPy({
|
|
17302
17417
|
id: input.id,
|
|
17303
17418
|
tools: input.tools,
|
|
@@ -17306,8 +17421,8 @@ function scaffoldPluginSpec(input) {
|
|
|
17306
17421
|
}),
|
|
17307
17422
|
"utf-8"
|
|
17308
17423
|
);
|
|
17309
|
-
|
|
17310
|
-
|
|
17424
|
+
fs18.writeFileSync(
|
|
17425
|
+
path19.join(tmpDir, "README.md"),
|
|
17311
17426
|
renderReadme({
|
|
17312
17427
|
id: input.id,
|
|
17313
17428
|
name: input.name,
|
|
@@ -17315,11 +17430,11 @@ function scaffoldPluginSpec(input) {
|
|
|
17315
17430
|
}),
|
|
17316
17431
|
"utf-8"
|
|
17317
17432
|
);
|
|
17318
|
-
|
|
17433
|
+
fs18.renameSync(tmpDir, pluginDir);
|
|
17319
17434
|
} catch (cause) {
|
|
17320
17435
|
try {
|
|
17321
|
-
if (
|
|
17322
|
-
|
|
17436
|
+
if (fs18.existsSync(tmpDir)) {
|
|
17437
|
+
fs18.rmSync(tmpDir, { recursive: true, force: true });
|
|
17323
17438
|
}
|
|
17324
17439
|
} catch {
|
|
17325
17440
|
}
|
|
@@ -17330,10 +17445,10 @@ function scaffoldPluginSpec(input) {
|
|
|
17330
17445
|
id: input.id,
|
|
17331
17446
|
pluginDir,
|
|
17332
17447
|
files: {
|
|
17333
|
-
pluginYaml:
|
|
17334
|
-
mcpJson:
|
|
17335
|
-
serverPy:
|
|
17336
|
-
readme:
|
|
17448
|
+
pluginYaml: path19.join(pluginDir, "plugin.yaml"),
|
|
17449
|
+
mcpJson: path19.join(pluginDir, ".mcp.json"),
|
|
17450
|
+
serverPy: path19.join(pluginDir, "server.py"),
|
|
17451
|
+
readme: path19.join(pluginDir, "README.md")
|
|
17337
17452
|
},
|
|
17338
17453
|
tools: input.tools.map((t) => t.name),
|
|
17339
17454
|
message: `Scaffolded ${input.id}. Reload ainative to register.`
|
|
@@ -17399,6 +17514,7 @@ var init_plugin_spec_tools = __esm({
|
|
|
17399
17514
|
init_tool_registry();
|
|
17400
17515
|
init_helpers2();
|
|
17401
17516
|
init_ainative_paths();
|
|
17517
|
+
init_types();
|
|
17402
17518
|
PluginSpecAlreadyExistsError = class extends Error {
|
|
17403
17519
|
constructor(pluginDir) {
|
|
17404
17520
|
super(
|
|
@@ -18864,7 +18980,7 @@ var init_claude = __esm({
|
|
|
18864
18980
|
init_registry2();
|
|
18865
18981
|
init_compatibility();
|
|
18866
18982
|
init_claude_agent();
|
|
18867
|
-
|
|
18983
|
+
init_catalog2();
|
|
18868
18984
|
init_claude_sdk();
|
|
18869
18985
|
init_workspace_context();
|
|
18870
18986
|
init_helpers();
|
|
@@ -19271,13 +19387,13 @@ var init_codex_app_server_client = __esm({
|
|
|
19271
19387
|
await syncPluginMcpToCodex2();
|
|
19272
19388
|
} catch (err2) {
|
|
19273
19389
|
try {
|
|
19274
|
-
const
|
|
19275
|
-
const
|
|
19390
|
+
const fs20 = await import("fs");
|
|
19391
|
+
const path21 = await import("path");
|
|
19276
19392
|
const { getAinativeLogsDir: getAinativeLogsDir2 } = await Promise.resolve().then(() => (init_ainative_paths(), ainative_paths_exports));
|
|
19277
19393
|
const dir = getAinativeLogsDir2();
|
|
19278
|
-
|
|
19279
|
-
|
|
19280
|
-
|
|
19394
|
+
fs20.mkdirSync(dir, { recursive: true });
|
|
19395
|
+
fs20.appendFileSync(
|
|
19396
|
+
path21.join(dir, "plugins.log"),
|
|
19281
19397
|
`${(/* @__PURE__ */ new Date()).toISOString()} codex-sync-failed: ${err2 instanceof Error ? err2.message : String(err2)}
|
|
19282
19398
|
`
|
|
19283
19399
|
);
|
|
@@ -20403,7 +20519,7 @@ var init_openai_codex = __esm({
|
|
|
20403
20519
|
init_context_builder();
|
|
20404
20520
|
init_output_scanner();
|
|
20405
20521
|
init_permissions();
|
|
20406
|
-
|
|
20522
|
+
init_catalog2();
|
|
20407
20523
|
init_workspace_context();
|
|
20408
20524
|
init_openai_codex_auth();
|
|
20409
20525
|
init_launch_failure();
|
|
@@ -21016,7 +21132,7 @@ var init_anthropic_direct = __esm({
|
|
|
21016
21132
|
init_ainative_tools();
|
|
21017
21133
|
init_tool_permissions();
|
|
21018
21134
|
init_agentic_loop();
|
|
21019
|
-
|
|
21135
|
+
init_catalog2();
|
|
21020
21136
|
init_registry2();
|
|
21021
21137
|
init_ledger();
|
|
21022
21138
|
init_output_scanner();
|
|
@@ -21450,7 +21566,7 @@ var init_openai_direct = __esm({
|
|
|
21450
21566
|
init_ainative_tools();
|
|
21451
21567
|
init_tool_permissions();
|
|
21452
21568
|
init_agentic_loop();
|
|
21453
|
-
|
|
21569
|
+
init_catalog2();
|
|
21454
21570
|
init_registry2();
|
|
21455
21571
|
init_ledger();
|
|
21456
21572
|
init_output_scanner();
|
|
@@ -21757,7 +21873,7 @@ var init_ollama_adapter = __esm({
|
|
|
21757
21873
|
init_schema();
|
|
21758
21874
|
init_execution_manager();
|
|
21759
21875
|
init_claude_agent();
|
|
21760
|
-
|
|
21876
|
+
init_catalog2();
|
|
21761
21877
|
init_registry2();
|
|
21762
21878
|
init_ledger();
|
|
21763
21879
|
DEFAULT_OLLAMA_BASE_URL = "http://localhost:11434";
|
|
@@ -21794,7 +21910,7 @@ var updateAuthSettingsSchema, updateOpenAISettingsSchema, nullablePositiveNumber
|
|
|
21794
21910
|
var init_settings3 = __esm({
|
|
21795
21911
|
"src/lib/validators/settings.ts"() {
|
|
21796
21912
|
"use strict";
|
|
21797
|
-
|
|
21913
|
+
init_catalog2();
|
|
21798
21914
|
updateAuthSettingsSchema = z29.object({
|
|
21799
21915
|
method: z29.enum(["api_key", "oauth"]).optional(),
|
|
21800
21916
|
apiKey: z29.string().startsWith("sk-ant-", "API key must start with sk-ant-").optional(),
|
|
@@ -21897,7 +22013,7 @@ function listConfiguredRuntimeIds(states) {
|
|
|
21897
22013
|
var init_runtime_setup = __esm({
|
|
21898
22014
|
"src/lib/settings/runtime-setup.ts"() {
|
|
21899
22015
|
"use strict";
|
|
21900
|
-
|
|
22016
|
+
init_catalog2();
|
|
21901
22017
|
init_auth();
|
|
21902
22018
|
init_openai_auth();
|
|
21903
22019
|
}
|
|
@@ -22317,7 +22433,7 @@ var init_budget_guardrails = __esm({
|
|
|
22317
22433
|
init_db();
|
|
22318
22434
|
init_schema();
|
|
22319
22435
|
init_settings();
|
|
22320
|
-
|
|
22436
|
+
init_catalog2();
|
|
22321
22437
|
init_helpers();
|
|
22322
22438
|
init_settings3();
|
|
22323
22439
|
init_ledger();
|
|
@@ -22372,7 +22488,7 @@ var runtimeRegistry;
|
|
|
22372
22488
|
var init_runtime = __esm({
|
|
22373
22489
|
"src/lib/agents/runtime/index.ts"() {
|
|
22374
22490
|
"use strict";
|
|
22375
|
-
|
|
22491
|
+
init_catalog2();
|
|
22376
22492
|
init_claude();
|
|
22377
22493
|
init_openai_codex();
|
|
22378
22494
|
init_anthropic_direct();
|
|
@@ -22647,7 +22763,7 @@ var init_execution_target = __esm({
|
|
|
22647
22763
|
init_registry2();
|
|
22648
22764
|
init_compatibility();
|
|
22649
22765
|
init_router();
|
|
22650
|
-
|
|
22766
|
+
init_catalog2();
|
|
22651
22767
|
init_runtime();
|
|
22652
22768
|
init_routing();
|
|
22653
22769
|
init_runtime_setup();
|
|
@@ -22829,7 +22945,7 @@ var init_task_dispatch = __esm({
|
|
|
22829
22945
|
init_runtime();
|
|
22830
22946
|
init_execution_target();
|
|
22831
22947
|
init_launch_failure();
|
|
22832
|
-
|
|
22948
|
+
init_catalog2();
|
|
22833
22949
|
}
|
|
22834
22950
|
});
|
|
22835
22951
|
|
|
@@ -22869,14 +22985,14 @@ function resolvePostAction(action, row, itemVariable) {
|
|
|
22869
22985
|
function substituteRowPath(template, row, itemVariable) {
|
|
22870
22986
|
const escaped = itemVariable.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
22871
22987
|
const pattern = new RegExp(`\\{\\{\\s*${escaped}\\.([\\w.]+)\\s*\\}\\}`, "g");
|
|
22872
|
-
return template.replace(pattern, (_match,
|
|
22873
|
-
const value = readPath(row,
|
|
22988
|
+
return template.replace(pattern, (_match, path21) => {
|
|
22989
|
+
const value = readPath(row, path21);
|
|
22874
22990
|
if (value === void 0 || value === null) return "";
|
|
22875
22991
|
return String(value);
|
|
22876
22992
|
});
|
|
22877
22993
|
}
|
|
22878
|
-
function readPath(obj,
|
|
22879
|
-
const parts =
|
|
22994
|
+
function readPath(obj, path21) {
|
|
22995
|
+
const parts = path21.split(".");
|
|
22880
22996
|
let current = obj;
|
|
22881
22997
|
for (const part of parts) {
|
|
22882
22998
|
if (current === null || current === void 0) return void 0;
|
|
@@ -23063,14 +23179,14 @@ ${resolvedTemplate}`);
|
|
|
23063
23179
|
return parts.join("");
|
|
23064
23180
|
}
|
|
23065
23181
|
function resolveRowTemplate(template, context) {
|
|
23066
|
-
return template.replace(/\{\{\s*([^}]+)\s*\}\}/g, (_match,
|
|
23067
|
-
const value = readContextPath(context,
|
|
23182
|
+
return template.replace(/\{\{\s*([^}]+)\s*\}\}/g, (_match, path21) => {
|
|
23183
|
+
const value = readContextPath(context, path21.trim());
|
|
23068
23184
|
if (value === void 0 || value === null) return "";
|
|
23069
23185
|
return typeof value === "string" ? value : JSON.stringify(value);
|
|
23070
23186
|
});
|
|
23071
23187
|
}
|
|
23072
|
-
function readContextPath(value,
|
|
23073
|
-
const parts =
|
|
23188
|
+
function readContextPath(value, path21) {
|
|
23189
|
+
const parts = path21.split(".");
|
|
23074
23190
|
let current = value;
|
|
23075
23191
|
for (const part of parts) {
|
|
23076
23192
|
if (current === null || current === void 0) return void 0;
|
|
@@ -24803,7 +24919,7 @@ var init_engine = __esm({
|
|
|
24803
24919
|
init_learning_session();
|
|
24804
24920
|
init_context_builder();
|
|
24805
24921
|
init_cost_estimator();
|
|
24806
|
-
|
|
24922
|
+
init_catalog2();
|
|
24807
24923
|
init_helpers();
|
|
24808
24924
|
init_execution_stats();
|
|
24809
24925
|
}
|
|
@@ -24813,6 +24929,7 @@ var init_engine = __esm({
|
|
|
24813
24929
|
var manifest_trigger_dispatch_exports = {};
|
|
24814
24930
|
__export(manifest_trigger_dispatch_exports, {
|
|
24815
24931
|
dispatchBlueprintForRow: () => dispatchBlueprintForRow,
|
|
24932
|
+
dispatchScheduledBlueprint: () => dispatchScheduledBlueprint,
|
|
24816
24933
|
evaluateManifestTriggers: () => evaluateManifestTriggers
|
|
24817
24934
|
});
|
|
24818
24935
|
async function evaluateManifestTriggers(tableId, rowId, rowData) {
|
|
@@ -24888,6 +25005,41 @@ async function dispatchBlueprintForRow(input) {
|
|
|
24888
25005
|
return null;
|
|
24889
25006
|
}
|
|
24890
25007
|
}
|
|
25008
|
+
async function dispatchScheduledBlueprint(input) {
|
|
25009
|
+
const { appId, blueprintId, scheduleId } = input;
|
|
25010
|
+
try {
|
|
25011
|
+
const { instantiateBlueprint: instantiateBlueprint2 } = await Promise.resolve().then(() => (init_instantiator(), instantiator_exports));
|
|
25012
|
+
const { executeWorkflow: executeWorkflow2 } = await Promise.resolve().then(() => (init_engine(), engine_exports));
|
|
25013
|
+
const { workflowId } = await instantiateBlueprint2(blueprintId, {}, appId);
|
|
25014
|
+
executeWorkflow2(workflowId).catch((err2) => {
|
|
25015
|
+
console.error(
|
|
25016
|
+
`[manifest-trigger-dispatch] executeWorkflow ${workflowId} failed:`,
|
|
25017
|
+
err2
|
|
25018
|
+
);
|
|
25019
|
+
});
|
|
25020
|
+
return { workflowId };
|
|
25021
|
+
} catch (err2) {
|
|
25022
|
+
const message = err2 instanceof Error ? err2.message : String(err2);
|
|
25023
|
+
console.error(
|
|
25024
|
+
`[manifest-trigger-dispatch] scheduled dispatch failed for app=${appId} blueprint=${blueprintId}:`,
|
|
25025
|
+
err2
|
|
25026
|
+
);
|
|
25027
|
+
try {
|
|
25028
|
+
await db.insert(notifications).values({
|
|
25029
|
+
id: crypto.randomUUID(),
|
|
25030
|
+
taskId: null,
|
|
25031
|
+
type: "task_failed",
|
|
25032
|
+
title: `Schedule failure in app "${appId}"`,
|
|
25033
|
+
body: `Blueprint "${blueprintId}" failed for schedule "${scheduleId}": ${message}`,
|
|
25034
|
+
read: false,
|
|
25035
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
25036
|
+
});
|
|
25037
|
+
} catch (nerr) {
|
|
25038
|
+
console.error(`[manifest-trigger-dispatch] notification write failed:`, nerr);
|
|
25039
|
+
}
|
|
25040
|
+
return null;
|
|
25041
|
+
}
|
|
25042
|
+
}
|
|
24891
25043
|
function findMatchingSubscriptions(apps, tableId) {
|
|
24892
25044
|
const out = [];
|
|
24893
25045
|
for (const app of apps) {
|
|
@@ -25430,25 +25582,54 @@ var init_tables = __esm({
|
|
|
25430
25582
|
}
|
|
25431
25583
|
});
|
|
25432
25584
|
|
|
25585
|
+
// src/lib/apps/app-schedule-id.ts
|
|
25586
|
+
var app_schedule_id_exports = {};
|
|
25587
|
+
__export(app_schedule_id_exports, {
|
|
25588
|
+
APP_SCHEDULE_PREFIX: () => APP_SCHEDULE_PREFIX,
|
|
25589
|
+
appScheduleId: () => appScheduleId,
|
|
25590
|
+
isAppScheduleId: () => isAppScheduleId,
|
|
25591
|
+
parseAppScheduleId: () => parseAppScheduleId
|
|
25592
|
+
});
|
|
25593
|
+
function appScheduleId(appId, scheduleId) {
|
|
25594
|
+
return `${APP_SCHEDULE_PREFIX}${appId}:${scheduleId}`;
|
|
25595
|
+
}
|
|
25596
|
+
function isAppScheduleId(id) {
|
|
25597
|
+
return id.startsWith(APP_SCHEDULE_PREFIX);
|
|
25598
|
+
}
|
|
25599
|
+
function parseAppScheduleId(id) {
|
|
25600
|
+
if (!isAppScheduleId(id)) return null;
|
|
25601
|
+
const rest = id.slice(APP_SCHEDULE_PREFIX.length);
|
|
25602
|
+
const sep = rest.indexOf(":");
|
|
25603
|
+
if (sep <= 0 || sep === rest.length - 1) return null;
|
|
25604
|
+
return { appId: rest.slice(0, sep), scheduleId: rest.slice(sep + 1) };
|
|
25605
|
+
}
|
|
25606
|
+
var APP_SCHEDULE_PREFIX;
|
|
25607
|
+
var init_app_schedule_id = __esm({
|
|
25608
|
+
"src/lib/apps/app-schedule-id.ts"() {
|
|
25609
|
+
"use strict";
|
|
25610
|
+
APP_SCHEDULE_PREFIX = "app:";
|
|
25611
|
+
}
|
|
25612
|
+
});
|
|
25613
|
+
|
|
25433
25614
|
// src/lib/packs/install.ts
|
|
25434
25615
|
var install_exports = {};
|
|
25435
25616
|
__export(install_exports, {
|
|
25436
25617
|
installPack: () => installPack
|
|
25437
25618
|
});
|
|
25438
|
-
import
|
|
25439
|
-
import
|
|
25619
|
+
import fs19 from "fs";
|
|
25620
|
+
import path20 from "path";
|
|
25440
25621
|
import os4 from "os";
|
|
25441
25622
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
25442
25623
|
import yaml12 from "js-yaml";
|
|
25443
25624
|
import semver from "semver";
|
|
25444
25625
|
function relayCoreVersion() {
|
|
25445
|
-
if (semver.valid("0.
|
|
25446
|
-
return "0.
|
|
25626
|
+
if (semver.valid("0.19.0")) {
|
|
25627
|
+
return "0.19.0";
|
|
25447
25628
|
}
|
|
25448
25629
|
try {
|
|
25449
25630
|
const root = getAppRoot(import.meta.dirname, 3);
|
|
25450
25631
|
const pkg2 = JSON.parse(
|
|
25451
|
-
|
|
25632
|
+
fs19.readFileSync(path20.join(root, "package.json"), "utf-8")
|
|
25452
25633
|
);
|
|
25453
25634
|
if (pkg2.version && semver.valid(pkg2.version)) return pkg2.version;
|
|
25454
25635
|
} catch {
|
|
@@ -25460,7 +25641,11 @@ async function installPack(source, options = {}) {
|
|
|
25460
25641
|
const profilesDir = options.profilesDir ?? getAinativeProfilesDir();
|
|
25461
25642
|
const blueprintsDir = options.blueprintsDir ?? getAinativeBlueprintsDir();
|
|
25462
25643
|
const coreVersion = options.coreVersion ?? relayCoreVersion();
|
|
25463
|
-
const {
|
|
25644
|
+
const { resolvePackSource: resolvePackSource2 } = await Promise.resolve().then(() => (init_catalog(), catalog_exports));
|
|
25645
|
+
const resolvedSource = resolvePackSource2(source, {
|
|
25646
|
+
templatesDir: options.templatesDir
|
|
25647
|
+
});
|
|
25648
|
+
const { dir: packDir, cleanup } = acquirePack(resolvedSource);
|
|
25464
25649
|
try {
|
|
25465
25650
|
const pack = parsePack(packDir);
|
|
25466
25651
|
if (pack.meta.relayCore) {
|
|
@@ -25486,6 +25671,26 @@ async function installPack(source, options = {}) {
|
|
|
25486
25671
|
}
|
|
25487
25672
|
}
|
|
25488
25673
|
const resolved = resolvePackLayer(pack);
|
|
25674
|
+
const declaredBlueprints = new Set(
|
|
25675
|
+
pack.manifest.blueprints.map((bp) => bp.id)
|
|
25676
|
+
);
|
|
25677
|
+
for (const sched of pack.manifest.schedules) {
|
|
25678
|
+
if (!sched.cron) {
|
|
25679
|
+
throw new PackValidationError(
|
|
25680
|
+
`Manifest schedule "${sched.id}" has no cron expression.`
|
|
25681
|
+
);
|
|
25682
|
+
}
|
|
25683
|
+
if (!sched.runs) {
|
|
25684
|
+
throw new PackValidationError(
|
|
25685
|
+
`Manifest schedule "${sched.id}" has no "runs" blueprint.`
|
|
25686
|
+
);
|
|
25687
|
+
}
|
|
25688
|
+
if (!declaredBlueprints.has(sched.runs)) {
|
|
25689
|
+
throw new PackValidationError(
|
|
25690
|
+
`Manifest schedule "${sched.id}" runs blueprint "${sched.runs}", which the manifest does not declare.`
|
|
25691
|
+
);
|
|
25692
|
+
}
|
|
25693
|
+
}
|
|
25489
25694
|
const { ensureAppProject: ensureAppProject2 } = await Promise.resolve().then(() => (init_compose_integration(), compose_integration_exports));
|
|
25490
25695
|
const { ensureCustomer: ensureCustomer2 } = await Promise.resolve().then(() => (init_customers(), customers_exports));
|
|
25491
25696
|
const { createTable: createTable2, addRows: addRows2, listTables: listTables2 } = await Promise.resolve().then(() => (init_tables(), tables_exports));
|
|
@@ -25536,7 +25741,44 @@ async function installPack(source, options = {}) {
|
|
|
25536
25741
|
});
|
|
25537
25742
|
customersSeeded += 1;
|
|
25538
25743
|
}
|
|
25539
|
-
const
|
|
25744
|
+
const scheduleLogicalToReal = /* @__PURE__ */ new Map();
|
|
25745
|
+
let schedulesRegistered = 0;
|
|
25746
|
+
if (pack.manifest.schedules.length > 0) {
|
|
25747
|
+
const { appScheduleId: appScheduleId2 } = await Promise.resolve().then(() => (init_app_schedule_id(), app_schedule_id_exports));
|
|
25748
|
+
const { installSchedulesFromSpecs: installSchedulesFromSpecs2 } = await Promise.resolve().then(() => (init_installer(), installer_exports));
|
|
25749
|
+
const specs = pack.manifest.schedules.map((sched) => {
|
|
25750
|
+
const compositeId = appScheduleId2(pack.meta.id, sched.id);
|
|
25751
|
+
scheduleLogicalToReal.set(sched.id, compositeId);
|
|
25752
|
+
const name = typeof sched.name === "string" ? sched.name : titleCase3(sched.id);
|
|
25753
|
+
return {
|
|
25754
|
+
id: compositeId,
|
|
25755
|
+
name: `${name} (${pack.meta.id})`,
|
|
25756
|
+
version: pack.meta.version,
|
|
25757
|
+
// Display-only: the scheduler branches on the app: id prefix and
|
|
25758
|
+
// dispatches the blueprint; this prompt is never sent to an agent.
|
|
25759
|
+
prompt: `App schedule for "${pack.meta.id}" \u2014 runs blueprint "${sched.runs}".`,
|
|
25760
|
+
cronExpression: sched.cron,
|
|
25761
|
+
recurs: true,
|
|
25762
|
+
type: "scheduled"
|
|
25763
|
+
};
|
|
25764
|
+
});
|
|
25765
|
+
installSchedulesFromSpecs2(specs);
|
|
25766
|
+
schedulesRegistered = specs.length;
|
|
25767
|
+
const { db: db3 } = await Promise.resolve().then(() => (init_db(), db_exports));
|
|
25768
|
+
const { schedules: schedulesTable } = await Promise.resolve().then(() => (init_schema(), schema_exports));
|
|
25769
|
+
const { and: and24, inArray: inArray7, isNull: isNull7 } = await import("drizzle-orm");
|
|
25770
|
+
db3.update(schedulesTable).set({ projectId: pack.meta.id }).where(
|
|
25771
|
+
and24(
|
|
25772
|
+
inArray7(schedulesTable.id, specs.map((s) => s.id)),
|
|
25773
|
+
isNull7(schedulesTable.projectId)
|
|
25774
|
+
)
|
|
25775
|
+
).run();
|
|
25776
|
+
}
|
|
25777
|
+
const droppedManifest = rewriteTableRefs(
|
|
25778
|
+
pack.manifest,
|
|
25779
|
+
logicalToReal,
|
|
25780
|
+
scheduleLogicalToReal
|
|
25781
|
+
);
|
|
25540
25782
|
if (pack.meta.entitlement) {
|
|
25541
25783
|
droppedManifest.entitlement = pack.meta.entitlement;
|
|
25542
25784
|
}
|
|
@@ -25546,6 +25788,10 @@ async function installPack(source, options = {}) {
|
|
|
25546
25788
|
profilesDir,
|
|
25547
25789
|
blueprintsDir
|
|
25548
25790
|
);
|
|
25791
|
+
if (blueprintsDropped > 0) {
|
|
25792
|
+
const { reloadBlueprints: reloadBlueprints2 } = await Promise.resolve().then(() => (init_registry3(), registry_exports3));
|
|
25793
|
+
reloadBlueprints2();
|
|
25794
|
+
}
|
|
25549
25795
|
return {
|
|
25550
25796
|
packId: pack.meta.id,
|
|
25551
25797
|
packVersion: pack.meta.version,
|
|
@@ -25554,7 +25800,8 @@ async function installPack(source, options = {}) {
|
|
|
25554
25800
|
customersSeeded,
|
|
25555
25801
|
profilesDropped,
|
|
25556
25802
|
blueprintsDropped,
|
|
25557
|
-
rowsSeeded
|
|
25803
|
+
rowsSeeded,
|
|
25804
|
+
schedulesRegistered
|
|
25558
25805
|
};
|
|
25559
25806
|
} finally {
|
|
25560
25807
|
cleanup();
|
|
@@ -25565,25 +25812,25 @@ function isGitUrl(source) {
|
|
|
25565
25812
|
}
|
|
25566
25813
|
function acquirePack(source) {
|
|
25567
25814
|
if (!isGitUrl(source)) {
|
|
25568
|
-
const resolved =
|
|
25569
|
-
if (!
|
|
25815
|
+
const resolved = path20.resolve(source);
|
|
25816
|
+
if (!fs19.existsSync(resolved)) {
|
|
25570
25817
|
throw new PackValidationError(`Pack path does not exist: ${resolved}`);
|
|
25571
25818
|
}
|
|
25572
25819
|
return { dir: resolved, cleanup: () => {
|
|
25573
25820
|
} };
|
|
25574
25821
|
}
|
|
25575
|
-
const tmp =
|
|
25822
|
+
const tmp = fs19.mkdtempSync(path20.join(os4.tmpdir(), "ainative-pack-clone-"));
|
|
25576
25823
|
try {
|
|
25577
25824
|
execFileSync3("git", ["clone", "--depth", "1", source, tmp], {
|
|
25578
25825
|
stdio: "pipe"
|
|
25579
25826
|
});
|
|
25580
25827
|
} catch (err2) {
|
|
25581
|
-
|
|
25828
|
+
fs19.rmSync(tmp, { recursive: true, force: true });
|
|
25582
25829
|
throw new PackValidationError(`git clone failed for ${source}`, err2);
|
|
25583
25830
|
}
|
|
25584
25831
|
return {
|
|
25585
25832
|
dir: tmp,
|
|
25586
|
-
cleanup: () =>
|
|
25833
|
+
cleanup: () => fs19.rmSync(tmp, { recursive: true, force: true })
|
|
25587
25834
|
};
|
|
25588
25835
|
}
|
|
25589
25836
|
function findResolved(files, relPath) {
|
|
@@ -25592,7 +25839,7 @@ function findResolved(files, relPath) {
|
|
|
25592
25839
|
function readCustomerSeed(resolved) {
|
|
25593
25840
|
const file = findResolved(resolved.files, "seed/customers.yaml");
|
|
25594
25841
|
if (!file) return [];
|
|
25595
|
-
const parsed = yaml12.load(
|
|
25842
|
+
const parsed = yaml12.load(fs19.readFileSync(file.absPath, "utf-8"));
|
|
25596
25843
|
if (!Array.isArray(parsed)) {
|
|
25597
25844
|
throw new PackValidationError(
|
|
25598
25845
|
"seed/customers.yaml must be a YAML list of { slug, name, ... }"
|
|
@@ -25604,7 +25851,7 @@ function readTableSeed(resolved, logicalId) {
|
|
|
25604
25851
|
for (const ext of ["json", "yaml", "yml"]) {
|
|
25605
25852
|
const file = findResolved(resolved.files, `seed/tables/${logicalId}.${ext}`);
|
|
25606
25853
|
if (!file) continue;
|
|
25607
|
-
const text2 =
|
|
25854
|
+
const text2 = fs19.readFileSync(file.absPath, "utf-8");
|
|
25608
25855
|
const parsed = ext === "json" ? JSON.parse(text2) : yaml12.load(text2);
|
|
25609
25856
|
if (!Array.isArray(parsed)) {
|
|
25610
25857
|
throw new PackValidationError(
|
|
@@ -25615,33 +25862,46 @@ function readTableSeed(resolved, logicalId) {
|
|
|
25615
25862
|
}
|
|
25616
25863
|
return [];
|
|
25617
25864
|
}
|
|
25618
|
-
function rewriteTableRefs(manifest, logicalToReal) {
|
|
25865
|
+
function rewriteTableRefs(manifest, logicalToReal, scheduleLogicalToReal = /* @__PURE__ */ new Map()) {
|
|
25619
25866
|
const rewritten = {
|
|
25620
25867
|
...manifest,
|
|
25621
25868
|
tables: manifest.tables.map((t) => {
|
|
25622
25869
|
const real2 = logicalToReal.get(t.id);
|
|
25623
25870
|
return real2 ? { ...t, id: real2 } : t;
|
|
25871
|
+
}),
|
|
25872
|
+
// Row-insert triggers bind to tables by the SAME logical id. Dispatch
|
|
25873
|
+
// (manifest-trigger-dispatch) matches trigger.table against the REAL
|
|
25874
|
+
// UUID, so an unrewritten ref silently never fires.
|
|
25875
|
+
blueprints: manifest.blueprints.map((bp) => {
|
|
25876
|
+
const triggerTable = bp.trigger?.table;
|
|
25877
|
+
if (!triggerTable) return bp;
|
|
25878
|
+
const real2 = logicalToReal.get(triggerTable);
|
|
25879
|
+
return real2 ? { ...bp, trigger: { ...bp.trigger, table: real2 } } : bp;
|
|
25880
|
+
}),
|
|
25881
|
+
schedules: manifest.schedules.map((s) => {
|
|
25882
|
+
const real2 = scheduleLogicalToReal.get(s.id);
|
|
25883
|
+
return real2 ? { ...s, id: real2 } : s;
|
|
25624
25884
|
})
|
|
25625
25885
|
};
|
|
25626
25886
|
if (rewritten.view) {
|
|
25627
|
-
rewritten.view =
|
|
25628
|
-
|
|
25629
|
-
|
|
25630
|
-
);
|
|
25887
|
+
rewritten.view = rewriteViewRefs(rewritten.view, {
|
|
25888
|
+
table: logicalToReal,
|
|
25889
|
+
schedule: scheduleLogicalToReal
|
|
25890
|
+
});
|
|
25631
25891
|
}
|
|
25632
25892
|
return rewritten;
|
|
25633
25893
|
}
|
|
25634
|
-
function
|
|
25894
|
+
function rewriteViewRefs(view, maps) {
|
|
25635
25895
|
if (Array.isArray(view)) {
|
|
25636
|
-
return view.map((v) =>
|
|
25896
|
+
return view.map((v) => rewriteViewRefs(v, maps));
|
|
25637
25897
|
}
|
|
25638
25898
|
if (view && typeof view === "object") {
|
|
25639
25899
|
const out = {};
|
|
25640
25900
|
for (const [key, value] of Object.entries(view)) {
|
|
25641
|
-
if (key === "table" && typeof value === "string") {
|
|
25642
|
-
out[key] =
|
|
25901
|
+
if ((key === "table" || key === "schedule") && typeof value === "string") {
|
|
25902
|
+
out[key] = maps[key].get(value) ?? value;
|
|
25643
25903
|
} else {
|
|
25644
|
-
out[key] =
|
|
25904
|
+
out[key] = rewriteViewRefs(value, maps);
|
|
25645
25905
|
}
|
|
25646
25906
|
}
|
|
25647
25907
|
return out;
|
|
@@ -25649,7 +25909,7 @@ function rewriteViewTableRefs(view, logicalToReal) {
|
|
|
25649
25909
|
return view;
|
|
25650
25910
|
}
|
|
25651
25911
|
function writeManifest(appsDir, appId, manifest) {
|
|
25652
|
-
|
|
25912
|
+
fs19.mkdirSync(path20.join(appsDir, appId), { recursive: true });
|
|
25653
25913
|
writeAppManifest(appId, manifest, appsDir);
|
|
25654
25914
|
}
|
|
25655
25915
|
function dropArtifacts(files, profilesDir, blueprintsDir) {
|
|
@@ -25657,18 +25917,18 @@ function dropArtifacts(files, profilesDir, blueprintsDir) {
|
|
|
25657
25917
|
let blueprintsDropped = 0;
|
|
25658
25918
|
for (const file of files) {
|
|
25659
25919
|
if (file.relPath.startsWith("profiles/")) {
|
|
25660
|
-
const dest =
|
|
25661
|
-
|
|
25662
|
-
|
|
25920
|
+
const dest = path20.join(profilesDir, file.relPath.slice("profiles/".length));
|
|
25921
|
+
fs19.mkdirSync(path20.dirname(dest), { recursive: true });
|
|
25922
|
+
fs19.copyFileSync(file.absPath, dest);
|
|
25663
25923
|
const top = file.relPath.split("/")[1];
|
|
25664
25924
|
if (top) profileDirs.add(top);
|
|
25665
25925
|
} else if (file.relPath.startsWith("blueprints/") && file.relPath.endsWith(".yaml")) {
|
|
25666
|
-
const dest =
|
|
25926
|
+
const dest = path20.join(
|
|
25667
25927
|
blueprintsDir,
|
|
25668
25928
|
file.relPath.slice("blueprints/".length)
|
|
25669
25929
|
);
|
|
25670
|
-
|
|
25671
|
-
|
|
25930
|
+
fs19.mkdirSync(path20.dirname(dest), { recursive: true });
|
|
25931
|
+
fs19.copyFileSync(file.absPath, dest);
|
|
25672
25932
|
blueprintsDropped += 1;
|
|
25673
25933
|
}
|
|
25674
25934
|
}
|
|
@@ -25729,7 +25989,7 @@ async function runPackCommand(argv, io) {
|
|
|
25729
25989
|
}
|
|
25730
25990
|
async function runAdd(source, licenseUrl, io) {
|
|
25731
25991
|
if (!source) {
|
|
25732
|
-
io.error("Missing pack
|
|
25992
|
+
io.error("Missing pack source. Usage: relay pack add <name|path|git-url>");
|
|
25733
25993
|
return 1;
|
|
25734
25994
|
}
|
|
25735
25995
|
try {
|
|
@@ -25741,7 +26001,7 @@ async function runAdd(source, licenseUrl, io) {
|
|
|
25741
26001
|
licenseUrl
|
|
25742
26002
|
});
|
|
25743
26003
|
io.log(
|
|
25744
|
-
`Installed ${report.packId}@${report.packVersion}: ${report.projectCreated ? "project created" : "project reused"}, ${report.tablesCreated} table(s) (${report.rowsSeeded} row(s)), ${report.customersSeeded} customer(s), ${report.profilesDropped} profile(s), ${report.blueprintsDropped} blueprint(s).`
|
|
26004
|
+
`Installed ${report.packId}@${report.packVersion}: ${report.projectCreated ? "project created" : "project reused"}, ${report.tablesCreated} table(s) (${report.rowsSeeded} row(s)), ${report.customersSeeded} customer(s), ${report.profilesDropped} profile(s), ${report.blueprintsDropped} blueprint(s), ${report.schedulesRegistered} schedule(s).`
|
|
25745
26005
|
);
|
|
25746
26006
|
return 0;
|
|
25747
26007
|
} catch (err2) {
|
|
@@ -25815,7 +26075,7 @@ var init_cli = __esm({
|
|
|
25815
26075
|
init_ainative_paths();
|
|
25816
26076
|
USAGE = [
|
|
25817
26077
|
"Usage: relay pack <action>",
|
|
25818
|
-
" add <path|git-url> [--license-url=<path|url>] install a pack",
|
|
26078
|
+
" add <name|path|git-url> [--license-url=<path|url>] install a pack",
|
|
25819
26079
|
" list list installed packs",
|
|
25820
26080
|
" remove <id> uninstall a pack",
|
|
25821
26081
|
" update <id> (v1 stub \u2014 editable-seed; edit in place)"
|
|
@@ -26288,10 +26548,10 @@ import { existsSync as existsSync4, renameSync, cpSync, rmSync as rmSync2, readF
|
|
|
26288
26548
|
import { join as join6 } from "path";
|
|
26289
26549
|
import { homedir as homedir2 } from "os";
|
|
26290
26550
|
import Database from "better-sqlite3";
|
|
26291
|
-
function hasSqliteHeader(
|
|
26551
|
+
function hasSqliteHeader(path21) {
|
|
26292
26552
|
const SQLITE_MAGIC = "SQLite format 3\0";
|
|
26293
26553
|
try {
|
|
26294
|
-
const header = readFileSync3(
|
|
26554
|
+
const header = readFileSync3(path21, { encoding: null });
|
|
26295
26555
|
return header.length >= 16 && header.subarray(0, 16).toString("binary") === SQLITE_MAGIC;
|
|
26296
26556
|
} catch {
|
|
26297
26557
|
return false;
|