@rudderhq/cli 0.3.6-canary.9 → 0.4.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/index.js +405 -72
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -572,6 +572,13 @@ var init_constants = __esm({
|
|
|
572
572
|
}
|
|
573
573
|
});
|
|
574
574
|
|
|
575
|
+
// ../packages/shared/dist/agent-run.js
|
|
576
|
+
var init_agent_run = __esm({
|
|
577
|
+
"../packages/shared/dist/agent-run.js"() {
|
|
578
|
+
"use strict";
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
|
|
575
582
|
// ../packages/shared/dist/types/observability.js
|
|
576
583
|
var init_observability = __esm({
|
|
577
584
|
"../packages/shared/dist/types/observability.js"() {
|
|
@@ -784,7 +791,7 @@ var init_adapter_skills = __esm({
|
|
|
784
791
|
|
|
785
792
|
// ../packages/shared/dist/validators/chat.js
|
|
786
793
|
import { z as z4 } from "zod";
|
|
787
|
-
var chatConversationStatusSchema, chatIssueCreationModeSchema, chatMessageRoleSchema, chatMessageKindSchema, chatMessageStatusSchema, chatContextEntityTypeSchema, createChatContextLinkSchema, createChatConversationSchema, setChatProjectContextSchema, updateChatConversationSchema, addChatMessageSchema, chatRichReferenceDisplaySchema, chatIssueIdentifierSchema, chatAskUserIdentifierSchema, chatAskUserOptionSchema, chatAskUserQuestionSchema, chatAskUserRequestSchema, chatIssueRichReferenceSchema, chatIssueCommentRichReferenceSchema, chatRichReferenceSchema, chatRichReferencesSchema, chatAutomationCreateSchema, createChatAttachmentMetadataSchema, chatIssueProposalSchema, convertChatToIssueSchema, chatOperationProposalSchema, resolveChatOperationProposalSchema, updateChatConversationUserStateSchema, updateMessengerThreadUserStateSchema, createMessengerCustomGroupSchema, createMessengerCustomGroupWithEntriesSchema, updateMessengerCustomGroupSchema, reorderMessengerCustomGroupsSchema, assignMessengerCustomGroupEntrySchema, reorderMessengerCustomGroupEntriesSchema;
|
|
794
|
+
var chatConversationStatusSchema, chatIssueCreationModeSchema, chatMessageRoleSchema, chatMessageKindSchema, chatMessageStatusSchema, chatContextEntityTypeSchema, createChatContextLinkSchema, createChatConversationSchema, setChatProjectContextSchema, updateChatConversationSchema, forkChatConversationSchema, addChatMessageSchema, chatQueuedMessagePayloadSchema, createChatQueuedMessageSchema, updateChatQueuedMessageSchema, cancelChatQueuedMessageSchema, steerChatQueuedMessageSchema, chatRichReferenceDisplaySchema, chatIssueIdentifierSchema, chatAskUserIdentifierSchema, chatAskUserOptionSchema, chatAskUserQuestionSchema, chatAskUserRequestSchema, chatIssueRichReferenceSchema, chatIssueCommentRichReferenceSchema, chatRichReferenceSchema, chatRichReferencesSchema, chatAutomationCreateSchema, createChatAttachmentMetadataSchema, chatIssueProposalSchema, convertChatToIssueSchema, chatOperationProposalSchema, resolveChatOperationProposalSchema, updateChatConversationUserStateSchema, updateMessengerThreadUserStateSchema, createMessengerCustomGroupSchema, createMessengerCustomGroupWithEntriesSchema, updateMessengerCustomGroupSchema, reorderMessengerCustomGroupsSchema, assignMessengerCustomGroupEntrySchema, reorderMessengerCustomGroupEntriesSchema;
|
|
788
795
|
var init_chat = __esm({
|
|
789
796
|
"../packages/shared/dist/validators/chat.js"() {
|
|
790
797
|
"use strict";
|
|
@@ -817,9 +824,39 @@ var init_chat = __esm({
|
|
|
817
824
|
primaryIssueId: z4.string().uuid().optional().nullable(),
|
|
818
825
|
resolvedAt: z4.string().datetime().optional().nullable()
|
|
819
826
|
});
|
|
827
|
+
forkChatConversationSchema = z4.object({
|
|
828
|
+
sourceMessageId: z4.string().uuid().optional().nullable(),
|
|
829
|
+
title: z4.string().trim().min(1).max(200).optional()
|
|
830
|
+
});
|
|
820
831
|
addChatMessageSchema = z4.object({
|
|
821
832
|
body: z4.string().trim().min(1).max(2e4),
|
|
822
|
-
editUserMessageId: z4.string().uuid().optional().nullable()
|
|
833
|
+
editUserMessageId: z4.string().uuid().optional().nullable(),
|
|
834
|
+
queuedMessageId: z4.string().uuid().optional().nullable()
|
|
835
|
+
});
|
|
836
|
+
chatQueuedMessagePayloadSchema = z4.object({
|
|
837
|
+
body: z4.string().trim().min(1).max(2e4),
|
|
838
|
+
attachmentIds: z4.array(z4.string().uuid()).optional().default([]),
|
|
839
|
+
projectId: z4.string().uuid().optional().nullable(),
|
|
840
|
+
skillRefs: z4.array(z4.string().trim().min(1).max(240)).optional().default([]),
|
|
841
|
+
accessMode: z4.string().trim().min(1).max(120).optional().nullable(),
|
|
842
|
+
model: z4.string().trim().min(1).max(120).optional().nullable(),
|
|
843
|
+
effort: z4.string().trim().min(1).max(120).optional().nullable(),
|
|
844
|
+
metadata: z4.record(z4.unknown()).optional().nullable()
|
|
845
|
+
});
|
|
846
|
+
createChatQueuedMessageSchema = z4.object({
|
|
847
|
+
clientMutationId: z4.string().trim().min(1).max(120),
|
|
848
|
+
expectedGenerationId: z4.string().uuid().optional().nullable(),
|
|
849
|
+
payload: chatQueuedMessagePayloadSchema
|
|
850
|
+
});
|
|
851
|
+
updateChatQueuedMessageSchema = z4.object({
|
|
852
|
+
version: z4.number().int().positive(),
|
|
853
|
+
payload: chatQueuedMessagePayloadSchema
|
|
854
|
+
});
|
|
855
|
+
cancelChatQueuedMessageSchema = z4.object({
|
|
856
|
+
version: z4.number().int().positive().optional()
|
|
857
|
+
});
|
|
858
|
+
steerChatQueuedMessageSchema = z4.object({
|
|
859
|
+
expectedActiveGenerationId: z4.string().uuid().optional().nullable()
|
|
823
860
|
});
|
|
824
861
|
chatRichReferenceDisplaySchema = z4.enum(["card", "inline"]);
|
|
825
862
|
chatIssueIdentifierSchema = z4.string().trim().min(1).max(64).regex(/^[A-Z0-9][A-Z0-9-]*$/i);
|
|
@@ -972,12 +1009,14 @@ var init_chat = __esm({
|
|
|
972
1009
|
icon: z4.string().trim().min(1).max(24).optional().nullable()
|
|
973
1010
|
});
|
|
974
1011
|
createMessengerCustomGroupWithEntriesSchema = createMessengerCustomGroupSchema.extend({
|
|
975
|
-
threadKeys: z4.array(z4.string().trim().min(1).max(240)).min(1).max(50)
|
|
1012
|
+
threadKeys: z4.array(z4.string().trim().min(1).max(240)).min(1).max(50),
|
|
1013
|
+
autoGenerateName: z4.boolean().optional()
|
|
976
1014
|
});
|
|
977
1015
|
updateMessengerCustomGroupSchema = z4.object({
|
|
978
1016
|
name: z4.string().trim().min(1).max(80).optional(),
|
|
979
1017
|
icon: z4.string().trim().min(1).max(24).optional().nullable(),
|
|
980
1018
|
collapsed: z4.boolean().optional(),
|
|
1019
|
+
pinned: z4.boolean().optional(),
|
|
981
1020
|
sortOrder: z4.number().int().min(0).optional()
|
|
982
1021
|
});
|
|
983
1022
|
reorderMessengerCustomGroupsSchema = z4.object({
|
|
@@ -2985,6 +3024,7 @@ var init_api = __esm({
|
|
|
2985
3024
|
secrets: `${API_PREFIX}/secrets`,
|
|
2986
3025
|
costs: `${API_PREFIX}/costs`,
|
|
2987
3026
|
activity: `${API_PREFIX}/activity`,
|
|
3027
|
+
agentRuns: `${API_PREFIX}/agent-runs`,
|
|
2988
3028
|
dashboard: `${API_PREFIX}/dashboard`,
|
|
2989
3029
|
sidebarBadges: `${API_PREFIX}/sidebar-badges`,
|
|
2990
3030
|
invites: `${API_PREFIX}/invites`,
|
|
@@ -3260,6 +3300,7 @@ var init_dist = __esm({
|
|
|
3260
3300
|
"../packages/shared/dist/index.js"() {
|
|
3261
3301
|
"use strict";
|
|
3262
3302
|
init_constants();
|
|
3303
|
+
init_agent_run();
|
|
3263
3304
|
init_observability();
|
|
3264
3305
|
init_workspace_backup();
|
|
3265
3306
|
init_validators();
|
|
@@ -3491,8 +3532,8 @@ var init_env = __esm({
|
|
|
3491
3532
|
});
|
|
3492
3533
|
|
|
3493
3534
|
// src/runtime/install.ts
|
|
3494
|
-
import { spawnSync } from "node:child_process";
|
|
3495
|
-
import { mkdir, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
|
|
3535
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
3536
|
+
import { cp, mkdir, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
|
|
3496
3537
|
import { createRequire } from "node:module";
|
|
3497
3538
|
import path4 from "node:path";
|
|
3498
3539
|
import { pathToFileURL } from "node:url";
|
|
@@ -3561,23 +3602,6 @@ async function hasRequiredRuntimePlatformDependencies(cacheDir) {
|
|
|
3561
3602
|
if (!platformPackage) return true;
|
|
3562
3603
|
return await canResolveRuntimePackage(cacheDir, platformPackage);
|
|
3563
3604
|
}
|
|
3564
|
-
async function assertRequiredRuntimePlatformDependencies(cacheDir, command, output) {
|
|
3565
|
-
if (!await canResolveRuntimePackage(cacheDir, EMBEDDED_POSTGRES_PACKAGE_NAME)) return;
|
|
3566
|
-
const platformPackage = resolveEmbeddedPostgresPlatformPackage();
|
|
3567
|
-
if (!platformPackage || await canResolveRuntimePackage(cacheDir, platformPackage)) return;
|
|
3568
|
-
throw new RuntimeInstallError(
|
|
3569
|
-
`Rudder runtime installation is missing required platform package ${platformPackage}. Re-run manually: ${command}`,
|
|
3570
|
-
{
|
|
3571
|
-
cacheDir,
|
|
3572
|
-
command,
|
|
3573
|
-
output: [
|
|
3574
|
-
output,
|
|
3575
|
-
`Missing required optional dependency: ${platformPackage}`,
|
|
3576
|
-
"Your npm registry, mirror, proxy, or cache may have skipped the embedded PostgreSQL platform package."
|
|
3577
|
-
].filter((line) => line.trim().length > 0).join("\n")
|
|
3578
|
-
}
|
|
3579
|
-
);
|
|
3580
|
-
}
|
|
3581
3605
|
async function isRuntimeCacheHit(options) {
|
|
3582
3606
|
const packageName = options.packageName ?? RUNTIME_NPM_PACKAGE_NAME;
|
|
3583
3607
|
const packageVersion = resolveRuntimePackageVersion(options.version);
|
|
@@ -3600,7 +3624,9 @@ async function ensureRuntimeInstalled(options) {
|
|
|
3600
3624
|
const cacheDir = resolveRuntimeCacheDir(packageVersion, options.homeDir);
|
|
3601
3625
|
const packageSpec = resolveRuntimePackageSpec(packageVersion, packageName);
|
|
3602
3626
|
const command = formatRuntimeInstallCommand(cacheDir, packageSpec);
|
|
3627
|
+
const preparePostgresPayload = options.preparePostgresPayload === true;
|
|
3603
3628
|
if (await isRuntimeCacheHit({ cacheDir, version: packageVersion, packageName })) {
|
|
3629
|
+
const postgresPayload2 = await stageRuntimePostgresPayload(cacheDir, preparePostgresPayload);
|
|
3604
3630
|
await touchRuntimeInstallMetadata(cacheDir);
|
|
3605
3631
|
const prune2 = await maybePruneRuntimeCache({
|
|
3606
3632
|
homeDir: options.homeDir,
|
|
@@ -3608,37 +3634,75 @@ async function ensureRuntimeInstalled(options) {
|
|
|
3608
3634
|
enabled: options.pruneRuntimeCache !== false,
|
|
3609
3635
|
retention: options.retention
|
|
3610
3636
|
});
|
|
3611
|
-
return
|
|
3637
|
+
return withPostgresPayload(
|
|
3638
|
+
{ status: "hit", cacheDir, packageSpec, command, output: "", ...prune2 ? { prune: prune2 } : {} },
|
|
3639
|
+
postgresPayload2
|
|
3640
|
+
);
|
|
3641
|
+
}
|
|
3642
|
+
const spawnSyncImpl = options.spawnSyncImpl ?? spawnSync;
|
|
3643
|
+
const existingRuntimeOutput = await tryRepairExistingRuntimePackage({
|
|
3644
|
+
spawnSyncImpl,
|
|
3645
|
+
cacheDir,
|
|
3646
|
+
packageName,
|
|
3647
|
+
packageVersion
|
|
3648
|
+
});
|
|
3649
|
+
if (existingRuntimeOutput !== null) {
|
|
3650
|
+
const postgresPayload2 = await stageRuntimePostgresPayload(cacheDir, preparePostgresPayload);
|
|
3651
|
+
const metadata2 = {
|
|
3652
|
+
version: 1,
|
|
3653
|
+
packageName,
|
|
3654
|
+
packageVersion,
|
|
3655
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3656
|
+
lastUsedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3657
|
+
};
|
|
3658
|
+
await writeRuntimeInstallMetadata(cacheDir, metadata2);
|
|
3659
|
+
const prune2 = await maybePruneRuntimeCache({
|
|
3660
|
+
homeDir: options.homeDir,
|
|
3661
|
+
requestedVersion: packageVersion,
|
|
3662
|
+
enabled: options.pruneRuntimeCache !== false,
|
|
3663
|
+
retention: options.retention
|
|
3664
|
+
});
|
|
3665
|
+
return withPostgresPayload(
|
|
3666
|
+
{ status: "installed", cacheDir, packageSpec, command, output: existingRuntimeOutput, ...prune2 ? { prune: prune2 } : {} },
|
|
3667
|
+
postgresPayload2
|
|
3668
|
+
);
|
|
3612
3669
|
}
|
|
3613
3670
|
await rm(cacheDir, { recursive: true, force: true });
|
|
3614
3671
|
await mkdir(cacheDir, { recursive: true });
|
|
3615
|
-
await writeFile(path4.join(cacheDir, "package.json"), `${JSON.stringify(
|
|
3672
|
+
await writeFile(path4.join(cacheDir, "package.json"), `${JSON.stringify(RUNTIME_CACHE_PACKAGE_JSON, null, 2)}
|
|
3616
3673
|
`, "utf8");
|
|
3617
|
-
const spawnSyncImpl = options.spawnSyncImpl ?? spawnSync;
|
|
3618
3674
|
const result = runNpmRuntimeInstall(spawnSyncImpl, cacheDir, packageSpec);
|
|
3619
|
-
|
|
3675
|
+
let output = collectSpawnOutput(result);
|
|
3620
3676
|
if (result.status !== 0 && packageVersion !== "latest" && isVersionNotFoundError(output)) {
|
|
3621
3677
|
const fallbackVersion = "latest";
|
|
3622
3678
|
const fallbackCacheDir = resolveRuntimeCacheDir(fallbackVersion, options.homeDir);
|
|
3623
3679
|
const fallbackSpec = resolveRuntimePackageSpec(fallbackVersion, packageName);
|
|
3624
3680
|
if (await isRuntimeCacheHit({ cacheDir: fallbackCacheDir, version: fallbackVersion, packageName })) {
|
|
3681
|
+
const fallbackPostgresPayload = await stageRuntimePostgresPayload(fallbackCacheDir, preparePostgresPayload);
|
|
3625
3682
|
await touchRuntimeInstallMetadata(fallbackCacheDir);
|
|
3626
|
-
return
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3683
|
+
return withPostgresPayload(
|
|
3684
|
+
{
|
|
3685
|
+
status: "hit",
|
|
3686
|
+
cacheDir: fallbackCacheDir,
|
|
3687
|
+
packageSpec: fallbackSpec,
|
|
3688
|
+
command: formatRuntimeInstallCommand(fallbackCacheDir, fallbackSpec),
|
|
3689
|
+
output: ""
|
|
3690
|
+
},
|
|
3691
|
+
fallbackPostgresPayload
|
|
3692
|
+
);
|
|
3633
3693
|
}
|
|
3634
3694
|
await rm(fallbackCacheDir, { recursive: true, force: true });
|
|
3635
3695
|
await mkdir(fallbackCacheDir, { recursive: true });
|
|
3636
|
-
await writeFile(path4.join(fallbackCacheDir, "package.json"), `${JSON.stringify(
|
|
3696
|
+
await writeFile(path4.join(fallbackCacheDir, "package.json"), `${JSON.stringify(RUNTIME_CACHE_PACKAGE_JSON, null, 2)}
|
|
3637
3697
|
`, "utf8");
|
|
3638
3698
|
const fallbackResult = runNpmRuntimeInstall(spawnSyncImpl, fallbackCacheDir, fallbackSpec);
|
|
3639
|
-
|
|
3699
|
+
let fallbackOutput = collectSpawnOutput(fallbackResult);
|
|
3640
3700
|
if (fallbackResult.status === 0) {
|
|
3641
|
-
|
|
3701
|
+
fallbackOutput = collectOutputParts(
|
|
3702
|
+
fallbackOutput,
|
|
3703
|
+
await ensureRequiredEmbeddedPostgresPlatformPackage(spawnSyncImpl, fallbackCacheDir)
|
|
3704
|
+
);
|
|
3705
|
+
const postgresPayload2 = await stageRuntimePostgresPayload(fallbackCacheDir, preparePostgresPayload);
|
|
3642
3706
|
const fallbackMetadata = {
|
|
3643
3707
|
version: 1,
|
|
3644
3708
|
packageName,
|
|
@@ -3647,13 +3711,16 @@ async function ensureRuntimeInstalled(options) {
|
|
|
3647
3711
|
lastUsedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3648
3712
|
};
|
|
3649
3713
|
await writeRuntimeInstallMetadata(fallbackCacheDir, fallbackMetadata);
|
|
3650
|
-
return
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3714
|
+
return withPostgresPayload(
|
|
3715
|
+
{
|
|
3716
|
+
status: "installed",
|
|
3717
|
+
cacheDir: fallbackCacheDir,
|
|
3718
|
+
packageSpec: fallbackSpec,
|
|
3719
|
+
command: formatRuntimeInstallCommand(fallbackCacheDir, fallbackSpec),
|
|
3720
|
+
output: fallbackOutput
|
|
3721
|
+
},
|
|
3722
|
+
postgresPayload2
|
|
3723
|
+
);
|
|
3657
3724
|
}
|
|
3658
3725
|
}
|
|
3659
3726
|
if (result.status !== 0) {
|
|
@@ -3662,7 +3729,11 @@ async function ensureRuntimeInstalled(options) {
|
|
|
3662
3729
|
{ cacheDir, command, output }
|
|
3663
3730
|
);
|
|
3664
3731
|
}
|
|
3665
|
-
|
|
3732
|
+
output = collectOutputParts(
|
|
3733
|
+
output,
|
|
3734
|
+
await ensureRequiredEmbeddedPostgresPlatformPackage(spawnSyncImpl, cacheDir)
|
|
3735
|
+
);
|
|
3736
|
+
const postgresPayload = await stageRuntimePostgresPayload(cacheDir, preparePostgresPayload);
|
|
3666
3737
|
const metadata = {
|
|
3667
3738
|
version: 1,
|
|
3668
3739
|
packageName,
|
|
@@ -3677,7 +3748,13 @@ async function ensureRuntimeInstalled(options) {
|
|
|
3677
3748
|
enabled: options.pruneRuntimeCache !== false,
|
|
3678
3749
|
retention: options.retention
|
|
3679
3750
|
});
|
|
3680
|
-
return
|
|
3751
|
+
return withPostgresPayload(
|
|
3752
|
+
{ status: "installed", cacheDir, packageSpec, command, output, ...prune ? { prune } : {} },
|
|
3753
|
+
postgresPayload
|
|
3754
|
+
);
|
|
3755
|
+
}
|
|
3756
|
+
function resolveRuntimePostgresPayloadBinDir(cacheDir, platform = process.platform, arch = process.arch) {
|
|
3757
|
+
return path4.join(cacheDir, RUNTIME_POSTGRES_PAYLOAD_DIR, runtimePostgresPlatformSegment(platform, arch), "bin");
|
|
3681
3758
|
}
|
|
3682
3759
|
function resolveRuntimeServerEntrypoint(cacheDir, packageName = RUNTIME_NPM_PACKAGE_NAME) {
|
|
3683
3760
|
return createRequire(path4.join(cacheDir, "package.json")).resolve(packageName);
|
|
@@ -3700,9 +3777,204 @@ function runNpmRuntimeInstall(spawnSyncImpl, cacheDir, packageSpec) {
|
|
|
3700
3777
|
function formatRuntimeInstallCommand(cacheDir, packageSpec) {
|
|
3701
3778
|
return `npm install --prefix ${cacheDir} ${RUNTIME_NPM_INSTALL_FLAGS.join(" ")} ${packageSpec}`;
|
|
3702
3779
|
}
|
|
3780
|
+
function formatRuntimePlatformRepairCommand(cacheDir, packageSpec) {
|
|
3781
|
+
return `npm pack ${packageSpec} --registry=${NPM_PUBLIC_REGISTRY_URL} --silent, then extract it into ${path4.join(cacheDir, "node_modules")}`;
|
|
3782
|
+
}
|
|
3703
3783
|
function collectSpawnOutput(result) {
|
|
3704
3784
|
return [result.stdout, result.stderr, result.error instanceof Error ? result.error.message : null].filter((value) => typeof value === "string" && value.trim().length > 0).join("\n").trim();
|
|
3705
3785
|
}
|
|
3786
|
+
function collectOutputParts(...parts) {
|
|
3787
|
+
return parts.filter((part) => part.trim().length > 0).join("\n").trim();
|
|
3788
|
+
}
|
|
3789
|
+
function withPostgresPayload(result, postgresPayload) {
|
|
3790
|
+
return {
|
|
3791
|
+
...result,
|
|
3792
|
+
output: collectOutputParts(result.output, postgresPayload.output),
|
|
3793
|
+
...postgresPayload.binDir ? { postgresPayloadBinDir: postgresPayload.binDir } : {}
|
|
3794
|
+
};
|
|
3795
|
+
}
|
|
3796
|
+
function runtimePackageJsonPath(cacheDir, packageName) {
|
|
3797
|
+
return path4.join(cacheDir, "node_modules", ...packageName.split("/"), "package.json");
|
|
3798
|
+
}
|
|
3799
|
+
async function readRuntimePackageJson(cacheDir, packageName) {
|
|
3800
|
+
try {
|
|
3801
|
+
return JSON.parse(await readFile(runtimePackageJsonPath(cacheDir, packageName), "utf8"));
|
|
3802
|
+
} catch {
|
|
3803
|
+
return null;
|
|
3804
|
+
}
|
|
3805
|
+
}
|
|
3806
|
+
async function tryRepairExistingRuntimePackage(options) {
|
|
3807
|
+
const runtimePackage = await readRuntimePackageJson(options.cacheDir, options.packageName);
|
|
3808
|
+
if (!runtimePackage) return null;
|
|
3809
|
+
if (options.packageVersion !== "latest" && runtimePackage.version !== options.packageVersion) return null;
|
|
3810
|
+
const output = await ensureRequiredEmbeddedPostgresPlatformPackage(options.spawnSyncImpl, options.cacheDir);
|
|
3811
|
+
return await hasRequiredRuntimePlatformDependencies(options.cacheDir) ? output : null;
|
|
3812
|
+
}
|
|
3813
|
+
async function resolveEmbeddedPostgresPlatformPackageSpec(cacheDir) {
|
|
3814
|
+
if (!await canResolveRuntimePackage(cacheDir, EMBEDDED_POSTGRES_PACKAGE_NAME)) return null;
|
|
3815
|
+
const packageName = resolveEmbeddedPostgresPlatformPackage();
|
|
3816
|
+
if (!packageName) return null;
|
|
3817
|
+
const embeddedPostgresPackage = await readRuntimePackageJson(cacheDir, EMBEDDED_POSTGRES_PACKAGE_NAME);
|
|
3818
|
+
const versionRange = embeddedPostgresPackage?.optionalDependencies?.[packageName];
|
|
3819
|
+
const packageVersion = normalizeOptionalDependencyVersion(versionRange);
|
|
3820
|
+
return packageVersion ? `${packageName}@${packageVersion}` : packageName;
|
|
3821
|
+
}
|
|
3822
|
+
async function ensureRequiredEmbeddedPostgresPlatformPackage(spawnSyncImpl, cacheDir) {
|
|
3823
|
+
const packageSpec = await resolveEmbeddedPostgresPlatformPackageSpec(cacheDir);
|
|
3824
|
+
if (!packageSpec) return "";
|
|
3825
|
+
const packageName = packageNameFromSpec(packageSpec);
|
|
3826
|
+
if (packageName && await canResolveRuntimePackage(cacheDir, packageName)) return "";
|
|
3827
|
+
await removeRuntimeInstallLocks(cacheDir);
|
|
3828
|
+
const result = await installRuntimePackageInStaging(spawnSyncImpl, cacheDir, packageSpec, packageName);
|
|
3829
|
+
const output = collectSpawnOutput(result);
|
|
3830
|
+
if (result.status === 0 && packageName && await canResolveRuntimePackage(cacheDir, packageName)) {
|
|
3831
|
+
return output;
|
|
3832
|
+
}
|
|
3833
|
+
const command = formatRuntimePlatformRepairCommand(cacheDir, packageSpec);
|
|
3834
|
+
throw new RuntimeInstallError(
|
|
3835
|
+
`Rudder runtime installation is missing required platform package ${packageName || packageSpec}. Re-run manually: ${command}`,
|
|
3836
|
+
{ cacheDir, command, output }
|
|
3837
|
+
);
|
|
3838
|
+
}
|
|
3839
|
+
async function installRuntimePackageInStaging(spawnSyncImpl, cacheDir, packageSpec, packageName) {
|
|
3840
|
+
const stagingDir = path4.join(cacheDir, `.platform-repair-${process.pid}-${Date.now()}`);
|
|
3841
|
+
await mkdir(stagingDir, { recursive: true });
|
|
3842
|
+
try {
|
|
3843
|
+
const packResult = runNpmPack(spawnSyncImpl, packageSpec, stagingDir);
|
|
3844
|
+
if (packResult.status !== 0) return packResult;
|
|
3845
|
+
const packFilename = parseNpmPackFilename(packResult.stdout);
|
|
3846
|
+
if (!packFilename) {
|
|
3847
|
+
return createSyntheticSpawnResult(1, "", `Unable to parse npm pack output for ${packageSpec}.`);
|
|
3848
|
+
}
|
|
3849
|
+
const archivePath = path4.join(stagingDir, packFilename);
|
|
3850
|
+
const targetDir = path4.dirname(runtimePackageJsonPath(cacheDir, packageName));
|
|
3851
|
+
await mkdir(path4.dirname(targetDir), { recursive: true });
|
|
3852
|
+
await rm(targetDir, { recursive: true, force: true });
|
|
3853
|
+
await mkdir(targetDir, { recursive: true });
|
|
3854
|
+
const extractResult = runTarExtract(spawnSyncImpl, archivePath, targetDir);
|
|
3855
|
+
return combineSpawnResults(packResult, extractResult);
|
|
3856
|
+
} finally {
|
|
3857
|
+
await rm(stagingDir, { recursive: true, force: true });
|
|
3858
|
+
}
|
|
3859
|
+
}
|
|
3860
|
+
function runNpmPack(spawnSyncImpl, packageSpec, destinationDir) {
|
|
3861
|
+
return spawnSyncImpl(
|
|
3862
|
+
process.platform === "win32" ? "npm.cmd" : "npm",
|
|
3863
|
+
["pack", packageSpec, "--pack-destination", destinationDir, ...RUNTIME_NPM_PACK_FLAGS],
|
|
3864
|
+
{
|
|
3865
|
+
encoding: "utf8",
|
|
3866
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
3867
|
+
env: { ...process.env, ...NPM_PLATFORM_REPAIR_ENV },
|
|
3868
|
+
...process.platform === "win32" ? { shell: true, windowsHide: true } : {}
|
|
3869
|
+
}
|
|
3870
|
+
);
|
|
3871
|
+
}
|
|
3872
|
+
function runTarExtract(spawnSyncImpl, archivePath, targetDir) {
|
|
3873
|
+
return spawnSyncImpl(
|
|
3874
|
+
"tar",
|
|
3875
|
+
["-xzf", archivePath, "-C", targetDir, "--strip-components", "1"],
|
|
3876
|
+
{
|
|
3877
|
+
encoding: "utf8",
|
|
3878
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
3879
|
+
...process.platform === "win32" ? { windowsHide: true } : {}
|
|
3880
|
+
}
|
|
3881
|
+
);
|
|
3882
|
+
}
|
|
3883
|
+
function parseNpmPackFilename(stdout) {
|
|
3884
|
+
if (typeof stdout !== "string") return null;
|
|
3885
|
+
const filename = stdout.trim().split(/\r?\n/).filter(Boolean).at(-1);
|
|
3886
|
+
return filename?.endsWith(".tgz") ? filename : null;
|
|
3887
|
+
}
|
|
3888
|
+
function createSyntheticSpawnResult(status, stdout, stderr) {
|
|
3889
|
+
return { status, stdout, stderr };
|
|
3890
|
+
}
|
|
3891
|
+
function combineSpawnResults(...results) {
|
|
3892
|
+
const last = results.at(-1);
|
|
3893
|
+
return {
|
|
3894
|
+
status: last?.status ?? 0,
|
|
3895
|
+
stdout: results.map((result) => result.stdout).filter(Boolean).join("\n"),
|
|
3896
|
+
stderr: results.map((result) => result.stderr).filter(Boolean).join("\n"),
|
|
3897
|
+
error: results.find((result) => result.error)?.error
|
|
3898
|
+
};
|
|
3899
|
+
}
|
|
3900
|
+
async function removeRuntimeInstallLocks(cacheDir) {
|
|
3901
|
+
await Promise.all([
|
|
3902
|
+
rm(path4.join(cacheDir, "package-lock.json"), { force: true }),
|
|
3903
|
+
rm(path4.join(cacheDir, "node_modules", ".package-lock.json"), { force: true })
|
|
3904
|
+
]);
|
|
3905
|
+
}
|
|
3906
|
+
function packageNameFromSpec(packageSpec) {
|
|
3907
|
+
if (!packageSpec.startsWith("@")) {
|
|
3908
|
+
const versionSeparator2 = packageSpec.indexOf("@");
|
|
3909
|
+
return versionSeparator2 === -1 ? packageSpec : packageSpec.slice(0, versionSeparator2);
|
|
3910
|
+
}
|
|
3911
|
+
const versionSeparator = packageSpec.indexOf("@", 1);
|
|
3912
|
+
return versionSeparator === -1 ? packageSpec : packageSpec.slice(0, versionSeparator);
|
|
3913
|
+
}
|
|
3914
|
+
function normalizeOptionalDependencyVersion(versionRange) {
|
|
3915
|
+
const trimmed = versionRange?.trim();
|
|
3916
|
+
if (!trimmed) return null;
|
|
3917
|
+
const exactVersion = /^[~^]\s*([0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);
|
|
3918
|
+
return exactVersion?.[1] ?? trimmed;
|
|
3919
|
+
}
|
|
3920
|
+
function runtimePostgresPlatformSegment(platform = process.platform, arch = process.arch) {
|
|
3921
|
+
return `${platform}-${arch}`;
|
|
3922
|
+
}
|
|
3923
|
+
function runtimePostgresExecutableName(baseName) {
|
|
3924
|
+
return process.platform === "win32" ? `${baseName}.exe` : baseName;
|
|
3925
|
+
}
|
|
3926
|
+
async function assertRuntimePostgresBinDirComplete(cacheDir, binDir) {
|
|
3927
|
+
const requiredBinaries = ["initdb", "pg_ctl", "postgres"];
|
|
3928
|
+
const missing = [];
|
|
3929
|
+
for (const binary of requiredBinaries) {
|
|
3930
|
+
const binaryPath = path4.join(binDir, runtimePostgresExecutableName(binary));
|
|
3931
|
+
try {
|
|
3932
|
+
await stat(binaryPath);
|
|
3933
|
+
} catch {
|
|
3934
|
+
missing.push(binaryPath);
|
|
3935
|
+
}
|
|
3936
|
+
}
|
|
3937
|
+
if (missing.length > 0) {
|
|
3938
|
+
throw new RuntimeInstallError(
|
|
3939
|
+
`${RUDDER_POSTGRES_BIN_DIR_ENV} must contain PostgreSQL 18.4 initdb, pg_ctl, and postgres binaries; missing ${missing.join(", ")}`,
|
|
3940
|
+
{ cacheDir, command: "validate PostgreSQL 18.4 runtime payload", output: "" }
|
|
3941
|
+
);
|
|
3942
|
+
}
|
|
3943
|
+
}
|
|
3944
|
+
async function isRuntimePostgresPayloadUsable(cacheDir, binDir) {
|
|
3945
|
+
try {
|
|
3946
|
+
await assertRuntimePostgresBinDirComplete(cacheDir, binDir);
|
|
3947
|
+
const postgresBinary = path4.join(binDir, runtimePostgresExecutableName("postgres"));
|
|
3948
|
+
const result = execFileSync(postgresBinary, ["--version"], { encoding: "utf8" });
|
|
3949
|
+
return /\bPostgreSQL\)?\s+18\.4\b/i.test(result);
|
|
3950
|
+
} catch {
|
|
3951
|
+
return false;
|
|
3952
|
+
}
|
|
3953
|
+
}
|
|
3954
|
+
async function stageRuntimePostgresPayload(cacheDir, enabled) {
|
|
3955
|
+
const targetRuntimeDir = path4.join(cacheDir, RUNTIME_POSTGRES_PAYLOAD_DIR);
|
|
3956
|
+
const targetBinDir = resolveRuntimePostgresPayloadBinDir(cacheDir);
|
|
3957
|
+
if (await isRuntimePostgresPayloadUsable(cacheDir, targetBinDir)) {
|
|
3958
|
+
return { output: "", binDir: targetBinDir };
|
|
3959
|
+
}
|
|
3960
|
+
if (!enabled) return { output: "" };
|
|
3961
|
+
const sourceBinDir = process.env[RUDDER_POSTGRES_BIN_DIR_ENV]?.trim();
|
|
3962
|
+
if (!sourceBinDir) return { output: "" };
|
|
3963
|
+
const resolvedSourceBinDir = path4.resolve(sourceBinDir);
|
|
3964
|
+
await assertRuntimePostgresBinDirComplete(cacheDir, resolvedSourceBinDir);
|
|
3965
|
+
const postgresBinary = path4.join(resolvedSourceBinDir, runtimePostgresExecutableName("postgres"));
|
|
3966
|
+
const result = execFileSync(postgresBinary, ["--version"], { encoding: "utf8" });
|
|
3967
|
+
if (!/\bPostgreSQL\)?\s+18\.4\b/i.test(result)) {
|
|
3968
|
+
throw new RuntimeInstallError(
|
|
3969
|
+
`${RUDDER_POSTGRES_BIN_DIR_ENV} must contain PostgreSQL 18.4 production binaries; got ${result.trim() || "unknown version"}`,
|
|
3970
|
+
{ cacheDir, command: `${postgresBinary} --version`, output: result }
|
|
3971
|
+
);
|
|
3972
|
+
}
|
|
3973
|
+
await rm(targetRuntimeDir, { recursive: true, force: true });
|
|
3974
|
+
await mkdir(path4.dirname(targetBinDir), { recursive: true });
|
|
3975
|
+
await cp(resolvedSourceBinDir, targetBinDir, { recursive: true });
|
|
3976
|
+
return { output: `staged PostgreSQL 18.4 runtime payload at ${targetBinDir}`, binDir: targetBinDir };
|
|
3977
|
+
}
|
|
3706
3978
|
function isVersionNotFoundError(output) {
|
|
3707
3979
|
const normalized = output.toLowerCase();
|
|
3708
3980
|
return normalized.includes("enoent") || normalized.includes("etarget") || normalized.includes("no matching version found");
|
|
@@ -3928,19 +4200,34 @@ function parseRuntimeVersion(version) {
|
|
|
3928
4200
|
canaryNumber: canaryMatch ? Number(canaryMatch[1]) : null
|
|
3929
4201
|
};
|
|
3930
4202
|
}
|
|
3931
|
-
var RUNTIME_NPM_PACKAGE_NAME, RUNTIME_METADATA_FILE, DEFAULT_RUNTIME_CACHE_MAX_ENTRIES, DEFAULT_RUNTIME_CACHE_MAX_AGE_MS, DEFAULT_RUNTIME_CACHE_MAX_BYTES, DEFAULT_RUNTIME_CACHE_KEEP_PREVIOUS, RUNTIME_NPM_INSTALL_FLAGS, EMBEDDED_POSTGRES_PACKAGE_NAME, RuntimeInstallError;
|
|
4203
|
+
var RUNTIME_NPM_PACKAGE_NAME, NPM_PUBLIC_REGISTRY_URL, RUNTIME_METADATA_FILE, RUNTIME_POSTGRES_PAYLOAD_DIR, DEFAULT_RUNTIME_CACHE_MAX_ENTRIES, DEFAULT_RUNTIME_CACHE_MAX_AGE_MS, DEFAULT_RUNTIME_CACHE_MAX_BYTES, DEFAULT_RUNTIME_CACHE_KEEP_PREVIOUS, RUNTIME_NPM_INSTALL_FLAGS, RUNTIME_NPM_PACK_FLAGS, EMBEDDED_POSTGRES_PACKAGE_NAME, RUDDER_POSTGRES_BIN_DIR_ENV, RUNTIME_CACHE_PACKAGE_JSON, NPM_PLATFORM_REPAIR_ENV, RuntimeInstallError;
|
|
3932
4204
|
var init_install = __esm({
|
|
3933
4205
|
"src/runtime/install.ts"() {
|
|
3934
4206
|
"use strict";
|
|
3935
4207
|
init_home();
|
|
3936
4208
|
RUNTIME_NPM_PACKAGE_NAME = "@rudderhq/server";
|
|
4209
|
+
NPM_PUBLIC_REGISTRY_URL = "https://registry.npmjs.org";
|
|
3937
4210
|
RUNTIME_METADATA_FILE = "runtime.json";
|
|
4211
|
+
RUNTIME_POSTGRES_PAYLOAD_DIR = "postgres-18.4";
|
|
3938
4212
|
DEFAULT_RUNTIME_CACHE_MAX_ENTRIES = 2;
|
|
3939
4213
|
DEFAULT_RUNTIME_CACHE_MAX_AGE_MS = 14 * 24 * 60 * 60 * 1e3;
|
|
3940
4214
|
DEFAULT_RUNTIME_CACHE_MAX_BYTES = 2 * 1024 * 1024 * 1024;
|
|
3941
4215
|
DEFAULT_RUNTIME_CACHE_KEEP_PREVIOUS = 0;
|
|
3942
4216
|
RUNTIME_NPM_INSTALL_FLAGS = ["--omit=dev", "--include=optional", "--no-audit", "--no-fund"];
|
|
4217
|
+
RUNTIME_NPM_PACK_FLAGS = ["--registry", NPM_PUBLIC_REGISTRY_URL, "--silent"];
|
|
3943
4218
|
EMBEDDED_POSTGRES_PACKAGE_NAME = "embedded-postgres";
|
|
4219
|
+
RUDDER_POSTGRES_BIN_DIR_ENV = "RUDDER_POSTGRES_BIN_DIR";
|
|
4220
|
+
RUNTIME_CACHE_PACKAGE_JSON = {
|
|
4221
|
+
name: "rudder-runtime-cache",
|
|
4222
|
+
version: "0.0.0",
|
|
4223
|
+
private: true,
|
|
4224
|
+
type: "module"
|
|
4225
|
+
};
|
|
4226
|
+
NPM_PLATFORM_REPAIR_ENV = {
|
|
4227
|
+
npm_config_registry: NPM_PUBLIC_REGISTRY_URL,
|
|
4228
|
+
npm_config_update_notifier: "false",
|
|
4229
|
+
NO_UPDATE_NOTIFIER: "1"
|
|
4230
|
+
};
|
|
3944
4231
|
RuntimeInstallError = class extends Error {
|
|
3945
4232
|
cacheDir;
|
|
3946
4233
|
command;
|
|
@@ -3991,9 +4278,15 @@ async function loadServerRuntimeModule(options) {
|
|
|
3991
4278
|
}
|
|
3992
4279
|
const installOptions = {
|
|
3993
4280
|
version: options.version,
|
|
3994
|
-
homeDir: options.homeDir
|
|
4281
|
+
homeDir: options.homeDir,
|
|
4282
|
+
preparePostgresPayload: true
|
|
3995
4283
|
};
|
|
3996
4284
|
const runtime = await ensureRuntimeInstalled(installOptions);
|
|
4285
|
+
if (!process.env[RUDDER_POSTGRES_BIN_DIR_ENV2]?.trim()) {
|
|
4286
|
+
if (runtime.postgresPayloadBinDir && fs3.existsSync(runtime.postgresPayloadBinDir)) {
|
|
4287
|
+
process.env[RUDDER_POSTGRES_BIN_DIR_ENV2] = runtime.postgresPayloadBinDir;
|
|
4288
|
+
}
|
|
4289
|
+
}
|
|
3997
4290
|
options.onRuntimeInstalled?.(runtime);
|
|
3998
4291
|
return await importRuntimeServerModule(runtime.cacheDir);
|
|
3999
4292
|
}
|
|
@@ -4016,10 +4309,12 @@ async function startServerFromModule(mod) {
|
|
|
4016
4309
|
takeoverOnVersionMismatch: true
|
|
4017
4310
|
});
|
|
4018
4311
|
}
|
|
4312
|
+
var RUDDER_POSTGRES_BIN_DIR_ENV2;
|
|
4019
4313
|
var init_server_entry = __esm({
|
|
4020
4314
|
"src/runtime/server-entry.ts"() {
|
|
4021
4315
|
"use strict";
|
|
4022
4316
|
init_install();
|
|
4317
|
+
RUDDER_POSTGRES_BIN_DIR_ENV2 = "RUDDER_POSTGRES_BIN_DIR";
|
|
4023
4318
|
}
|
|
4024
4319
|
});
|
|
4025
4320
|
|
|
@@ -5622,7 +5917,7 @@ var init_doctor = __esm({
|
|
|
5622
5917
|
});
|
|
5623
5918
|
|
|
5624
5919
|
// src/install.ts
|
|
5625
|
-
import { execFileSync, spawnSync as spawnSync2 } from "node:child_process";
|
|
5920
|
+
import { execFileSync as execFileSync2, spawnSync as spawnSync2 } from "node:child_process";
|
|
5626
5921
|
function normalizePath(value) {
|
|
5627
5922
|
return (value ?? "").replaceAll("\\", "/").toLowerCase();
|
|
5628
5923
|
}
|
|
@@ -5651,10 +5946,10 @@ function isTransientBinaryPath(candidatePath) {
|
|
|
5651
5946
|
const normalized = normalizePath(candidatePath);
|
|
5652
5947
|
return normalized.includes("/_npx/");
|
|
5653
5948
|
}
|
|
5654
|
-
function hasGlobalInstalledPackage(packageName, execFileSyncImpl =
|
|
5949
|
+
function hasGlobalInstalledPackage(packageName, execFileSyncImpl = execFileSync2) {
|
|
5655
5950
|
return getGlobalInstalledPackageVersion(packageName, execFileSyncImpl) !== null;
|
|
5656
5951
|
}
|
|
5657
|
-
function getGlobalInstalledPackageVersion(packageName, execFileSyncImpl =
|
|
5952
|
+
function getGlobalInstalledPackageVersion(packageName, execFileSyncImpl = execFileSync2) {
|
|
5658
5953
|
try {
|
|
5659
5954
|
const output = execFileSyncImpl(
|
|
5660
5955
|
process.platform === "win32" ? "npm.cmd" : "npm",
|
|
@@ -5670,7 +5965,7 @@ function getGlobalInstalledPackageVersion(packageName, execFileSyncImpl = execFi
|
|
|
5670
5965
|
return null;
|
|
5671
5966
|
}
|
|
5672
5967
|
}
|
|
5673
|
-
function hasPersistentBinaryOnPath(execFileSyncImpl =
|
|
5968
|
+
function hasPersistentBinaryOnPath(execFileSyncImpl = execFileSync2) {
|
|
5674
5969
|
const { command, args } = resolveCommandLookupExecutable();
|
|
5675
5970
|
try {
|
|
5676
5971
|
const output = execFileSyncImpl(command, args, {
|
|
@@ -5685,7 +5980,7 @@ function hasPersistentBinaryOnPath(execFileSyncImpl = execFileSync) {
|
|
|
5685
5980
|
}
|
|
5686
5981
|
function detectPersistentCliState(options = {}) {
|
|
5687
5982
|
const env = options.env ?? process.env;
|
|
5688
|
-
const execFileSyncImpl = options.execFileSyncImpl ??
|
|
5983
|
+
const execFileSyncImpl = options.execFileSyncImpl ?? execFileSync2;
|
|
5689
5984
|
const installSpec = resolvePersistentCliInstallSpec(env);
|
|
5690
5985
|
const usingNpx = isLikelyNpxExecutionContext(options.entryPath ?? process.argv[1], env);
|
|
5691
5986
|
if (!usingNpx) {
|
|
@@ -7270,6 +7565,15 @@ function isMaintainerOnlySkillTarget(candidate) {
|
|
|
7270
7565
|
const normalized = normalizePathSlashes(candidate);
|
|
7271
7566
|
return normalized.includes("/server/resources/bundled-skills/") || normalized.includes("/.agents/skills/");
|
|
7272
7567
|
}
|
|
7568
|
+
function parseObject(value) {
|
|
7569
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
7570
|
+
return {};
|
|
7571
|
+
}
|
|
7572
|
+
return value;
|
|
7573
|
+
}
|
|
7574
|
+
function asString(value, fallback) {
|
|
7575
|
+
return typeof value === "string" && value.length > 0 ? value : fallback;
|
|
7576
|
+
}
|
|
7273
7577
|
|
|
7274
7578
|
// ../packages/agent-runtime-utils/dist/server-utils.prompts.js
|
|
7275
7579
|
var RUDDER_AGENT_OPERATING_CONTRACT = [
|
|
@@ -7293,7 +7597,7 @@ var RUDDER_AGENT_OPERATING_CONTRACT = [
|
|
|
7293
7597
|
"- `library:projects/<project-key>/...` is the Rudder product locator for those files, not the Markdown link syntax and not a reason to route ordinary local edits through the CLI.",
|
|
7294
7598
|
'- When you create or update a durable Library file, always include a user-visible Markdown link to that file in your final chat reply or issue comment. Use `rudder library file ref "$RUDDER_PROJECT_LIBRARY_PATH/<relative-file>" --json` and paste the returned `markdownLink`; do not pass the absolute `$RUDDER_PROJECT_LIBRARY_ROOT/...` path to `ref`, and do not hand-write `library-entry://...` or `library-file://...` links.',
|
|
7295
7599
|
'- If `$RUDDER_PROJECT_LIBRARY_ROOT` is unset or inaccessible, use `rudder library file get/put "$RUDDER_PROJECT_LIBRARY_PATH/<relative-file>"` as the remote or restricted runtime fallback.',
|
|
7296
|
-
"- Use
|
|
7600
|
+
"- Use `$RUDDER_RUNTIME_TMPDIR` for transient scratch files and temporary verification files when it is set; otherwise use `/tmp`. Do not put durable work product there.",
|
|
7297
7601
|
"- Local trusted runtimes may expose the host operator home as `$RUDDER_OPERATOR_HOME`; use it only when a local skill or script intentionally needs operator-owned desktop app or CLI state. Do not replace `$HOME` with it.",
|
|
7298
7602
|
"",
|
|
7299
7603
|
"When you create or copy a skill under `$AGENT_HOME/skills/<slug>/`, check the agent's Skills snapshot before claiming it will load in future runs. If it is installed but not enabled, say exactly that future runs will not load it until enabled, and offer to enable it with `rudder agent skills enable <agent-id> <selection-ref>` when you have permission.",
|
|
@@ -7340,16 +7644,16 @@ var RUDDER_AGENT_OPERATING_CONTRACT = [
|
|
|
7340
7644
|
var RUDDER_AGENT_HEARTBEAT_INSTRUCTION = [
|
|
7341
7645
|
"# Rudder Heartbeat Instruction",
|
|
7342
7646
|
"",
|
|
7343
|
-
"This section is injected by Rudder for heartbeat scene runs. It is the platform-owned
|
|
7647
|
+
"This section is injected by Rudder only for heartbeat scene runs. It is the platform-owned heartbeat/self-check pipeline.",
|
|
7344
7648
|
"",
|
|
7345
7649
|
"## Heartbeat Pipeline",
|
|
7346
7650
|
"",
|
|
7347
7651
|
"1. Identify yourself and inspect wake context, including `RUDDER_TASK_ID`, `RUDDER_WAKE_REASON`, `RUDDER_WAKE_COMMENT_ID`, and `RUDDER_APPROVAL_ID` when present.",
|
|
7348
7652
|
"2. Local Planning Check:",
|
|
7349
7653
|
" ",
|
|
7350
|
-
"
|
|
7351
|
-
"
|
|
7352
|
-
"
|
|
7654
|
+
"- Read today's plan from `$AGENT_HOME/memory/YYYY-MM-DD.md` under \"## Today's Plan\". You need to clearly know your work plan for today, and work according to the plan.",
|
|
7655
|
+
"- Review each planned item: what's completed, what's blocked, and what up next.",
|
|
7656
|
+
"- Record progress updates in the daily notes.",
|
|
7353
7657
|
" ",
|
|
7354
7658
|
"3.Then handle approval follow-up: read the approval and linked issues, then close resolved work or comment on what remains.",
|
|
7355
7659
|
"4. Inspect your Rudder inbox. Prioritize reviewer rows in `in_review` or `blocked`, then assignee `in_progress`, then assignee `todo`. Do not look for unassigned work.",
|
|
@@ -7357,8 +7661,8 @@ var RUDDER_AGENT_HEARTBEAT_INSTRUCTION = [
|
|
|
7357
7661
|
"6. Checkout before doing assignee task work. A `409` means another agent owns the task; do not retry it.",
|
|
7358
7662
|
"7. Load compact issue context, do one bounded useful chunk, and preserve evidence.",
|
|
7359
7663
|
"8. Before exiting active work, leave exactly one durable signal: progress, done, blocked, explicit handoff, or structured review decision.",
|
|
7360
|
-
"9. Treat passive follow-up as
|
|
7361
|
-
"10. Treat review close-out follow-up as review
|
|
7664
|
+
"9. Treat passive follow-up as issue follow-up, not a fresh assignment.",
|
|
7665
|
+
"10. Treat review close-out follow-up as review follow-up; free-form accept/reject text is not a durable decision.",
|
|
7362
7666
|
"",
|
|
7363
7667
|
"Use the Rudder control-plane interface available in this runtime. CLI-capable runtimes should use the bundled `rudder` skill for command details, Library handoff rules, organization-skill workflow, and control-plane best practices. HTTP compatibility runtimes should follow the explicit HTTP workflow in their wake text; that workflow overrides CLI command guidance."
|
|
7364
7668
|
].join("\n");
|
|
@@ -7381,25 +7685,48 @@ async function resolveRudderSkillsDir(moduleDir, additionalCandidates = []) {
|
|
|
7381
7685
|
return null;
|
|
7382
7686
|
}
|
|
7383
7687
|
async function removeMaintainerOnlySkillSymlinks(skillsHome, allowedSkillNames) {
|
|
7688
|
+
return removeUnselectedRudderSkillSymlinks(skillsHome, allowedSkillNames);
|
|
7689
|
+
}
|
|
7690
|
+
async function readRudderMaterializedSkillSource(target) {
|
|
7691
|
+
const manifestPath = path9.join(target, ".rudder", "materialized-skill.json");
|
|
7692
|
+
const raw = await fs6.readFile(manifestPath, "utf8").catch(() => null);
|
|
7693
|
+
if (!raw)
|
|
7694
|
+
return null;
|
|
7695
|
+
try {
|
|
7696
|
+
const parsed = parseObject(JSON.parse(raw));
|
|
7697
|
+
const sourcePath = asString(parsed.sourcePath, "").trim();
|
|
7698
|
+
return sourcePath.length > 0 ? path9.resolve(sourcePath) : null;
|
|
7699
|
+
} catch {
|
|
7700
|
+
return null;
|
|
7701
|
+
}
|
|
7702
|
+
}
|
|
7703
|
+
async function removeUnselectedRudderSkillSymlinks(skillsHome, allowedSkillNames, knownSkillSources = []) {
|
|
7384
7704
|
const allowed = new Set(Array.from(allowedSkillNames));
|
|
7705
|
+
const knownSources = new Set(Array.from(knownSkillSources).map((value) => value.trim()).filter(Boolean).map((value) => path9.resolve(value)));
|
|
7385
7706
|
try {
|
|
7386
7707
|
const entries = await fs6.readdir(skillsHome, { withFileTypes: true });
|
|
7387
7708
|
const removed = [];
|
|
7388
7709
|
for (const entry of entries) {
|
|
7389
|
-
if (allowed.has(entry.name))
|
|
7390
|
-
continue;
|
|
7391
7710
|
const target = path9.join(skillsHome, entry.name);
|
|
7392
7711
|
const existing = await fs6.lstat(target).catch(() => null);
|
|
7393
|
-
if (!existing
|
|
7712
|
+
if (!existing)
|
|
7394
7713
|
continue;
|
|
7395
|
-
|
|
7396
|
-
if (
|
|
7714
|
+
let isRudderManagedSkill = false;
|
|
7715
|
+
if (existing.isSymbolicLink()) {
|
|
7716
|
+
const linkedPath = await fs6.readlink(target).catch(() => null);
|
|
7717
|
+
if (!linkedPath)
|
|
7718
|
+
continue;
|
|
7719
|
+
const resolvedLinkedPath = path9.isAbsolute(linkedPath) ? linkedPath : path9.resolve(path9.dirname(target), linkedPath);
|
|
7720
|
+
isRudderManagedSkill = knownSources.has(path9.resolve(resolvedLinkedPath)) || isMaintainerOnlySkillTarget(linkedPath) || isMaintainerOnlySkillTarget(resolvedLinkedPath);
|
|
7721
|
+
} else if (existing.isDirectory()) {
|
|
7722
|
+
const materializedSource = await readRudderMaterializedSkillSource(target);
|
|
7723
|
+
isRudderManagedSkill = materializedSource !== null && knownSources.has(materializedSource);
|
|
7724
|
+
}
|
|
7725
|
+
if (!isRudderManagedSkill)
|
|
7397
7726
|
continue;
|
|
7398
|
-
|
|
7399
|
-
if (!isMaintainerOnlySkillTarget(linkedPath) && !isMaintainerOnlySkillTarget(resolvedLinkedPath)) {
|
|
7727
|
+
if (allowed.has(entry.name))
|
|
7400
7728
|
continue;
|
|
7401
|
-
}
|
|
7402
|
-
await fs6.unlink(target);
|
|
7729
|
+
await fs6.rm(target, { recursive: true, force: true });
|
|
7403
7730
|
removed.push(entry.name);
|
|
7404
7731
|
}
|
|
7405
7732
|
return removed;
|
|
@@ -13668,7 +13995,7 @@ import * as p15 from "@clack/prompts";
|
|
|
13668
13995
|
import { spawn as spawn2, spawnSync as spawnSync3 } from "node:child_process";
|
|
13669
13996
|
import { createHash, randomUUID } from "node:crypto";
|
|
13670
13997
|
import { createWriteStream, constants as fsConstants, mkdirSync, readFileSync as readFileSync2 } from "node:fs";
|
|
13671
|
-
import { access, chmod, copyFile, cp, mkdir as mkdir3, mkdtemp, readdir as readdir3, readFile as readFile6, rm as rm2, stat as stat4, utimes, writeFile as writeFile3 } from "node:fs/promises";
|
|
13998
|
+
import { access, chmod, copyFile, cp as cp2, mkdir as mkdir3, mkdtemp, readdir as readdir3, readFile as readFile6, rm as rm2, stat as stat4, utimes, writeFile as writeFile3 } from "node:fs/promises";
|
|
13672
13999
|
import { homedir, tmpdir } from "node:os";
|
|
13673
14000
|
import path21 from "node:path";
|
|
13674
14001
|
import { Readable, Transform } from "node:stream";
|
|
@@ -13963,6 +14290,9 @@ function resolveDesktopReleaseTag(version) {
|
|
|
13963
14290
|
function isExactRuntimePackageSpec(version, packageSpec) {
|
|
13964
14291
|
return version !== "latest" && packageSpec === resolveRuntimePackageSpec(version);
|
|
13965
14292
|
}
|
|
14293
|
+
function runtimeSupportsDesktopShellAssets(version, runtime) {
|
|
14294
|
+
return isExactRuntimePackageSpec(version, runtime.packageSpec) && Boolean(runtime.postgresPayloadBinDir);
|
|
14295
|
+
}
|
|
13966
14296
|
function resolveDesktopAssetTarget(platform = process.platform, arch = process.arch) {
|
|
13967
14297
|
if (platform === "darwin") {
|
|
13968
14298
|
if (arch !== "x64" && arch !== "arm64") {
|
|
@@ -14843,7 +15173,7 @@ async function copyPortableAppBundle(sourcePath, destinationPath) {
|
|
|
14843
15173
|
if (isSuccessfulRobocopyExitCode(result.status)) return;
|
|
14844
15174
|
throw new Error(formatCommandFailure(command.command, command.args, result.stdout, result.stderr));
|
|
14845
15175
|
}
|
|
14846
|
-
await
|
|
15176
|
+
await cp2(sourcePath, destinationPath, { recursive: true, verbatimSymlinks: true });
|
|
14847
15177
|
}
|
|
14848
15178
|
async function removeMacQuarantine(paths, target) {
|
|
14849
15179
|
if (target.platform !== "macos") return;
|
|
@@ -14986,11 +15316,14 @@ async function startCommand(opts) {
|
|
|
14986
15316
|
const spinner3 = p15.spinner();
|
|
14987
15317
|
spinner3.start("Installing or reusing Rudder runtime...");
|
|
14988
15318
|
try {
|
|
14989
|
-
const runtime = await ensureRuntimeInstalled({ version });
|
|
14990
|
-
runtimeSupportsShellAssets =
|
|
15319
|
+
const runtime = await ensureRuntimeInstalled({ version, preparePostgresPayload: true });
|
|
15320
|
+
runtimeSupportsShellAssets = runtimeSupportsDesktopShellAssets(version, runtime);
|
|
14991
15321
|
spinner3.stop(
|
|
14992
15322
|
runtime.status === "hit" ? `Rudder runtime cache hit at ${pc15.cyan(runtime.cacheDir)}.` : `Rudder runtime installed at ${pc15.cyan(runtime.cacheDir)}.`
|
|
14993
15323
|
);
|
|
15324
|
+
if (!runtime.postgresPayloadBinDir && installDesktop) {
|
|
15325
|
+
p15.log.warn("Rudder runtime cache has no PostgreSQL 18.4 payload; the full portable Desktop asset will be used.");
|
|
15326
|
+
}
|
|
14994
15327
|
if (!runtimeSupportsShellAssets && installDesktop) {
|
|
14995
15328
|
p15.log.warn("Rudder runtime did not resolve to the exact Desktop version; the full portable Desktop asset will be used.");
|
|
14996
15329
|
}
|