@rudderhq/cli 0.3.6-canary.9 → 0.4.1
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/README.md +8 -0
- package/dist/index.js +415 -76
- 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"() {
|
|
@@ -607,6 +614,7 @@ var init_instance = __esm({
|
|
|
607
614
|
}).strict();
|
|
608
615
|
patchInstanceNotificationSettingsSchema = instanceNotificationSettingsSchema.partial();
|
|
609
616
|
instanceLangfuseSettingsSchema = z.object({
|
|
617
|
+
installed: z.boolean().default(false),
|
|
610
618
|
enabled: z.boolean().default(false),
|
|
611
619
|
baseUrl: z.string().url().default("http://localhost:3000"),
|
|
612
620
|
publicKey: z.string().default(""),
|
|
@@ -784,7 +792,7 @@ var init_adapter_skills = __esm({
|
|
|
784
792
|
|
|
785
793
|
// ../packages/shared/dist/validators/chat.js
|
|
786
794
|
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;
|
|
795
|
+
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
796
|
var init_chat = __esm({
|
|
789
797
|
"../packages/shared/dist/validators/chat.js"() {
|
|
790
798
|
"use strict";
|
|
@@ -817,9 +825,39 @@ var init_chat = __esm({
|
|
|
817
825
|
primaryIssueId: z4.string().uuid().optional().nullable(),
|
|
818
826
|
resolvedAt: z4.string().datetime().optional().nullable()
|
|
819
827
|
});
|
|
828
|
+
forkChatConversationSchema = z4.object({
|
|
829
|
+
sourceMessageId: z4.string().uuid().optional().nullable(),
|
|
830
|
+
title: z4.string().trim().min(1).max(200).optional()
|
|
831
|
+
});
|
|
820
832
|
addChatMessageSchema = z4.object({
|
|
821
833
|
body: z4.string().trim().min(1).max(2e4),
|
|
822
|
-
editUserMessageId: z4.string().uuid().optional().nullable()
|
|
834
|
+
editUserMessageId: z4.string().uuid().optional().nullable(),
|
|
835
|
+
queuedMessageId: z4.string().uuid().optional().nullable()
|
|
836
|
+
});
|
|
837
|
+
chatQueuedMessagePayloadSchema = z4.object({
|
|
838
|
+
body: z4.string().trim().min(1).max(2e4),
|
|
839
|
+
attachmentIds: z4.array(z4.string().uuid()).optional().default([]),
|
|
840
|
+
projectId: z4.string().uuid().optional().nullable(),
|
|
841
|
+
skillRefs: z4.array(z4.string().trim().min(1).max(240)).optional().default([]),
|
|
842
|
+
accessMode: z4.string().trim().min(1).max(120).optional().nullable(),
|
|
843
|
+
model: z4.string().trim().min(1).max(120).optional().nullable(),
|
|
844
|
+
effort: z4.string().trim().min(1).max(120).optional().nullable(),
|
|
845
|
+
metadata: z4.record(z4.unknown()).optional().nullable()
|
|
846
|
+
});
|
|
847
|
+
createChatQueuedMessageSchema = z4.object({
|
|
848
|
+
clientMutationId: z4.string().trim().min(1).max(120),
|
|
849
|
+
expectedGenerationId: z4.string().uuid().optional().nullable(),
|
|
850
|
+
payload: chatQueuedMessagePayloadSchema
|
|
851
|
+
});
|
|
852
|
+
updateChatQueuedMessageSchema = z4.object({
|
|
853
|
+
version: z4.number().int().positive(),
|
|
854
|
+
payload: chatQueuedMessagePayloadSchema
|
|
855
|
+
});
|
|
856
|
+
cancelChatQueuedMessageSchema = z4.object({
|
|
857
|
+
version: z4.number().int().positive().optional()
|
|
858
|
+
});
|
|
859
|
+
steerChatQueuedMessageSchema = z4.object({
|
|
860
|
+
expectedActiveGenerationId: z4.string().uuid().optional().nullable()
|
|
823
861
|
});
|
|
824
862
|
chatRichReferenceDisplaySchema = z4.enum(["card", "inline"]);
|
|
825
863
|
chatIssueIdentifierSchema = z4.string().trim().min(1).max(64).regex(/^[A-Z0-9][A-Z0-9-]*$/i);
|
|
@@ -972,12 +1010,14 @@ var init_chat = __esm({
|
|
|
972
1010
|
icon: z4.string().trim().min(1).max(24).optional().nullable()
|
|
973
1011
|
});
|
|
974
1012
|
createMessengerCustomGroupWithEntriesSchema = createMessengerCustomGroupSchema.extend({
|
|
975
|
-
threadKeys: z4.array(z4.string().trim().min(1).max(240)).min(1).max(50)
|
|
1013
|
+
threadKeys: z4.array(z4.string().trim().min(1).max(240)).min(1).max(50),
|
|
1014
|
+
autoGenerateName: z4.boolean().optional()
|
|
976
1015
|
});
|
|
977
1016
|
updateMessengerCustomGroupSchema = z4.object({
|
|
978
1017
|
name: z4.string().trim().min(1).max(80).optional(),
|
|
979
1018
|
icon: z4.string().trim().min(1).max(24).optional().nullable(),
|
|
980
1019
|
collapsed: z4.boolean().optional(),
|
|
1020
|
+
pinned: z4.boolean().optional(),
|
|
981
1021
|
sortOrder: z4.number().int().min(0).optional()
|
|
982
1022
|
});
|
|
983
1023
|
reorderMessengerCustomGroupsSchema = z4.object({
|
|
@@ -2985,6 +3025,7 @@ var init_api = __esm({
|
|
|
2985
3025
|
secrets: `${API_PREFIX}/secrets`,
|
|
2986
3026
|
costs: `${API_PREFIX}/costs`,
|
|
2987
3027
|
activity: `${API_PREFIX}/activity`,
|
|
3028
|
+
agentRuns: `${API_PREFIX}/agent-runs`,
|
|
2988
3029
|
dashboard: `${API_PREFIX}/dashboard`,
|
|
2989
3030
|
sidebarBadges: `${API_PREFIX}/sidebar-badges`,
|
|
2990
3031
|
invites: `${API_PREFIX}/invites`,
|
|
@@ -3183,6 +3224,7 @@ var init_config_schema = __esm({
|
|
|
3183
3224
|
})
|
|
3184
3225
|
});
|
|
3185
3226
|
langfuseConfigSchema = z28.object({
|
|
3227
|
+
installed: z28.boolean().optional(),
|
|
3186
3228
|
enabled: z28.boolean().default(false),
|
|
3187
3229
|
baseUrl: z28.string().url().default("http://localhost:3000"),
|
|
3188
3230
|
publicKey: z28.string().optional(),
|
|
@@ -3260,6 +3302,7 @@ var init_dist = __esm({
|
|
|
3260
3302
|
"../packages/shared/dist/index.js"() {
|
|
3261
3303
|
"use strict";
|
|
3262
3304
|
init_constants();
|
|
3305
|
+
init_agent_run();
|
|
3263
3306
|
init_observability();
|
|
3264
3307
|
init_workspace_backup();
|
|
3265
3308
|
init_validators();
|
|
@@ -3491,8 +3534,8 @@ var init_env = __esm({
|
|
|
3491
3534
|
});
|
|
3492
3535
|
|
|
3493
3536
|
// src/runtime/install.ts
|
|
3494
|
-
import { spawnSync } from "node:child_process";
|
|
3495
|
-
import { mkdir, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
|
|
3537
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
3538
|
+
import { cp, mkdir, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
|
|
3496
3539
|
import { createRequire } from "node:module";
|
|
3497
3540
|
import path4 from "node:path";
|
|
3498
3541
|
import { pathToFileURL } from "node:url";
|
|
@@ -3561,23 +3604,6 @@ async function hasRequiredRuntimePlatformDependencies(cacheDir) {
|
|
|
3561
3604
|
if (!platformPackage) return true;
|
|
3562
3605
|
return await canResolveRuntimePackage(cacheDir, platformPackage);
|
|
3563
3606
|
}
|
|
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
3607
|
async function isRuntimeCacheHit(options) {
|
|
3582
3608
|
const packageName = options.packageName ?? RUNTIME_NPM_PACKAGE_NAME;
|
|
3583
3609
|
const packageVersion = resolveRuntimePackageVersion(options.version);
|
|
@@ -3600,7 +3626,9 @@ async function ensureRuntimeInstalled(options) {
|
|
|
3600
3626
|
const cacheDir = resolveRuntimeCacheDir(packageVersion, options.homeDir);
|
|
3601
3627
|
const packageSpec = resolveRuntimePackageSpec(packageVersion, packageName);
|
|
3602
3628
|
const command = formatRuntimeInstallCommand(cacheDir, packageSpec);
|
|
3629
|
+
const preparePostgresPayload = options.preparePostgresPayload === true;
|
|
3603
3630
|
if (await isRuntimeCacheHit({ cacheDir, version: packageVersion, packageName })) {
|
|
3631
|
+
const postgresPayload2 = await stageRuntimePostgresPayload(cacheDir, preparePostgresPayload);
|
|
3604
3632
|
await touchRuntimeInstallMetadata(cacheDir);
|
|
3605
3633
|
const prune2 = await maybePruneRuntimeCache({
|
|
3606
3634
|
homeDir: options.homeDir,
|
|
@@ -3608,37 +3636,75 @@ async function ensureRuntimeInstalled(options) {
|
|
|
3608
3636
|
enabled: options.pruneRuntimeCache !== false,
|
|
3609
3637
|
retention: options.retention
|
|
3610
3638
|
});
|
|
3611
|
-
return
|
|
3639
|
+
return withPostgresPayload(
|
|
3640
|
+
{ status: "hit", cacheDir, packageSpec, command, output: "", ...prune2 ? { prune: prune2 } : {} },
|
|
3641
|
+
postgresPayload2
|
|
3642
|
+
);
|
|
3643
|
+
}
|
|
3644
|
+
const spawnSyncImpl = options.spawnSyncImpl ?? spawnSync;
|
|
3645
|
+
const existingRuntimeOutput = await tryRepairExistingRuntimePackage({
|
|
3646
|
+
spawnSyncImpl,
|
|
3647
|
+
cacheDir,
|
|
3648
|
+
packageName,
|
|
3649
|
+
packageVersion
|
|
3650
|
+
});
|
|
3651
|
+
if (existingRuntimeOutput !== null) {
|
|
3652
|
+
const postgresPayload2 = await stageRuntimePostgresPayload(cacheDir, preparePostgresPayload);
|
|
3653
|
+
const metadata2 = {
|
|
3654
|
+
version: 1,
|
|
3655
|
+
packageName,
|
|
3656
|
+
packageVersion,
|
|
3657
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3658
|
+
lastUsedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3659
|
+
};
|
|
3660
|
+
await writeRuntimeInstallMetadata(cacheDir, metadata2);
|
|
3661
|
+
const prune2 = await maybePruneRuntimeCache({
|
|
3662
|
+
homeDir: options.homeDir,
|
|
3663
|
+
requestedVersion: packageVersion,
|
|
3664
|
+
enabled: options.pruneRuntimeCache !== false,
|
|
3665
|
+
retention: options.retention
|
|
3666
|
+
});
|
|
3667
|
+
return withPostgresPayload(
|
|
3668
|
+
{ status: "installed", cacheDir, packageSpec, command, output: existingRuntimeOutput, ...prune2 ? { prune: prune2 } : {} },
|
|
3669
|
+
postgresPayload2
|
|
3670
|
+
);
|
|
3612
3671
|
}
|
|
3613
3672
|
await rm(cacheDir, { recursive: true, force: true });
|
|
3614
3673
|
await mkdir(cacheDir, { recursive: true });
|
|
3615
|
-
await writeFile(path4.join(cacheDir, "package.json"), `${JSON.stringify(
|
|
3674
|
+
await writeFile(path4.join(cacheDir, "package.json"), `${JSON.stringify(RUNTIME_CACHE_PACKAGE_JSON, null, 2)}
|
|
3616
3675
|
`, "utf8");
|
|
3617
|
-
const spawnSyncImpl = options.spawnSyncImpl ?? spawnSync;
|
|
3618
3676
|
const result = runNpmRuntimeInstall(spawnSyncImpl, cacheDir, packageSpec);
|
|
3619
|
-
|
|
3677
|
+
let output = collectSpawnOutput(result);
|
|
3620
3678
|
if (result.status !== 0 && packageVersion !== "latest" && isVersionNotFoundError(output)) {
|
|
3621
3679
|
const fallbackVersion = "latest";
|
|
3622
3680
|
const fallbackCacheDir = resolveRuntimeCacheDir(fallbackVersion, options.homeDir);
|
|
3623
3681
|
const fallbackSpec = resolveRuntimePackageSpec(fallbackVersion, packageName);
|
|
3624
3682
|
if (await isRuntimeCacheHit({ cacheDir: fallbackCacheDir, version: fallbackVersion, packageName })) {
|
|
3683
|
+
const fallbackPostgresPayload = await stageRuntimePostgresPayload(fallbackCacheDir, preparePostgresPayload);
|
|
3625
3684
|
await touchRuntimeInstallMetadata(fallbackCacheDir);
|
|
3626
|
-
return
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3685
|
+
return withPostgresPayload(
|
|
3686
|
+
{
|
|
3687
|
+
status: "hit",
|
|
3688
|
+
cacheDir: fallbackCacheDir,
|
|
3689
|
+
packageSpec: fallbackSpec,
|
|
3690
|
+
command: formatRuntimeInstallCommand(fallbackCacheDir, fallbackSpec),
|
|
3691
|
+
output: ""
|
|
3692
|
+
},
|
|
3693
|
+
fallbackPostgresPayload
|
|
3694
|
+
);
|
|
3633
3695
|
}
|
|
3634
3696
|
await rm(fallbackCacheDir, { recursive: true, force: true });
|
|
3635
3697
|
await mkdir(fallbackCacheDir, { recursive: true });
|
|
3636
|
-
await writeFile(path4.join(fallbackCacheDir, "package.json"), `${JSON.stringify(
|
|
3698
|
+
await writeFile(path4.join(fallbackCacheDir, "package.json"), `${JSON.stringify(RUNTIME_CACHE_PACKAGE_JSON, null, 2)}
|
|
3637
3699
|
`, "utf8");
|
|
3638
3700
|
const fallbackResult = runNpmRuntimeInstall(spawnSyncImpl, fallbackCacheDir, fallbackSpec);
|
|
3639
|
-
|
|
3701
|
+
let fallbackOutput = collectSpawnOutput(fallbackResult);
|
|
3640
3702
|
if (fallbackResult.status === 0) {
|
|
3641
|
-
|
|
3703
|
+
fallbackOutput = collectOutputParts(
|
|
3704
|
+
fallbackOutput,
|
|
3705
|
+
await ensureRequiredEmbeddedPostgresPlatformPackage(spawnSyncImpl, fallbackCacheDir)
|
|
3706
|
+
);
|
|
3707
|
+
const postgresPayload2 = await stageRuntimePostgresPayload(fallbackCacheDir, preparePostgresPayload);
|
|
3642
3708
|
const fallbackMetadata = {
|
|
3643
3709
|
version: 1,
|
|
3644
3710
|
packageName,
|
|
@@ -3647,13 +3713,16 @@ async function ensureRuntimeInstalled(options) {
|
|
|
3647
3713
|
lastUsedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3648
3714
|
};
|
|
3649
3715
|
await writeRuntimeInstallMetadata(fallbackCacheDir, fallbackMetadata);
|
|
3650
|
-
return
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3716
|
+
return withPostgresPayload(
|
|
3717
|
+
{
|
|
3718
|
+
status: "installed",
|
|
3719
|
+
cacheDir: fallbackCacheDir,
|
|
3720
|
+
packageSpec: fallbackSpec,
|
|
3721
|
+
command: formatRuntimeInstallCommand(fallbackCacheDir, fallbackSpec),
|
|
3722
|
+
output: fallbackOutput
|
|
3723
|
+
},
|
|
3724
|
+
postgresPayload2
|
|
3725
|
+
);
|
|
3657
3726
|
}
|
|
3658
3727
|
}
|
|
3659
3728
|
if (result.status !== 0) {
|
|
@@ -3662,7 +3731,11 @@ async function ensureRuntimeInstalled(options) {
|
|
|
3662
3731
|
{ cacheDir, command, output }
|
|
3663
3732
|
);
|
|
3664
3733
|
}
|
|
3665
|
-
|
|
3734
|
+
output = collectOutputParts(
|
|
3735
|
+
output,
|
|
3736
|
+
await ensureRequiredEmbeddedPostgresPlatformPackage(spawnSyncImpl, cacheDir)
|
|
3737
|
+
);
|
|
3738
|
+
const postgresPayload = await stageRuntimePostgresPayload(cacheDir, preparePostgresPayload);
|
|
3666
3739
|
const metadata = {
|
|
3667
3740
|
version: 1,
|
|
3668
3741
|
packageName,
|
|
@@ -3677,7 +3750,13 @@ async function ensureRuntimeInstalled(options) {
|
|
|
3677
3750
|
enabled: options.pruneRuntimeCache !== false,
|
|
3678
3751
|
retention: options.retention
|
|
3679
3752
|
});
|
|
3680
|
-
return
|
|
3753
|
+
return withPostgresPayload(
|
|
3754
|
+
{ status: "installed", cacheDir, packageSpec, command, output, ...prune ? { prune } : {} },
|
|
3755
|
+
postgresPayload
|
|
3756
|
+
);
|
|
3757
|
+
}
|
|
3758
|
+
function resolveRuntimePostgresPayloadBinDir(cacheDir, platform = process.platform, arch = process.arch) {
|
|
3759
|
+
return path4.join(cacheDir, RUNTIME_POSTGRES_PAYLOAD_DIR, runtimePostgresPlatformSegment(platform, arch), "bin");
|
|
3681
3760
|
}
|
|
3682
3761
|
function resolveRuntimeServerEntrypoint(cacheDir, packageName = RUNTIME_NPM_PACKAGE_NAME) {
|
|
3683
3762
|
return createRequire(path4.join(cacheDir, "package.json")).resolve(packageName);
|
|
@@ -3700,9 +3779,204 @@ function runNpmRuntimeInstall(spawnSyncImpl, cacheDir, packageSpec) {
|
|
|
3700
3779
|
function formatRuntimeInstallCommand(cacheDir, packageSpec) {
|
|
3701
3780
|
return `npm install --prefix ${cacheDir} ${RUNTIME_NPM_INSTALL_FLAGS.join(" ")} ${packageSpec}`;
|
|
3702
3781
|
}
|
|
3782
|
+
function formatRuntimePlatformRepairCommand(cacheDir, packageSpec) {
|
|
3783
|
+
return `npm pack ${packageSpec} --registry=${NPM_PUBLIC_REGISTRY_URL} --silent, then extract it into ${path4.join(cacheDir, "node_modules")}`;
|
|
3784
|
+
}
|
|
3703
3785
|
function collectSpawnOutput(result) {
|
|
3704
3786
|
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
3787
|
}
|
|
3788
|
+
function collectOutputParts(...parts) {
|
|
3789
|
+
return parts.filter((part) => part.trim().length > 0).join("\n").trim();
|
|
3790
|
+
}
|
|
3791
|
+
function withPostgresPayload(result, postgresPayload) {
|
|
3792
|
+
return {
|
|
3793
|
+
...result,
|
|
3794
|
+
output: collectOutputParts(result.output, postgresPayload.output),
|
|
3795
|
+
...postgresPayload.binDir ? { postgresPayloadBinDir: postgresPayload.binDir } : {}
|
|
3796
|
+
};
|
|
3797
|
+
}
|
|
3798
|
+
function runtimePackageJsonPath(cacheDir, packageName) {
|
|
3799
|
+
return path4.join(cacheDir, "node_modules", ...packageName.split("/"), "package.json");
|
|
3800
|
+
}
|
|
3801
|
+
async function readRuntimePackageJson(cacheDir, packageName) {
|
|
3802
|
+
try {
|
|
3803
|
+
return JSON.parse(await readFile(runtimePackageJsonPath(cacheDir, packageName), "utf8"));
|
|
3804
|
+
} catch {
|
|
3805
|
+
return null;
|
|
3806
|
+
}
|
|
3807
|
+
}
|
|
3808
|
+
async function tryRepairExistingRuntimePackage(options) {
|
|
3809
|
+
const runtimePackage = await readRuntimePackageJson(options.cacheDir, options.packageName);
|
|
3810
|
+
if (!runtimePackage) return null;
|
|
3811
|
+
if (options.packageVersion !== "latest" && runtimePackage.version !== options.packageVersion) return null;
|
|
3812
|
+
const output = await ensureRequiredEmbeddedPostgresPlatformPackage(options.spawnSyncImpl, options.cacheDir);
|
|
3813
|
+
return await hasRequiredRuntimePlatformDependencies(options.cacheDir) ? output : null;
|
|
3814
|
+
}
|
|
3815
|
+
async function resolveEmbeddedPostgresPlatformPackageSpec(cacheDir) {
|
|
3816
|
+
if (!await canResolveRuntimePackage(cacheDir, EMBEDDED_POSTGRES_PACKAGE_NAME)) return null;
|
|
3817
|
+
const packageName = resolveEmbeddedPostgresPlatformPackage();
|
|
3818
|
+
if (!packageName) return null;
|
|
3819
|
+
const embeddedPostgresPackage = await readRuntimePackageJson(cacheDir, EMBEDDED_POSTGRES_PACKAGE_NAME);
|
|
3820
|
+
const versionRange = embeddedPostgresPackage?.optionalDependencies?.[packageName];
|
|
3821
|
+
const packageVersion = normalizeOptionalDependencyVersion(versionRange);
|
|
3822
|
+
return packageVersion ? `${packageName}@${packageVersion}` : packageName;
|
|
3823
|
+
}
|
|
3824
|
+
async function ensureRequiredEmbeddedPostgresPlatformPackage(spawnSyncImpl, cacheDir) {
|
|
3825
|
+
const packageSpec = await resolveEmbeddedPostgresPlatformPackageSpec(cacheDir);
|
|
3826
|
+
if (!packageSpec) return "";
|
|
3827
|
+
const packageName = packageNameFromSpec(packageSpec);
|
|
3828
|
+
if (packageName && await canResolveRuntimePackage(cacheDir, packageName)) return "";
|
|
3829
|
+
await removeRuntimeInstallLocks(cacheDir);
|
|
3830
|
+
const result = await installRuntimePackageInStaging(spawnSyncImpl, cacheDir, packageSpec, packageName);
|
|
3831
|
+
const output = collectSpawnOutput(result);
|
|
3832
|
+
if (result.status === 0 && packageName && await canResolveRuntimePackage(cacheDir, packageName)) {
|
|
3833
|
+
return output;
|
|
3834
|
+
}
|
|
3835
|
+
const command = formatRuntimePlatformRepairCommand(cacheDir, packageSpec);
|
|
3836
|
+
throw new RuntimeInstallError(
|
|
3837
|
+
`Rudder runtime installation is missing required platform package ${packageName || packageSpec}. Re-run manually: ${command}`,
|
|
3838
|
+
{ cacheDir, command, output }
|
|
3839
|
+
);
|
|
3840
|
+
}
|
|
3841
|
+
async function installRuntimePackageInStaging(spawnSyncImpl, cacheDir, packageSpec, packageName) {
|
|
3842
|
+
const stagingDir = path4.join(cacheDir, `.platform-repair-${process.pid}-${Date.now()}`);
|
|
3843
|
+
await mkdir(stagingDir, { recursive: true });
|
|
3844
|
+
try {
|
|
3845
|
+
const packResult = runNpmPack(spawnSyncImpl, packageSpec, stagingDir);
|
|
3846
|
+
if (packResult.status !== 0) return packResult;
|
|
3847
|
+
const packFilename = parseNpmPackFilename(packResult.stdout);
|
|
3848
|
+
if (!packFilename) {
|
|
3849
|
+
return createSyntheticSpawnResult(1, "", `Unable to parse npm pack output for ${packageSpec}.`);
|
|
3850
|
+
}
|
|
3851
|
+
const archivePath = path4.join(stagingDir, packFilename);
|
|
3852
|
+
const targetDir = path4.dirname(runtimePackageJsonPath(cacheDir, packageName));
|
|
3853
|
+
await mkdir(path4.dirname(targetDir), { recursive: true });
|
|
3854
|
+
await rm(targetDir, { recursive: true, force: true });
|
|
3855
|
+
await mkdir(targetDir, { recursive: true });
|
|
3856
|
+
const extractResult = runTarExtract(spawnSyncImpl, archivePath, targetDir);
|
|
3857
|
+
return combineSpawnResults(packResult, extractResult);
|
|
3858
|
+
} finally {
|
|
3859
|
+
await rm(stagingDir, { recursive: true, force: true });
|
|
3860
|
+
}
|
|
3861
|
+
}
|
|
3862
|
+
function runNpmPack(spawnSyncImpl, packageSpec, destinationDir) {
|
|
3863
|
+
return spawnSyncImpl(
|
|
3864
|
+
process.platform === "win32" ? "npm.cmd" : "npm",
|
|
3865
|
+
["pack", packageSpec, "--pack-destination", destinationDir, ...RUNTIME_NPM_PACK_FLAGS],
|
|
3866
|
+
{
|
|
3867
|
+
encoding: "utf8",
|
|
3868
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
3869
|
+
env: { ...process.env, ...NPM_PLATFORM_REPAIR_ENV },
|
|
3870
|
+
...process.platform === "win32" ? { shell: true, windowsHide: true } : {}
|
|
3871
|
+
}
|
|
3872
|
+
);
|
|
3873
|
+
}
|
|
3874
|
+
function runTarExtract(spawnSyncImpl, archivePath, targetDir) {
|
|
3875
|
+
return spawnSyncImpl(
|
|
3876
|
+
"tar",
|
|
3877
|
+
["-xzf", archivePath, "-C", targetDir, "--strip-components", "1"],
|
|
3878
|
+
{
|
|
3879
|
+
encoding: "utf8",
|
|
3880
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
3881
|
+
...process.platform === "win32" ? { windowsHide: true } : {}
|
|
3882
|
+
}
|
|
3883
|
+
);
|
|
3884
|
+
}
|
|
3885
|
+
function parseNpmPackFilename(stdout) {
|
|
3886
|
+
if (typeof stdout !== "string") return null;
|
|
3887
|
+
const filename = stdout.trim().split(/\r?\n/).filter(Boolean).at(-1);
|
|
3888
|
+
return filename?.endsWith(".tgz") ? filename : null;
|
|
3889
|
+
}
|
|
3890
|
+
function createSyntheticSpawnResult(status, stdout, stderr) {
|
|
3891
|
+
return { status, stdout, stderr };
|
|
3892
|
+
}
|
|
3893
|
+
function combineSpawnResults(...results) {
|
|
3894
|
+
const last = results.at(-1);
|
|
3895
|
+
return {
|
|
3896
|
+
status: last?.status ?? 0,
|
|
3897
|
+
stdout: results.map((result) => result.stdout).filter(Boolean).join("\n"),
|
|
3898
|
+
stderr: results.map((result) => result.stderr).filter(Boolean).join("\n"),
|
|
3899
|
+
error: results.find((result) => result.error)?.error
|
|
3900
|
+
};
|
|
3901
|
+
}
|
|
3902
|
+
async function removeRuntimeInstallLocks(cacheDir) {
|
|
3903
|
+
await Promise.all([
|
|
3904
|
+
rm(path4.join(cacheDir, "package-lock.json"), { force: true }),
|
|
3905
|
+
rm(path4.join(cacheDir, "node_modules", ".package-lock.json"), { force: true })
|
|
3906
|
+
]);
|
|
3907
|
+
}
|
|
3908
|
+
function packageNameFromSpec(packageSpec) {
|
|
3909
|
+
if (!packageSpec.startsWith("@")) {
|
|
3910
|
+
const versionSeparator2 = packageSpec.indexOf("@");
|
|
3911
|
+
return versionSeparator2 === -1 ? packageSpec : packageSpec.slice(0, versionSeparator2);
|
|
3912
|
+
}
|
|
3913
|
+
const versionSeparator = packageSpec.indexOf("@", 1);
|
|
3914
|
+
return versionSeparator === -1 ? packageSpec : packageSpec.slice(0, versionSeparator);
|
|
3915
|
+
}
|
|
3916
|
+
function normalizeOptionalDependencyVersion(versionRange) {
|
|
3917
|
+
const trimmed = versionRange?.trim();
|
|
3918
|
+
if (!trimmed) return null;
|
|
3919
|
+
const exactVersion = /^[~^]\s*([0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);
|
|
3920
|
+
return exactVersion?.[1] ?? trimmed;
|
|
3921
|
+
}
|
|
3922
|
+
function runtimePostgresPlatformSegment(platform = process.platform, arch = process.arch) {
|
|
3923
|
+
return `${platform}-${arch}`;
|
|
3924
|
+
}
|
|
3925
|
+
function runtimePostgresExecutableName(baseName) {
|
|
3926
|
+
return process.platform === "win32" ? `${baseName}.exe` : baseName;
|
|
3927
|
+
}
|
|
3928
|
+
async function assertRuntimePostgresBinDirComplete(cacheDir, binDir) {
|
|
3929
|
+
const requiredBinaries = ["initdb", "pg_ctl", "postgres"];
|
|
3930
|
+
const missing = [];
|
|
3931
|
+
for (const binary of requiredBinaries) {
|
|
3932
|
+
const binaryPath = path4.join(binDir, runtimePostgresExecutableName(binary));
|
|
3933
|
+
try {
|
|
3934
|
+
await stat(binaryPath);
|
|
3935
|
+
} catch {
|
|
3936
|
+
missing.push(binaryPath);
|
|
3937
|
+
}
|
|
3938
|
+
}
|
|
3939
|
+
if (missing.length > 0) {
|
|
3940
|
+
throw new RuntimeInstallError(
|
|
3941
|
+
`${RUDDER_POSTGRES_BIN_DIR_ENV} must contain PostgreSQL 18.4 initdb, pg_ctl, and postgres binaries; missing ${missing.join(", ")}`,
|
|
3942
|
+
{ cacheDir, command: "validate PostgreSQL 18.4 runtime payload", output: "" }
|
|
3943
|
+
);
|
|
3944
|
+
}
|
|
3945
|
+
}
|
|
3946
|
+
async function isRuntimePostgresPayloadUsable(cacheDir, binDir) {
|
|
3947
|
+
try {
|
|
3948
|
+
await assertRuntimePostgresBinDirComplete(cacheDir, binDir);
|
|
3949
|
+
const postgresBinary = path4.join(binDir, runtimePostgresExecutableName("postgres"));
|
|
3950
|
+
const result = execFileSync(postgresBinary, ["--version"], { encoding: "utf8" });
|
|
3951
|
+
return /\bPostgreSQL\)?\s+18\.4\b/i.test(result);
|
|
3952
|
+
} catch {
|
|
3953
|
+
return false;
|
|
3954
|
+
}
|
|
3955
|
+
}
|
|
3956
|
+
async function stageRuntimePostgresPayload(cacheDir, enabled) {
|
|
3957
|
+
const targetRuntimeDir = path4.join(cacheDir, RUNTIME_POSTGRES_PAYLOAD_DIR);
|
|
3958
|
+
const targetBinDir = resolveRuntimePostgresPayloadBinDir(cacheDir);
|
|
3959
|
+
if (await isRuntimePostgresPayloadUsable(cacheDir, targetBinDir)) {
|
|
3960
|
+
return { output: "", binDir: targetBinDir };
|
|
3961
|
+
}
|
|
3962
|
+
if (!enabled) return { output: "" };
|
|
3963
|
+
const sourceBinDir = process.env[RUDDER_POSTGRES_BIN_DIR_ENV]?.trim();
|
|
3964
|
+
if (!sourceBinDir) return { output: "" };
|
|
3965
|
+
const resolvedSourceBinDir = path4.resolve(sourceBinDir);
|
|
3966
|
+
await assertRuntimePostgresBinDirComplete(cacheDir, resolvedSourceBinDir);
|
|
3967
|
+
const postgresBinary = path4.join(resolvedSourceBinDir, runtimePostgresExecutableName("postgres"));
|
|
3968
|
+
const result = execFileSync(postgresBinary, ["--version"], { encoding: "utf8" });
|
|
3969
|
+
if (!/\bPostgreSQL\)?\s+18\.4\b/i.test(result)) {
|
|
3970
|
+
throw new RuntimeInstallError(
|
|
3971
|
+
`${RUDDER_POSTGRES_BIN_DIR_ENV} must contain PostgreSQL 18.4 production binaries; got ${result.trim() || "unknown version"}`,
|
|
3972
|
+
{ cacheDir, command: `${postgresBinary} --version`, output: result }
|
|
3973
|
+
);
|
|
3974
|
+
}
|
|
3975
|
+
await rm(targetRuntimeDir, { recursive: true, force: true });
|
|
3976
|
+
await mkdir(path4.dirname(targetBinDir), { recursive: true });
|
|
3977
|
+
await cp(resolvedSourceBinDir, targetBinDir, { recursive: true });
|
|
3978
|
+
return { output: `staged PostgreSQL 18.4 runtime payload at ${targetBinDir}`, binDir: targetBinDir };
|
|
3979
|
+
}
|
|
3706
3980
|
function isVersionNotFoundError(output) {
|
|
3707
3981
|
const normalized = output.toLowerCase();
|
|
3708
3982
|
return normalized.includes("enoent") || normalized.includes("etarget") || normalized.includes("no matching version found");
|
|
@@ -3928,19 +4202,34 @@ function parseRuntimeVersion(version) {
|
|
|
3928
4202
|
canaryNumber: canaryMatch ? Number(canaryMatch[1]) : null
|
|
3929
4203
|
};
|
|
3930
4204
|
}
|
|
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;
|
|
4205
|
+
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
4206
|
var init_install = __esm({
|
|
3933
4207
|
"src/runtime/install.ts"() {
|
|
3934
4208
|
"use strict";
|
|
3935
4209
|
init_home();
|
|
3936
4210
|
RUNTIME_NPM_PACKAGE_NAME = "@rudderhq/server";
|
|
4211
|
+
NPM_PUBLIC_REGISTRY_URL = "https://registry.npmjs.org";
|
|
3937
4212
|
RUNTIME_METADATA_FILE = "runtime.json";
|
|
4213
|
+
RUNTIME_POSTGRES_PAYLOAD_DIR = "postgres-18.4";
|
|
3938
4214
|
DEFAULT_RUNTIME_CACHE_MAX_ENTRIES = 2;
|
|
3939
4215
|
DEFAULT_RUNTIME_CACHE_MAX_AGE_MS = 14 * 24 * 60 * 60 * 1e3;
|
|
3940
4216
|
DEFAULT_RUNTIME_CACHE_MAX_BYTES = 2 * 1024 * 1024 * 1024;
|
|
3941
4217
|
DEFAULT_RUNTIME_CACHE_KEEP_PREVIOUS = 0;
|
|
3942
4218
|
RUNTIME_NPM_INSTALL_FLAGS = ["--omit=dev", "--include=optional", "--no-audit", "--no-fund"];
|
|
4219
|
+
RUNTIME_NPM_PACK_FLAGS = ["--registry", NPM_PUBLIC_REGISTRY_URL, "--silent"];
|
|
3943
4220
|
EMBEDDED_POSTGRES_PACKAGE_NAME = "embedded-postgres";
|
|
4221
|
+
RUDDER_POSTGRES_BIN_DIR_ENV = "RUDDER_POSTGRES_BIN_DIR";
|
|
4222
|
+
RUNTIME_CACHE_PACKAGE_JSON = {
|
|
4223
|
+
name: "rudder-runtime-cache",
|
|
4224
|
+
version: "0.0.0",
|
|
4225
|
+
private: true,
|
|
4226
|
+
type: "module"
|
|
4227
|
+
};
|
|
4228
|
+
NPM_PLATFORM_REPAIR_ENV = {
|
|
4229
|
+
npm_config_registry: NPM_PUBLIC_REGISTRY_URL,
|
|
4230
|
+
npm_config_update_notifier: "false",
|
|
4231
|
+
NO_UPDATE_NOTIFIER: "1"
|
|
4232
|
+
};
|
|
3944
4233
|
RuntimeInstallError = class extends Error {
|
|
3945
4234
|
cacheDir;
|
|
3946
4235
|
command;
|
|
@@ -3991,9 +4280,15 @@ async function loadServerRuntimeModule(options) {
|
|
|
3991
4280
|
}
|
|
3992
4281
|
const installOptions = {
|
|
3993
4282
|
version: options.version,
|
|
3994
|
-
homeDir: options.homeDir
|
|
4283
|
+
homeDir: options.homeDir,
|
|
4284
|
+
preparePostgresPayload: true
|
|
3995
4285
|
};
|
|
3996
4286
|
const runtime = await ensureRuntimeInstalled(installOptions);
|
|
4287
|
+
if (!process.env[RUDDER_POSTGRES_BIN_DIR_ENV2]?.trim()) {
|
|
4288
|
+
if (runtime.postgresPayloadBinDir && fs3.existsSync(runtime.postgresPayloadBinDir)) {
|
|
4289
|
+
process.env[RUDDER_POSTGRES_BIN_DIR_ENV2] = runtime.postgresPayloadBinDir;
|
|
4290
|
+
}
|
|
4291
|
+
}
|
|
3997
4292
|
options.onRuntimeInstalled?.(runtime);
|
|
3998
4293
|
return await importRuntimeServerModule(runtime.cacheDir);
|
|
3999
4294
|
}
|
|
@@ -4016,10 +4311,12 @@ async function startServerFromModule(mod) {
|
|
|
4016
4311
|
takeoverOnVersionMismatch: true
|
|
4017
4312
|
});
|
|
4018
4313
|
}
|
|
4314
|
+
var RUDDER_POSTGRES_BIN_DIR_ENV2;
|
|
4019
4315
|
var init_server_entry = __esm({
|
|
4020
4316
|
"src/runtime/server-entry.ts"() {
|
|
4021
4317
|
"use strict";
|
|
4022
4318
|
init_install();
|
|
4319
|
+
RUDDER_POSTGRES_BIN_DIR_ENV2 = "RUDDER_POSTGRES_BIN_DIR";
|
|
4023
4320
|
}
|
|
4024
4321
|
});
|
|
4025
4322
|
|
|
@@ -5622,7 +5919,7 @@ var init_doctor = __esm({
|
|
|
5622
5919
|
});
|
|
5623
5920
|
|
|
5624
5921
|
// src/install.ts
|
|
5625
|
-
import { execFileSync, spawnSync as spawnSync2 } from "node:child_process";
|
|
5922
|
+
import { execFileSync as execFileSync2, spawnSync as spawnSync2 } from "node:child_process";
|
|
5626
5923
|
function normalizePath(value) {
|
|
5627
5924
|
return (value ?? "").replaceAll("\\", "/").toLowerCase();
|
|
5628
5925
|
}
|
|
@@ -5651,10 +5948,10 @@ function isTransientBinaryPath(candidatePath) {
|
|
|
5651
5948
|
const normalized = normalizePath(candidatePath);
|
|
5652
5949
|
return normalized.includes("/_npx/");
|
|
5653
5950
|
}
|
|
5654
|
-
function hasGlobalInstalledPackage(packageName, execFileSyncImpl =
|
|
5951
|
+
function hasGlobalInstalledPackage(packageName, execFileSyncImpl = execFileSync2) {
|
|
5655
5952
|
return getGlobalInstalledPackageVersion(packageName, execFileSyncImpl) !== null;
|
|
5656
5953
|
}
|
|
5657
|
-
function getGlobalInstalledPackageVersion(packageName, execFileSyncImpl =
|
|
5954
|
+
function getGlobalInstalledPackageVersion(packageName, execFileSyncImpl = execFileSync2) {
|
|
5658
5955
|
try {
|
|
5659
5956
|
const output = execFileSyncImpl(
|
|
5660
5957
|
process.platform === "win32" ? "npm.cmd" : "npm",
|
|
@@ -5670,7 +5967,7 @@ function getGlobalInstalledPackageVersion(packageName, execFileSyncImpl = execFi
|
|
|
5670
5967
|
return null;
|
|
5671
5968
|
}
|
|
5672
5969
|
}
|
|
5673
|
-
function hasPersistentBinaryOnPath(execFileSyncImpl =
|
|
5970
|
+
function hasPersistentBinaryOnPath(execFileSyncImpl = execFileSync2) {
|
|
5674
5971
|
const { command, args } = resolveCommandLookupExecutable();
|
|
5675
5972
|
try {
|
|
5676
5973
|
const output = execFileSyncImpl(command, args, {
|
|
@@ -5685,7 +5982,7 @@ function hasPersistentBinaryOnPath(execFileSyncImpl = execFileSync) {
|
|
|
5685
5982
|
}
|
|
5686
5983
|
function detectPersistentCliState(options = {}) {
|
|
5687
5984
|
const env = options.env ?? process.env;
|
|
5688
|
-
const execFileSyncImpl = options.execFileSyncImpl ??
|
|
5985
|
+
const execFileSyncImpl = options.execFileSyncImpl ?? execFileSync2;
|
|
5689
5986
|
const installSpec = resolvePersistentCliInstallSpec(env);
|
|
5690
5987
|
const usingNpx = isLikelyNpxExecutionContext(options.entryPath ?? process.argv[1], env);
|
|
5691
5988
|
if (!usingNpx) {
|
|
@@ -7270,6 +7567,15 @@ function isMaintainerOnlySkillTarget(candidate) {
|
|
|
7270
7567
|
const normalized = normalizePathSlashes(candidate);
|
|
7271
7568
|
return normalized.includes("/server/resources/bundled-skills/") || normalized.includes("/.agents/skills/");
|
|
7272
7569
|
}
|
|
7570
|
+
function parseObject(value) {
|
|
7571
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
7572
|
+
return {};
|
|
7573
|
+
}
|
|
7574
|
+
return value;
|
|
7575
|
+
}
|
|
7576
|
+
function asString(value, fallback) {
|
|
7577
|
+
return typeof value === "string" && value.length > 0 ? value : fallback;
|
|
7578
|
+
}
|
|
7273
7579
|
|
|
7274
7580
|
// ../packages/agent-runtime-utils/dist/server-utils.prompts.js
|
|
7275
7581
|
var RUDDER_AGENT_OPERATING_CONTRACT = [
|
|
@@ -7293,7 +7599,7 @@ var RUDDER_AGENT_OPERATING_CONTRACT = [
|
|
|
7293
7599
|
"- `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
7600
|
'- 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
7601
|
'- 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
|
|
7602
|
+
"- 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
7603
|
"- 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
7604
|
"",
|
|
7299
7605
|
"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 +7646,16 @@ var RUDDER_AGENT_OPERATING_CONTRACT = [
|
|
|
7340
7646
|
var RUDDER_AGENT_HEARTBEAT_INSTRUCTION = [
|
|
7341
7647
|
"# Rudder Heartbeat Instruction",
|
|
7342
7648
|
"",
|
|
7343
|
-
"This section is injected by Rudder for heartbeat scene runs. It is the platform-owned
|
|
7649
|
+
"This section is injected by Rudder only for heartbeat scene runs. It is the platform-owned heartbeat/self-check pipeline.",
|
|
7344
7650
|
"",
|
|
7345
7651
|
"## Heartbeat Pipeline",
|
|
7346
7652
|
"",
|
|
7347
7653
|
"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
7654
|
"2. Local Planning Check:",
|
|
7349
7655
|
" ",
|
|
7350
|
-
"
|
|
7351
|
-
"
|
|
7352
|
-
"
|
|
7656
|
+
"- 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.",
|
|
7657
|
+
"- Review each planned item: what's completed, what's blocked, and what up next.",
|
|
7658
|
+
"- Record progress updates in the daily notes.",
|
|
7353
7659
|
" ",
|
|
7354
7660
|
"3.Then handle approval follow-up: read the approval and linked issues, then close resolved work or comment on what remains.",
|
|
7355
7661
|
"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 +7663,8 @@ var RUDDER_AGENT_HEARTBEAT_INSTRUCTION = [
|
|
|
7357
7663
|
"6. Checkout before doing assignee task work. A `409` means another agent owns the task; do not retry it.",
|
|
7358
7664
|
"7. Load compact issue context, do one bounded useful chunk, and preserve evidence.",
|
|
7359
7665
|
"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
|
|
7666
|
+
"9. Treat passive follow-up as issue follow-up, not a fresh assignment.",
|
|
7667
|
+
"10. Treat review close-out follow-up as review follow-up; free-form accept/reject text is not a durable decision.",
|
|
7362
7668
|
"",
|
|
7363
7669
|
"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
7670
|
].join("\n");
|
|
@@ -7381,25 +7687,48 @@ async function resolveRudderSkillsDir(moduleDir, additionalCandidates = []) {
|
|
|
7381
7687
|
return null;
|
|
7382
7688
|
}
|
|
7383
7689
|
async function removeMaintainerOnlySkillSymlinks(skillsHome, allowedSkillNames) {
|
|
7690
|
+
return removeUnselectedRudderSkillSymlinks(skillsHome, allowedSkillNames);
|
|
7691
|
+
}
|
|
7692
|
+
async function readRudderMaterializedSkillSource(target) {
|
|
7693
|
+
const manifestPath = path9.join(target, ".rudder", "materialized-skill.json");
|
|
7694
|
+
const raw = await fs6.readFile(manifestPath, "utf8").catch(() => null);
|
|
7695
|
+
if (!raw)
|
|
7696
|
+
return null;
|
|
7697
|
+
try {
|
|
7698
|
+
const parsed = parseObject(JSON.parse(raw));
|
|
7699
|
+
const sourcePath = asString(parsed.sourcePath, "").trim();
|
|
7700
|
+
return sourcePath.length > 0 ? path9.resolve(sourcePath) : null;
|
|
7701
|
+
} catch {
|
|
7702
|
+
return null;
|
|
7703
|
+
}
|
|
7704
|
+
}
|
|
7705
|
+
async function removeUnselectedRudderSkillSymlinks(skillsHome, allowedSkillNames, knownSkillSources = []) {
|
|
7384
7706
|
const allowed = new Set(Array.from(allowedSkillNames));
|
|
7707
|
+
const knownSources = new Set(Array.from(knownSkillSources).map((value) => value.trim()).filter(Boolean).map((value) => path9.resolve(value)));
|
|
7385
7708
|
try {
|
|
7386
7709
|
const entries = await fs6.readdir(skillsHome, { withFileTypes: true });
|
|
7387
7710
|
const removed = [];
|
|
7388
7711
|
for (const entry of entries) {
|
|
7389
|
-
if (allowed.has(entry.name))
|
|
7390
|
-
continue;
|
|
7391
7712
|
const target = path9.join(skillsHome, entry.name);
|
|
7392
7713
|
const existing = await fs6.lstat(target).catch(() => null);
|
|
7393
|
-
if (!existing
|
|
7714
|
+
if (!existing)
|
|
7394
7715
|
continue;
|
|
7395
|
-
|
|
7396
|
-
if (
|
|
7716
|
+
let isRudderManagedSkill = false;
|
|
7717
|
+
if (existing.isSymbolicLink()) {
|
|
7718
|
+
const linkedPath = await fs6.readlink(target).catch(() => null);
|
|
7719
|
+
if (!linkedPath)
|
|
7720
|
+
continue;
|
|
7721
|
+
const resolvedLinkedPath = path9.isAbsolute(linkedPath) ? linkedPath : path9.resolve(path9.dirname(target), linkedPath);
|
|
7722
|
+
isRudderManagedSkill = knownSources.has(path9.resolve(resolvedLinkedPath)) || isMaintainerOnlySkillTarget(linkedPath) || isMaintainerOnlySkillTarget(resolvedLinkedPath);
|
|
7723
|
+
} else if (existing.isDirectory()) {
|
|
7724
|
+
const materializedSource = await readRudderMaterializedSkillSource(target);
|
|
7725
|
+
isRudderManagedSkill = materializedSource !== null && knownSources.has(materializedSource);
|
|
7726
|
+
}
|
|
7727
|
+
if (!isRudderManagedSkill)
|
|
7397
7728
|
continue;
|
|
7398
|
-
|
|
7399
|
-
if (!isMaintainerOnlySkillTarget(linkedPath) && !isMaintainerOnlySkillTarget(resolvedLinkedPath)) {
|
|
7729
|
+
if (allowed.has(entry.name))
|
|
7400
7730
|
continue;
|
|
7401
|
-
}
|
|
7402
|
-
await fs6.unlink(target);
|
|
7731
|
+
await fs6.rm(target, { recursive: true, force: true });
|
|
7403
7732
|
removed.push(entry.name);
|
|
7404
7733
|
}
|
|
7405
7734
|
return removed;
|
|
@@ -13668,7 +13997,7 @@ import * as p15 from "@clack/prompts";
|
|
|
13668
13997
|
import { spawn as spawn2, spawnSync as spawnSync3 } from "node:child_process";
|
|
13669
13998
|
import { createHash, randomUUID } from "node:crypto";
|
|
13670
13999
|
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";
|
|
14000
|
+
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
14001
|
import { homedir, tmpdir } from "node:os";
|
|
13673
14002
|
import path21 from "node:path";
|
|
13674
14003
|
import { Readable, Transform } from "node:stream";
|
|
@@ -13963,6 +14292,9 @@ function resolveDesktopReleaseTag(version) {
|
|
|
13963
14292
|
function isExactRuntimePackageSpec(version, packageSpec) {
|
|
13964
14293
|
return version !== "latest" && packageSpec === resolveRuntimePackageSpec(version);
|
|
13965
14294
|
}
|
|
14295
|
+
function runtimeSupportsDesktopShellAssets(version, runtime) {
|
|
14296
|
+
return isExactRuntimePackageSpec(version, runtime.packageSpec) && Boolean(runtime.postgresPayloadBinDir);
|
|
14297
|
+
}
|
|
13966
14298
|
function resolveDesktopAssetTarget(platform = process.platform, arch = process.arch) {
|
|
13967
14299
|
if (platform === "darwin") {
|
|
13968
14300
|
if (arch !== "x64" && arch !== "arm64") {
|
|
@@ -14843,7 +15175,7 @@ async function copyPortableAppBundle(sourcePath, destinationPath) {
|
|
|
14843
15175
|
if (isSuccessfulRobocopyExitCode(result.status)) return;
|
|
14844
15176
|
throw new Error(formatCommandFailure(command.command, command.args, result.stdout, result.stderr));
|
|
14845
15177
|
}
|
|
14846
|
-
await
|
|
15178
|
+
await cp2(sourcePath, destinationPath, { recursive: true, verbatimSymlinks: true });
|
|
14847
15179
|
}
|
|
14848
15180
|
async function removeMacQuarantine(paths, target) {
|
|
14849
15181
|
if (target.platform !== "macos") return;
|
|
@@ -14958,7 +15290,8 @@ async function runStartPhase(message, successMessage, task, progressPhase) {
|
|
|
14958
15290
|
}
|
|
14959
15291
|
async function startCommand(opts) {
|
|
14960
15292
|
const installCli = opts.cli !== false;
|
|
14961
|
-
const
|
|
15293
|
+
const serverOnly = opts.serverOnly === true;
|
|
15294
|
+
const installDesktop = !serverOnly && opts.desktop !== false;
|
|
14962
15295
|
const installRuntime = opts.runtime !== false;
|
|
14963
15296
|
const repo = opts.repo?.trim() || DEFAULT_DESKTOP_RELEASE_REPO;
|
|
14964
15297
|
const version = opts.targetVersion?.trim() || opts.version?.trim() || resolveCurrentCliVersion();
|
|
@@ -14971,9 +15304,9 @@ async function startCommand(opts) {
|
|
|
14971
15304
|
});
|
|
14972
15305
|
}
|
|
14973
15306
|
if (!installCli && !installDesktop && !installRuntime) {
|
|
14974
|
-
throw new Error("Nothing to start. Remove --no-cli, --no-runtime, or --
|
|
15307
|
+
throw new Error("Nothing to start. Remove --no-cli, --no-runtime, --no-desktop, or --server-only.");
|
|
14975
15308
|
}
|
|
14976
|
-
p15.intro(pc15.bgCyan(pc15.black(" rudder start ")));
|
|
15309
|
+
p15.intro(pc15.bgCyan(pc15.black(serverOnly ? " rudder start --server-only " : " rudder start ")));
|
|
14977
15310
|
if (opts.versionCheck !== false) {
|
|
14978
15311
|
const updateNotice = await getCliUpdateNotice(version);
|
|
14979
15312
|
if (updateNotice) p15.log.warn(updateNotice);
|
|
@@ -14986,11 +15319,14 @@ async function startCommand(opts) {
|
|
|
14986
15319
|
const spinner3 = p15.spinner();
|
|
14987
15320
|
spinner3.start("Installing or reusing Rudder runtime...");
|
|
14988
15321
|
try {
|
|
14989
|
-
const runtime = await ensureRuntimeInstalled({ version });
|
|
14990
|
-
runtimeSupportsShellAssets =
|
|
15322
|
+
const runtime = await ensureRuntimeInstalled({ version, preparePostgresPayload: true });
|
|
15323
|
+
runtimeSupportsShellAssets = runtimeSupportsDesktopShellAssets(version, runtime);
|
|
14991
15324
|
spinner3.stop(
|
|
14992
15325
|
runtime.status === "hit" ? `Rudder runtime cache hit at ${pc15.cyan(runtime.cacheDir)}.` : `Rudder runtime installed at ${pc15.cyan(runtime.cacheDir)}.`
|
|
14993
15326
|
);
|
|
15327
|
+
if (!runtime.postgresPayloadBinDir && installDesktop) {
|
|
15328
|
+
p15.log.warn("Rudder runtime cache has no PostgreSQL 18.4 payload; the full portable Desktop asset will be used.");
|
|
15329
|
+
}
|
|
14994
15330
|
if (!runtimeSupportsShellAssets && installDesktop) {
|
|
14995
15331
|
p15.log.warn("Rudder runtime did not resolve to the exact Desktop version; the full portable Desktop asset will be used.");
|
|
14996
15332
|
}
|
|
@@ -15198,6 +15534,9 @@ async function startCommand(opts) {
|
|
|
15198
15534
|
);
|
|
15199
15535
|
}
|
|
15200
15536
|
});
|
|
15537
|
+
} else if (serverOnly) {
|
|
15538
|
+
p15.log.step("Server-only install");
|
|
15539
|
+
p15.log.message("Desktop app installation was skipped. Start the server with `rudder run` and open the printed local URL in a browser.");
|
|
15201
15540
|
}
|
|
15202
15541
|
p15.outro(pc15.green("Rudder start complete."));
|
|
15203
15542
|
}
|
|
@@ -15268,7 +15607,7 @@ function createProgram() {
|
|
|
15268
15607
|
});
|
|
15269
15608
|
loadRudderEnvFile(options.config);
|
|
15270
15609
|
});
|
|
15271
|
-
program.command("start").description("Start Rudder Desktop and prepare the matching persistent CLI").option("--no-cli", "Skip persistent CLI installation").option("--no-runtime", "Skip Rudder runtime installation").option("--no-desktop", "Skip desktop app installation").option("--version <version>", "Rudder version to start (default: current CLI version)").option("--target-version <version>", "Rudder version to start; avoids the root CLI version flag").option("--repo <owner/repo>", "GitHub repository that hosts desktop releases").option("--output-dir <path>", "Directory for downloaded desktop release assets").option("--desktop-install-dir <path>", "Directory for the portable Desktop install").option("--no-open", "Install Desktop without launching it").option("--wait-for-active-runs", "Wait for active Rudder runs to finish before replacing Desktop", false).option("--desktop-progress-json", "Emit newline-delimited Desktop update progress events").option("--desktop-wait-for-apply", "Wait for an apply signal after downloading and verifying the Desktop update", false).option("--no-version-check", "Skip checking npm for a newer Rudder CLI version").option("--dry-run", "Print the start actions without changing the machine", false).action(startCommand);
|
|
15610
|
+
program.command("start").description("Start Rudder Desktop and prepare the matching persistent CLI").option("--server-only", "Prepare the Rudder server runtime and persistent CLI without installing Desktop").option("--no-cli", "Skip persistent CLI installation").option("--no-runtime", "Skip Rudder runtime installation").option("--no-desktop", "Skip desktop app installation").option("--version <version>", "Rudder version to start (default: current CLI version)").option("--target-version <version>", "Rudder version to start; avoids the root CLI version flag").option("--repo <owner/repo>", "GitHub repository that hosts desktop releases").option("--output-dir <path>", "Directory for downloaded desktop release assets").option("--desktop-install-dir <path>", "Directory for the portable Desktop install").option("--no-open", "Install Desktop without launching it").option("--wait-for-active-runs", "Wait for active Rudder runs to finish before replacing Desktop", false).option("--desktop-progress-json", "Emit newline-delimited Desktop update progress events").option("--desktop-wait-for-apply", "Wait for an apply signal after downloading and verifying the Desktop update", false).option("--no-version-check", "Skip checking npm for a newer Rudder CLI version").option("--dry-run", "Print the start actions without changing the machine", false).action(startCommand);
|
|
15272
15611
|
program.command("onboard").description("Interactive first-run setup wizard").option("-c, --config <path>", "Path to config file").option("-d, --data-dir <path>", DATA_DIR_OPTION_HELP).option("-y, --yes", "Accept defaults (quickstart + start immediately)", false).option("--run", "Start Rudder immediately after saving config", false).action(onboard);
|
|
15273
15612
|
program.command("doctor").description("Run diagnostic checks on your Rudder setup").option("-c, --config <path>", "Path to config file").option("-d, --data-dir <path>", DATA_DIR_OPTION_HELP).option("--repair", "Attempt to repair issues automatically").alias("--fix").option("-y, --yes", "Skip repair confirmation prompts").action(async (opts) => {
|
|
15274
15613
|
await doctor(opts);
|