@eigenpal/cli 0.15.1 → 0.16.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/CHANGELOG.md +12 -0
- package/dist/cli.js +976 -169
- package/dist/docs-bundle.json +61 -19
- package/dist/skill/reference/cli/email-servers.md +175 -0
- package/dist/skill/reference/cli/surface.md +7 -0
- package/dist/skill/reference/evaluators.md +2 -2
- package/dist/skill/reference/step-types.md +264 -18
- package/dist/skill/reference/workflow-yaml.md +2 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -7685,6 +7685,7 @@ var init_common = __esm(() => {
|
|
|
7685
7685
|
AUTOMATION_TRIGGER: "atr",
|
|
7686
7686
|
FILE_SOURCE_CONFIG: "fsc",
|
|
7687
7687
|
FILE_UPLOAD: "fup",
|
|
7688
|
+
EMAIL_SERVER: "ems",
|
|
7688
7689
|
WEBHOOK_ENDPOINT: "whep",
|
|
7689
7690
|
WEBHOOK_EVENT: "whev",
|
|
7690
7691
|
WEBHOOK_DELIVERY: "whdl",
|
|
@@ -7803,7 +7804,11 @@ var init_ai_client = __esm(() => {
|
|
|
7803
7804
|
];
|
|
7804
7805
|
ReasoningEffortSchema = _enum(REASONING_EFFORTS);
|
|
7805
7806
|
ModelReasoningConfigSchema = object({
|
|
7806
|
-
supportedEfforts: array(ReasoningEffortSchema).min(1)
|
|
7807
|
+
supportedEfforts: array(ReasoningEffortSchema).min(1),
|
|
7808
|
+
defaultEffort: ReasoningEffortSchema.optional()
|
|
7809
|
+
}).refine((config) => config.defaultEffort === undefined || config.supportedEfforts.includes(config.defaultEffort), {
|
|
7810
|
+
message: "defaultEffort must be included in supportedEfforts",
|
|
7811
|
+
path: ["defaultEffort"]
|
|
7807
7812
|
}).strict();
|
|
7808
7813
|
});
|
|
7809
7814
|
|
|
@@ -15429,6 +15434,250 @@ var init_validation = __esm(() => {
|
|
|
15429
15434
|
init_workspace_schema();
|
|
15430
15435
|
});
|
|
15431
15436
|
|
|
15437
|
+
// ../types/src/email-servers.ts
|
|
15438
|
+
function defaultSmtpPort(security, port) {
|
|
15439
|
+
return port ?? SMTP_DEFAULT_PORT_BY_SECURITY[security];
|
|
15440
|
+
}
|
|
15441
|
+
function refineSmtpCredentialPair(data, ctx) {
|
|
15442
|
+
const hasUsername = data.username !== undefined;
|
|
15443
|
+
const hasPassword = data.password !== undefined;
|
|
15444
|
+
if (hasUsername !== hasPassword) {
|
|
15445
|
+
ctx.addIssue({
|
|
15446
|
+
code: "custom",
|
|
15447
|
+
path: hasUsername ? ["password"] : ["username"],
|
|
15448
|
+
message: "SMTP username and password must both be set or both omitted"
|
|
15449
|
+
});
|
|
15450
|
+
}
|
|
15451
|
+
}
|
|
15452
|
+
function refineSmtpNoneRejectsCredentials(data, ctx) {
|
|
15453
|
+
if (data.security !== "none")
|
|
15454
|
+
return;
|
|
15455
|
+
if (typeof data.username === "string") {
|
|
15456
|
+
ctx.addIssue({
|
|
15457
|
+
code: "custom",
|
|
15458
|
+
path: ["username"],
|
|
15459
|
+
message: SMTP_NONE_CREDENTIALS_MESSAGE
|
|
15460
|
+
});
|
|
15461
|
+
}
|
|
15462
|
+
if (data.password !== undefined) {
|
|
15463
|
+
ctx.addIssue({
|
|
15464
|
+
code: "custom",
|
|
15465
|
+
path: ["password"],
|
|
15466
|
+
message: SMTP_NONE_CREDENTIALS_MESSAGE
|
|
15467
|
+
});
|
|
15468
|
+
}
|
|
15469
|
+
}
|
|
15470
|
+
function hasTransport(patch) {
|
|
15471
|
+
return "transport" in patch;
|
|
15472
|
+
}
|
|
15473
|
+
function smtpDestinationChanged(existingTransport, patch, storedSmtp) {
|
|
15474
|
+
if (existingTransport !== "smtp")
|
|
15475
|
+
return false;
|
|
15476
|
+
const hostChanged = storedSmtp?.host != null && storedSmtp.host !== patch.host;
|
|
15477
|
+
const usernameChanged = typeof patch.username === "string" && patch.username !== (storedSmtp?.username ?? null);
|
|
15478
|
+
return hostChanged || usernameChanged;
|
|
15479
|
+
}
|
|
15480
|
+
function planEmailServerSecretUpdate(input) {
|
|
15481
|
+
if (!hasTransport(input.patch)) {
|
|
15482
|
+
return { resendApiKey: "retain", smtpPassword: "retain", caPem: "retain" };
|
|
15483
|
+
}
|
|
15484
|
+
if (input.patch.transport === "resend") {
|
|
15485
|
+
return {
|
|
15486
|
+
resendApiKey: input.patch.apiKey !== undefined ? "set" : "retain",
|
|
15487
|
+
smtpPassword: "clear",
|
|
15488
|
+
caPem: "clear"
|
|
15489
|
+
};
|
|
15490
|
+
}
|
|
15491
|
+
const password = input.patch.password !== undefined ? "set" : input.patch.username === null ? "clear" : input.existingTransport !== "smtp" ? "clear" : smtpDestinationChanged(input.existingTransport, input.patch, input.storedSmtp) ? "clear" : "retain";
|
|
15492
|
+
const caPem = input.patch.caPem === null ? "clear" : input.patch.caPem !== undefined ? "set" : input.existingTransport === "smtp" ? "retain" : "clear";
|
|
15493
|
+
return {
|
|
15494
|
+
resendApiKey: "clear",
|
|
15495
|
+
smtpPassword: password,
|
|
15496
|
+
caPem
|
|
15497
|
+
};
|
|
15498
|
+
}
|
|
15499
|
+
function planSmtpAuthActions(existingTransport, patch, storedSmtp) {
|
|
15500
|
+
const secrets = planEmailServerSecretUpdate({ existingTransport, storedSmtp, patch });
|
|
15501
|
+
const username = patch.username === null ? "clear" : typeof patch.username === "string" ? "set" : existingTransport === "smtp" ? "retain" : "clear";
|
|
15502
|
+
return { username, password: secrets.smtpPassword };
|
|
15503
|
+
}
|
|
15504
|
+
function actionLeavesPresent(action, storedPresent) {
|
|
15505
|
+
if (action === "set")
|
|
15506
|
+
return true;
|
|
15507
|
+
if (action === "clear")
|
|
15508
|
+
return false;
|
|
15509
|
+
return storedPresent;
|
|
15510
|
+
}
|
|
15511
|
+
function getEmailServerUpdateError(existingTransport, patch, storedSmtp) {
|
|
15512
|
+
if (hasTransport(patch) && patch.transport === "smtp") {
|
|
15513
|
+
const auth = planSmtpAuthActions(existingTransport, patch, storedSmtp);
|
|
15514
|
+
const hasUsername = actionLeavesPresent(auth.username, Boolean(storedSmtp?.username));
|
|
15515
|
+
const hasPassword = actionLeavesPresent(auth.password, storedSmtp?.passwordConfigured === true);
|
|
15516
|
+
if (patch.security === "none" && (hasUsername || hasPassword)) {
|
|
15517
|
+
return SMTP_NONE_CREDENTIALS_MESSAGE;
|
|
15518
|
+
}
|
|
15519
|
+
if (smtpDestinationChanged(existingTransport, patch, storedSmtp) && patch.password === undefined && hasUsername && storedSmtp?.passwordConfigured === true) {
|
|
15520
|
+
return SMTP_TARGET_PASSWORD_MESSAGE;
|
|
15521
|
+
}
|
|
15522
|
+
if (hasUsername !== hasPassword) {
|
|
15523
|
+
return SMTP_CREDENTIAL_PAIR_MESSAGE;
|
|
15524
|
+
}
|
|
15525
|
+
}
|
|
15526
|
+
if (!hasTransport(patch))
|
|
15527
|
+
return null;
|
|
15528
|
+
if (patch.transport === existingTransport)
|
|
15529
|
+
return null;
|
|
15530
|
+
if (patch.transport === "resend" && patch.apiKey === undefined) {
|
|
15531
|
+
return "Resend API key is required when changing transport to resend";
|
|
15532
|
+
}
|
|
15533
|
+
return null;
|
|
15534
|
+
}
|
|
15535
|
+
var EMAIL_SERVER_TRANSPORTS, SMTP_SECURITY_MODES, SMTP_DEFAULT_PORT_BY_SECURITY, EMAIL_SERVER_ID_PREFIX, EMAIL_SERVER_ID_PATTERN, EmailServerIdSchema, EmailServerNameSchema, EmailServerFromEmailSchema, FROM_NAME_UNSAFE, EmailServerFromNameSchema, SmtpHostSchema, SmtpPortSchema, SmtpSecuritySchema, SmtpUsernameSchema, SecretStringSchema, fromFields, SMTP_NONE_CREDENTIALS_MESSAGE = "SMTP credentials cannot be used with security 'none'", SMTP_CREDENTIAL_PAIR_MESSAGE = "SMTP username and password must both be present or both absent", SMTP_TARGET_PASSWORD_MESSAGE = "A new SMTP password is required when the host or username changes", CreateResendEmailServerRequestSchema, CreateSmtpEmailServerRequestSchema, CreateEmailServerRequestSchema, UpdateMetadataOnlySchema, UpdateResendEmailServerRequestSchema, UpdateSmtpEmailServerRequestSchema, UpdateEmailServerRequestSchema, PublicEmailServerTimestamps, PublicResendEmailServerSchema, PublicSmtpEmailServerSchema, EmailServerSchema, ListEmailServersResponseSchema, DeleteEmailServerResponseSchema, TestEmailServerRequestSchema, TestEmailServerResponseSchema;
|
|
15536
|
+
var init_email_servers = __esm(() => {
|
|
15537
|
+
init_zod();
|
|
15538
|
+
init_common();
|
|
15539
|
+
EMAIL_SERVER_TRANSPORTS = ["resend", "smtp"];
|
|
15540
|
+
SMTP_SECURITY_MODES = ["starttls", "tls", "none"];
|
|
15541
|
+
SMTP_DEFAULT_PORT_BY_SECURITY = {
|
|
15542
|
+
starttls: 587,
|
|
15543
|
+
tls: 465,
|
|
15544
|
+
none: 25
|
|
15545
|
+
};
|
|
15546
|
+
EMAIL_SERVER_ID_PREFIX = ID_PREFIXES.EMAIL_SERVER;
|
|
15547
|
+
EMAIL_SERVER_ID_PATTERN = /^ems_[A-Za-z0-9_-]+$/;
|
|
15548
|
+
EmailServerIdSchema = string2().regex(EMAIL_SERVER_ID_PATTERN, "Expected ems_… id").max(128);
|
|
15549
|
+
EmailServerNameSchema = string2().trim().min(1).max(128);
|
|
15550
|
+
EmailServerFromEmailSchema = string2().trim().email();
|
|
15551
|
+
FROM_NAME_UNSAFE = /[\p{Cc}<>]/u;
|
|
15552
|
+
EmailServerFromNameSchema = string2().trim().min(1).max(128).refine((value) => !FROM_NAME_UNSAFE.test(value), {
|
|
15553
|
+
message: "fromName cannot contain control characters or angle brackets"
|
|
15554
|
+
});
|
|
15555
|
+
SmtpHostSchema = string2().trim().min(1).max(253);
|
|
15556
|
+
SmtpPortSchema = number2().int().min(1).max(65535);
|
|
15557
|
+
SmtpSecuritySchema = _enum(SMTP_SECURITY_MODES);
|
|
15558
|
+
SmtpUsernameSchema = string2().min(1).max(256);
|
|
15559
|
+
SecretStringSchema = string2().min(1);
|
|
15560
|
+
fromFields = {
|
|
15561
|
+
fromEmail: EmailServerFromEmailSchema,
|
|
15562
|
+
fromName: EmailServerFromNameSchema
|
|
15563
|
+
};
|
|
15564
|
+
CreateResendEmailServerRequestSchema = object({
|
|
15565
|
+
name: EmailServerNameSchema,
|
|
15566
|
+
enabled: boolean2().optional().default(true),
|
|
15567
|
+
transport: literal("resend"),
|
|
15568
|
+
apiKey: SecretStringSchema,
|
|
15569
|
+
...fromFields
|
|
15570
|
+
}).strict();
|
|
15571
|
+
CreateSmtpEmailServerRequestSchema = object({
|
|
15572
|
+
name: EmailServerNameSchema,
|
|
15573
|
+
enabled: boolean2().optional().default(true),
|
|
15574
|
+
transport: literal("smtp"),
|
|
15575
|
+
host: SmtpHostSchema,
|
|
15576
|
+
port: SmtpPortSchema.optional(),
|
|
15577
|
+
security: SmtpSecuritySchema.optional().default("starttls"),
|
|
15578
|
+
username: SmtpUsernameSchema.optional(),
|
|
15579
|
+
password: SecretStringSchema.optional(),
|
|
15580
|
+
caPem: SecretStringSchema.optional(),
|
|
15581
|
+
...fromFields
|
|
15582
|
+
}).strict().superRefine((data, ctx) => {
|
|
15583
|
+
refineSmtpCredentialPair(data, ctx);
|
|
15584
|
+
refineSmtpNoneRejectsCredentials(data, ctx);
|
|
15585
|
+
}).transform((data) => ({
|
|
15586
|
+
...data,
|
|
15587
|
+
port: defaultSmtpPort(data.security, data.port)
|
|
15588
|
+
}));
|
|
15589
|
+
CreateEmailServerRequestSchema = discriminatedUnion("transport", [
|
|
15590
|
+
CreateResendEmailServerRequestSchema,
|
|
15591
|
+
CreateSmtpEmailServerRequestSchema
|
|
15592
|
+
]).meta({ id: "CreateEmailServerRequest" });
|
|
15593
|
+
UpdateMetadataOnlySchema = object({
|
|
15594
|
+
name: EmailServerNameSchema.optional(),
|
|
15595
|
+
enabled: boolean2().optional()
|
|
15596
|
+
}).strict().superRefine((value, ctx) => {
|
|
15597
|
+
if (value.name === undefined && value.enabled === undefined) {
|
|
15598
|
+
ctx.addIssue({
|
|
15599
|
+
code: "custom",
|
|
15600
|
+
message: "at least one field is required"
|
|
15601
|
+
});
|
|
15602
|
+
}
|
|
15603
|
+
});
|
|
15604
|
+
UpdateResendEmailServerRequestSchema = object({
|
|
15605
|
+
name: EmailServerNameSchema.optional(),
|
|
15606
|
+
enabled: boolean2().optional(),
|
|
15607
|
+
transport: literal("resend"),
|
|
15608
|
+
apiKey: SecretStringSchema.optional(),
|
|
15609
|
+
...fromFields
|
|
15610
|
+
}).strict();
|
|
15611
|
+
UpdateSmtpEmailServerRequestSchema = object({
|
|
15612
|
+
name: EmailServerNameSchema.optional(),
|
|
15613
|
+
enabled: boolean2().optional(),
|
|
15614
|
+
transport: literal("smtp"),
|
|
15615
|
+
host: SmtpHostSchema,
|
|
15616
|
+
port: SmtpPortSchema,
|
|
15617
|
+
security: SmtpSecuritySchema,
|
|
15618
|
+
username: SmtpUsernameSchema.nullable().optional(),
|
|
15619
|
+
password: SecretStringSchema.optional(),
|
|
15620
|
+
caPem: SecretStringSchema.nullable().optional(),
|
|
15621
|
+
...fromFields
|
|
15622
|
+
}).strict().superRefine(refineSmtpNoneRejectsCredentials);
|
|
15623
|
+
UpdateEmailServerRequestSchema = union([
|
|
15624
|
+
UpdateResendEmailServerRequestSchema,
|
|
15625
|
+
UpdateSmtpEmailServerRequestSchema,
|
|
15626
|
+
UpdateMetadataOnlySchema
|
|
15627
|
+
]).meta({ id: "UpdateEmailServerRequest" });
|
|
15628
|
+
PublicEmailServerTimestamps = {
|
|
15629
|
+
id: EmailServerIdSchema,
|
|
15630
|
+
name: EmailServerNameSchema,
|
|
15631
|
+
enabled: boolean2(),
|
|
15632
|
+
createdAt: union([string2(), exports_coerce.date()]),
|
|
15633
|
+
updatedAt: union([string2(), exports_coerce.date()])
|
|
15634
|
+
};
|
|
15635
|
+
PublicResendEmailServerSchema = object({
|
|
15636
|
+
...PublicEmailServerTimestamps,
|
|
15637
|
+
transport: literal("resend"),
|
|
15638
|
+
fromEmail: EmailServerFromEmailSchema,
|
|
15639
|
+
fromName: EmailServerFromNameSchema,
|
|
15640
|
+
apiKeyConfigured: literal(true)
|
|
15641
|
+
}).strict().meta({ id: "PublicResendEmailServer" });
|
|
15642
|
+
PublicSmtpEmailServerSchema = object({
|
|
15643
|
+
...PublicEmailServerTimestamps,
|
|
15644
|
+
transport: literal("smtp"),
|
|
15645
|
+
fromEmail: EmailServerFromEmailSchema,
|
|
15646
|
+
fromName: EmailServerFromNameSchema,
|
|
15647
|
+
host: SmtpHostSchema,
|
|
15648
|
+
port: SmtpPortSchema,
|
|
15649
|
+
security: SmtpSecuritySchema,
|
|
15650
|
+
username: string2().nullable(),
|
|
15651
|
+
passwordConfigured: boolean2(),
|
|
15652
|
+
caPemConfigured: boolean2()
|
|
15653
|
+
}).strict().meta({ id: "PublicSmtpEmailServer" });
|
|
15654
|
+
EmailServerSchema = discriminatedUnion("transport", [PublicResendEmailServerSchema, PublicSmtpEmailServerSchema]).meta({ id: "EmailServer" });
|
|
15655
|
+
ListEmailServersResponseSchema = object({
|
|
15656
|
+
data: array(EmailServerSchema),
|
|
15657
|
+
total: number2().int(),
|
|
15658
|
+
limit: number2().int(),
|
|
15659
|
+
offset: number2().int()
|
|
15660
|
+
}).meta({ id: "ListEmailServersResponse" });
|
|
15661
|
+
DeleteEmailServerResponseSchema = object({
|
|
15662
|
+
deleted: literal(true),
|
|
15663
|
+
id: EmailServerIdSchema
|
|
15664
|
+
}).strict().meta({ id: "DeleteEmailServerResponse" });
|
|
15665
|
+
TestEmailServerRequestSchema = object({
|
|
15666
|
+
to: EmailServerFromEmailSchema
|
|
15667
|
+
}).strict().meta({ id: "TestEmailServerRequest" });
|
|
15668
|
+
TestEmailServerResponseSchema = discriminatedUnion("ok", [
|
|
15669
|
+
object({
|
|
15670
|
+
ok: literal(true),
|
|
15671
|
+
transport: _enum(EMAIL_SERVER_TRANSPORTS),
|
|
15672
|
+
messageId: string2().min(1)
|
|
15673
|
+
}).strict(),
|
|
15674
|
+
object({
|
|
15675
|
+
ok: literal(false),
|
|
15676
|
+
error: string2().min(1)
|
|
15677
|
+
}).strict()
|
|
15678
|
+
]).meta({ id: "TestEmailServerResponse" });
|
|
15679
|
+
});
|
|
15680
|
+
|
|
15432
15681
|
// ../../node_modules/@babel/parser/lib/index.js
|
|
15433
15682
|
var require_lib = __commonJS(function(exports) {
|
|
15434
15683
|
Object.defineProperty(exports, "__esModule", {
|
|
@@ -52892,6 +53141,61 @@ var init_typed_script = __esm(() => {
|
|
|
52892
53141
|
init_compile();
|
|
52893
53142
|
});
|
|
52894
53143
|
|
|
53144
|
+
// ../types/src/workflow/email-recipients.ts
|
|
53145
|
+
function splitRecipientTokens(value) {
|
|
53146
|
+
const tokens = [];
|
|
53147
|
+
let start = 0;
|
|
53148
|
+
let templateClose;
|
|
53149
|
+
for (let index = 0;index < value.length; index++) {
|
|
53150
|
+
if (templateClose) {
|
|
53151
|
+
if (value.startsWith(templateClose, index)) {
|
|
53152
|
+
index++;
|
|
53153
|
+
templateClose = undefined;
|
|
53154
|
+
}
|
|
53155
|
+
continue;
|
|
53156
|
+
}
|
|
53157
|
+
if (value.startsWith("{{", index)) {
|
|
53158
|
+
templateClose = "}}";
|
|
53159
|
+
index++;
|
|
53160
|
+
continue;
|
|
53161
|
+
}
|
|
53162
|
+
if (value.startsWith("{%", index)) {
|
|
53163
|
+
templateClose = "%}";
|
|
53164
|
+
index++;
|
|
53165
|
+
continue;
|
|
53166
|
+
}
|
|
53167
|
+
if (value[index] === ",") {
|
|
53168
|
+
tokens.push(value.slice(start, index));
|
|
53169
|
+
start = index + 1;
|
|
53170
|
+
}
|
|
53171
|
+
}
|
|
53172
|
+
tokens.push(value.slice(start));
|
|
53173
|
+
return tokens;
|
|
53174
|
+
}
|
|
53175
|
+
function countDeterministicEmailRecipients(value) {
|
|
53176
|
+
if (value === undefined || value === null)
|
|
53177
|
+
return 0;
|
|
53178
|
+
const parts = Array.isArray(value) ? value : [value];
|
|
53179
|
+
let count = 0;
|
|
53180
|
+
for (const part of parts) {
|
|
53181
|
+
if (typeof part !== "string")
|
|
53182
|
+
continue;
|
|
53183
|
+
const tokens = splitRecipientTokens(part).map((token) => token.trim()).filter((token) => token.length > 0);
|
|
53184
|
+
count += tokens.length;
|
|
53185
|
+
}
|
|
53186
|
+
return count;
|
|
53187
|
+
}
|
|
53188
|
+
function countActionEmailRecipients(fields) {
|
|
53189
|
+
return countDeterministicEmailRecipients(fields.to) + countDeterministicEmailRecipients(fields.cc) + countDeterministicEmailRecipients(fields.bcc);
|
|
53190
|
+
}
|
|
53191
|
+
function actionEmailRecipientCountExceedsLimit(fields) {
|
|
53192
|
+
return countActionEmailRecipients(fields) > ACTION_EMAIL_MAX_RECIPIENTS;
|
|
53193
|
+
}
|
|
53194
|
+
var ACTION_EMAIL_MAX_RECIPIENTS = 10, ACTION_EMAIL_RECIPIENT_LIMIT_MESSAGE;
|
|
53195
|
+
var init_email_recipients = __esm(() => {
|
|
53196
|
+
ACTION_EMAIL_RECIPIENT_LIMIT_MESSAGE = `At most ${ACTION_EMAIL_MAX_RECIPIENTS} recipients combined across to, cc, and bcc`;
|
|
53197
|
+
});
|
|
53198
|
+
|
|
52895
53199
|
// ../types/src/workflow/script-function.ts
|
|
52896
53200
|
var SCRIPT_FN_MAX_BYTES = 50000;
|
|
52897
53201
|
|
|
@@ -52998,7 +53302,8 @@ var init_steps = __esm(() => {
|
|
|
52998
53302
|
ACTION_STEP_TYPES = [
|
|
52999
53303
|
"action.http",
|
|
53000
53304
|
"action.invoke-workflow",
|
|
53001
|
-
"action.website-reader"
|
|
53305
|
+
"action.website-reader",
|
|
53306
|
+
"action.email"
|
|
53002
53307
|
];
|
|
53003
53308
|
CONTROL_STEP_TYPES = [
|
|
53004
53309
|
"control.if",
|
|
@@ -53128,17 +53433,19 @@ function getStepSchema(stepType) {
|
|
|
53128
53433
|
function listStepTypes() {
|
|
53129
53434
|
return [...STEP_TYPES];
|
|
53130
53435
|
}
|
|
53131
|
-
var OptionalReasoningEffortSchema, AiParseConfigSchema, AiParseOutputSchema, AiExtractConfigSchema, AiExtractOutputSchema, VisionPageRangeSchema, AiVisionConfigSchema, AiVisionOutputSchema, AiSplitConfigSchema, AiSplitSectionSchema, AiSplitOutputSchema, AiSegmentConfigSchema, AiSegmentOutputSchema, AiClassifyConfigSchema, AiClassifyOutputSchema, ClassifyPagesLabelSchema2, AiClassifyPagesConfigSchema, AiClassifyPagesOutputSchema, TransformSetConfigSchema, TransformSetOutputSchema, TransformRemoveConfigSchema, TransformRemoveOutputSchema, TransformCombineConfigSchema, TransformCombineOutputSchema, TransformSplitConfigSchema, TransformSplitOutputSchema, TransformMergeConfigSchema, TransformMergeOutputSchema, TransformTemplateConfigSchema, TransformTemplateOutputSchema, TransformPdfEmbedConfigSchema, TransformPdfEmbedOutputSchema, TransformXlsxToJsonConfigSchema, TransformXlsxToJsonOutputSchema, JsonToXlsxAuthoringRowsSchema, JsonToXlsxSheetConfigSchema, TransformJsonToXlsxConfigSchema, TransformJsonToXlsxOutputSchema, TransformScriptConfigSchema, TransformScriptOutputSchema, ParsedDocPageSchema, TransformTextChunkerConfigSchema, TransformTextChunkerOutputSchema, RegexNormalizerSchema, RegexFormatSchema, REGEX_FLAGS, RegexFieldSchema, TransformRegexExtractConfigSchema, TransformRegexExtractOutputSchema, ActionHttpConfigSchema, ActionHttpOutputSchema, ActionInvokeWorkflowConfigSchema, ActionInvokeWorkflowOutputSchema, ActionWebsiteReaderConfigSchema, ActionWebsiteReaderOutputSchema, ControlIfConfigSchema, ControlIfOutputSchema, ControlSwitchConfigSchema, ControlSwitchOutputSchema, ControlForeachConfigSchema, ControlForeachOutputSchema, ControlParallelMapConfigSchema, ControlParallelMapOutputSchema, ControlParallelConfigSchema, ControlParallelOutputSchema, ControlWaitConfigSchema, ControlWaitOutputSchema, ControlFailConfigSchema, ControlFailOutputSchema, STEP_SCHEMAS;
|
|
53436
|
+
var OptionalReasoningEffortSchema, AiParseConfigSchema, AiParseOutputSchema, AiExtractConfigSchema, AiExtractOutputSchema, VisionPageRangeSchema, AiVisionConfigSchema, AiVisionOutputSchema, AiSplitConfigSchema, AiSplitSectionSchema, AiSplitOutputSchema, AiSegmentConfigSchema, AiSegmentOutputSchema, AiClassifyConfigSchema, AiClassifyOutputSchema, ClassifyPagesLabelSchema2, AiClassifyPagesConfigSchema, AiClassifyPagesOutputSchema, TransformSetConfigSchema, TransformSetOutputSchema, TransformRemoveConfigSchema, TransformRemoveOutputSchema, TransformCombineConfigSchema, TransformCombineOutputSchema, TransformSplitConfigSchema, TransformSplitOutputSchema, TransformMergeConfigSchema, TransformMergeOutputSchema, TransformTemplateConfigSchema, TransformTemplateOutputSchema, TransformPdfEmbedConfigSchema, TransformPdfEmbedOutputSchema, TransformXlsxToJsonConfigSchema, TransformXlsxToJsonOutputSchema, JsonToXlsxAuthoringRowsSchema, JsonToXlsxSheetConfigSchema, TransformJsonToXlsxConfigSchema, TransformJsonToXlsxOutputSchema, TransformScriptConfigSchema, TransformScriptOutputSchema, ParsedDocPageSchema, TransformTextChunkerConfigSchema, TransformTextChunkerOutputSchema, RegexNormalizerSchema, RegexFormatSchema, REGEX_FLAGS, RegexFieldSchema, TransformRegexExtractConfigSchema, TransformRegexExtractOutputSchema, ActionHttpConfigSchema, ActionHttpOutputSchema, ActionInvokeWorkflowConfigSchema, ActionInvokeWorkflowOutputSchema, ActionWebsiteReaderConfigSchema, ActionWebsiteReaderOutputSchema, ACTION_EMAIL_MAX_ATTACHMENTS = 10, ACTION_EMAIL_MAX_ATTACHMENT_BYTES, ACTION_EMAIL_BODY_MAX_BYTES, emailBodyMaxBytes = (value) => new TextEncoder().encode(value).byteLength <= ACTION_EMAIL_BODY_MAX_BYTES, ActionEmailRecipientListSchema, ActionEmailToSchema, ActionEmailOptionalRecipientsSchema, ActionEmailAttachmentSchema, ActionEmailConfigSchema, ActionEmailOutputSchema, ControlIfConfigSchema, ControlIfOutputSchema, ControlSwitchConfigSchema, ControlSwitchOutputSchema, ControlForeachConfigSchema, ControlForeachOutputSchema, ControlParallelMapConfigSchema, ControlParallelMapOutputSchema, ControlParallelConfigSchema, ControlParallelOutputSchema, ControlWaitConfigSchema, ControlWaitOutputSchema, ControlFailConfigSchema, ControlFailOutputSchema, STEP_SCHEMAS;
|
|
53132
53437
|
var init_step_configs = __esm(() => {
|
|
53133
53438
|
init_zod();
|
|
53134
53439
|
init_ai_client();
|
|
53135
53440
|
init_common();
|
|
53441
|
+
init_email_servers();
|
|
53136
53442
|
init_parser();
|
|
53137
53443
|
init_json_to_xlsx();
|
|
53138
53444
|
init_xlsx_to_json();
|
|
53139
53445
|
init_typed_script();
|
|
53446
|
+
init_email_recipients();
|
|
53140
53447
|
init_steps();
|
|
53141
|
-
OptionalReasoningEffortSchema = ReasoningEffortSchema.optional().describe("Reasoning effort for models that support it. Omit to
|
|
53448
|
+
OptionalReasoningEffortSchema = ReasoningEffortSchema.optional().describe("Reasoning effort for models that support it. Omit to use the selected model's default.");
|
|
53142
53449
|
AiParseConfigSchema = object({
|
|
53143
53450
|
input: string2().describe("Storage reference or template expression for the document"),
|
|
53144
53451
|
parseMode: ParseModeSchema.optional().describe('Base parser for PDF/image inputs. OCR is the default; vision uses the selected LLM. `native` extracts PDF embedded text only and never calls OCR or vision. `native-or-ocr` extracts native text, runs page-quality diagnostics, and requests OCR when pages have detectable anomalies (empty, U+FFFD, lone surrogates, forbidden controls, unassigned/noncharacter, heavy PUA). Page selection, subset egress, and billing are provider-dependent. Valid-looking wrong text and literal "?" are not flagged. Text and Office files always use local parsing.'),
|
|
@@ -53661,6 +53968,54 @@ var init_step_configs = __esm(() => {
|
|
|
53661
53968
|
length: number2().describe("Content length in characters"),
|
|
53662
53969
|
url: string2().describe("Final URL after redirects")
|
|
53663
53970
|
});
|
|
53971
|
+
ACTION_EMAIL_MAX_ATTACHMENT_BYTES = 12 * 1024 * 1024;
|
|
53972
|
+
ACTION_EMAIL_BODY_MAX_BYTES = 50 * 1024;
|
|
53973
|
+
ActionEmailRecipientListSchema = array(string2().min(1));
|
|
53974
|
+
ActionEmailToSchema = union([
|
|
53975
|
+
string2().min(1, "To is required"),
|
|
53976
|
+
ActionEmailRecipientListSchema.min(1, "To requires at least one recipient")
|
|
53977
|
+
]);
|
|
53978
|
+
ActionEmailOptionalRecipientsSchema = union([
|
|
53979
|
+
string2().min(1),
|
|
53980
|
+
ActionEmailRecipientListSchema
|
|
53981
|
+
]);
|
|
53982
|
+
ActionEmailAttachmentSchema = union([
|
|
53983
|
+
string2().min(1).describe("File id or template expression that resolves to a file id"),
|
|
53984
|
+
object({
|
|
53985
|
+
fileId: string2().min(1).describe("File id or template expression that resolves to a file id"),
|
|
53986
|
+
filename: string2().min(1).optional().describe("Optional download filename override")
|
|
53987
|
+
})
|
|
53988
|
+
]);
|
|
53989
|
+
ActionEmailConfigSchema = object({
|
|
53990
|
+
server: EmailServerIdSchema.describe("Outbound email server id (`ems_…`)"),
|
|
53991
|
+
to: ActionEmailToSchema.describe("Primary recipient(s). String, comma-separated list, or nonempty string array. Combined with cc and bcc, at most 10 recipients."),
|
|
53992
|
+
cc: ActionEmailOptionalRecipientsSchema.optional().describe("Carbon-copy recipient(s). String, comma-separated list, or string array. Combined with to and bcc, at most 10 recipients."),
|
|
53993
|
+
bcc: ActionEmailOptionalRecipientsSchema.optional().describe("Blind carbon-copy recipient(s). String, comma-separated list, or string array. Combined with to and cc, at most 10 recipients."),
|
|
53994
|
+
replyTo: string2().min(1).optional().describe("Reply-To address (supports template expressions)"),
|
|
53995
|
+
subject: string2().min(1, "Subject is required").describe("Email subject"),
|
|
53996
|
+
text: string2().min(1, "Body is required").refine(emailBodyMaxBytes, {
|
|
53997
|
+
message: `Email body must be at most ${ACTION_EMAIL_BODY_MAX_BYTES} bytes`
|
|
53998
|
+
}).describe("Plain-text email body (max 50KiB)"),
|
|
53999
|
+
attachments: array(ActionEmailAttachmentSchema).max(ACTION_EMAIL_MAX_ATTACHMENTS, `At most ${ACTION_EMAIL_MAX_ATTACHMENTS} attachments`).optional().describe("Optional same-run attachments as { fileId, filename? } or a bare fileId string (12MiB combined)")
|
|
54000
|
+
}).superRefine((config, ctx) => {
|
|
54001
|
+
if (actionEmailRecipientCountExceedsLimit(config)) {
|
|
54002
|
+
ctx.addIssue({
|
|
54003
|
+
code: "custom",
|
|
54004
|
+
message: ACTION_EMAIL_RECIPIENT_LIMIT_MESSAGE,
|
|
54005
|
+
path: ["to"]
|
|
54006
|
+
});
|
|
54007
|
+
}
|
|
54008
|
+
});
|
|
54009
|
+
ActionEmailOutputSchema = object({
|
|
54010
|
+
serverId: EmailServerIdSchema.describe("Email server that sent (or would have sent) the message"),
|
|
54011
|
+
messageId: string2().nullable().describe("Provider message id. Null when delivery was skipped (evaluation runs)."),
|
|
54012
|
+
provider: _enum(["resend", "smtp"]).nullable().describe("Email provider that sent the message. Null when delivery was skipped."),
|
|
54013
|
+
to: array(string2()).describe("Normalized To recipients"),
|
|
54014
|
+
cc: array(string2()).describe("Normalized Cc recipients"),
|
|
54015
|
+
bcc: array(string2()).describe("Normalized Bcc recipients"),
|
|
54016
|
+
attachmentCount: number2().int().nonnegative().describe("Number of attachments sent"),
|
|
54017
|
+
totalBytes: number2().int().nonnegative().describe("Total attachment size in bytes")
|
|
54018
|
+
});
|
|
53664
54019
|
ControlIfConfigSchema = object({
|
|
53665
54020
|
condition: string2().min(1, "Condition is required").describe("LiquidJS expression that evaluates to boolean")
|
|
53666
54021
|
});
|
|
@@ -53914,6 +54269,15 @@ var init_step_configs = __esm(() => {
|
|
|
53914
54269
|
outputSchema: ActionWebsiteReaderOutputSchema,
|
|
53915
54270
|
configInWith: true
|
|
53916
54271
|
},
|
|
54272
|
+
"action.email": {
|
|
54273
|
+
type: "action.email",
|
|
54274
|
+
category: "action",
|
|
54275
|
+
name: "Send Email",
|
|
54276
|
+
description: "Send an email with optional attachments via a selected email server. At most 10 recipients combined across to, cc, and bcc.",
|
|
54277
|
+
configSchema: ActionEmailConfigSchema,
|
|
54278
|
+
outputSchema: ActionEmailOutputSchema,
|
|
54279
|
+
configInWith: true
|
|
54280
|
+
},
|
|
53917
54281
|
"control.if": {
|
|
53918
54282
|
type: "control.if",
|
|
53919
54283
|
category: "control",
|
|
@@ -54455,7 +54819,7 @@ var init_evaluator_config = __esm(() => {
|
|
|
54455
54819
|
LabelsRecord = record(string2().min(1), ScoreInUnitInterval);
|
|
54456
54820
|
LlmJudgeConfigSchema = object({
|
|
54457
54821
|
model: string2().min(1).optional().describe("Which LLM grades the output. Falls back to the workspace's default LLM provider when unset."),
|
|
54458
|
-
reasoningEffort: ReasoningEffortSchema.optional().describe("Reasoning effort for models that support it. Omit to
|
|
54822
|
+
reasoningEffort: ReasoningEffortSchema.optional().describe("Reasoning effort for models that support it. Omit to use the selected model's default."),
|
|
54459
54823
|
mode: JudgeModeSchema.default("continuous").describe("Continuous = the LLM returns a free-form score in [0, 1]. Discrete = the LLM picks one of your labels and the score is looked up from the table."),
|
|
54460
54824
|
labels: LabelsRecord.optional().describe("Allowed labels and the score each maps to. Required in discrete mode. The judge MUST return one of these labels; each score must be in [0, 1]."),
|
|
54461
54825
|
passThreshold: ScoreInUnitInterval.optional().describe(LEGACY_EVALUATOR_THRESHOLD_DESCRIPTION),
|
|
@@ -55423,6 +55787,7 @@ var init_src = __esm(() => {
|
|
|
55423
55787
|
init_eval();
|
|
55424
55788
|
init_git_source();
|
|
55425
55789
|
init_triggers();
|
|
55790
|
+
init_email_servers();
|
|
55426
55791
|
init_webhooks();
|
|
55427
55792
|
init_typed_script();
|
|
55428
55793
|
});
|
|
@@ -205368,7 +205733,7 @@ import { fileURLToPath as fileURLToPath8 } from "url";
|
|
|
205368
205733
|
// package.json
|
|
205369
205734
|
var package_default = {
|
|
205370
205735
|
name: "@eigenpal/cli",
|
|
205371
|
-
version: "0.
|
|
205736
|
+
version: "0.16.1",
|
|
205372
205737
|
description: "Eigenpal CLI — author and run document workflows from your terminal. Agent-ready.",
|
|
205373
205738
|
keywords: [
|
|
205374
205739
|
"eigenpal",
|
|
@@ -205425,7 +205790,7 @@ var package_default = {
|
|
|
205425
205790
|
"@clack/prompts": "^1.3.0",
|
|
205426
205791
|
ajv: "^8.17.1",
|
|
205427
205792
|
commander: "^14.0.3",
|
|
205428
|
-
fflate: "0.8.
|
|
205793
|
+
fflate: "0.8.3",
|
|
205429
205794
|
picocolors: "^1.1.1",
|
|
205430
205795
|
yaml: "^2.7.0",
|
|
205431
205796
|
xlsx: "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
|
|
@@ -208137,9 +208502,11 @@ function registerGitCommands(program) {
|
|
|
208137
208502
|
// ../../node_modules/fflate/esm/index.mjs
|
|
208138
208503
|
import { createRequire as createRequire2 } from "module";
|
|
208139
208504
|
var require2 = createRequire2("/");
|
|
208505
|
+
var _a3;
|
|
208140
208506
|
var Worker;
|
|
208507
|
+
var isMarkedAsUntransferable;
|
|
208141
208508
|
try {
|
|
208142
|
-
|
|
208509
|
+
_a3 = require2("worker_threads"), Worker = _a3.Worker, isMarkedAsUntransferable = _a3.isMarkedAsUntransferable;
|
|
208143
208510
|
} catch (e) {}
|
|
208144
208511
|
var u8 = Uint8Array;
|
|
208145
208512
|
var u16 = Uint16Array;
|
|
@@ -208625,7 +208992,7 @@ var fltn = function(d, p, t, o) {
|
|
|
208625
208992
|
var val2 = d[k], n = p + k, op = o;
|
|
208626
208993
|
if (Array.isArray(val2))
|
|
208627
208994
|
op = mrg(o, val2[1]), val2 = val2[0];
|
|
208628
|
-
if (val2
|
|
208995
|
+
if (ArrayBuffer.isView(val2))
|
|
208629
208996
|
t[n] = [val2, op];
|
|
208630
208997
|
else {
|
|
208631
208998
|
t[n += "/"] = [new u8(0), op];
|
|
@@ -240643,18 +241010,471 @@ function matchingSnippet(content, terms) {
|
|
|
240643
241010
|
return line.replace(/^[#>*\s-]+/, "").replace(/[`[\]{}]/g, "").trim().slice(0, 140);
|
|
240644
241011
|
}
|
|
240645
241012
|
|
|
241013
|
+
// src/lib/api-paths.ts
|
|
241014
|
+
var API_PREFIX = "/v1";
|
|
241015
|
+
function apiPath(suffix) {
|
|
241016
|
+
if (suffix === "/v1" || suffix.startsWith("/v1/"))
|
|
241017
|
+
return suffix;
|
|
241018
|
+
if (suffix === "/api/v1" || suffix.startsWith("/api/v1/")) {
|
|
241019
|
+
return `${API_PREFIX}${suffix.slice("/api/v1".length)}`;
|
|
241020
|
+
}
|
|
241021
|
+
const normalized = suffix.startsWith("/") ? suffix : `/${suffix}`;
|
|
241022
|
+
return `${API_PREFIX}${normalized}`;
|
|
241023
|
+
}
|
|
241024
|
+
|
|
241025
|
+
// src/lib/email-servers-cli.ts
|
|
241026
|
+
init_src();
|
|
241027
|
+
import { existsSync as existsSync14, readFileSync as readFileSync14 } from "node:fs";
|
|
241028
|
+
import { resolve as resolve4 } from "node:path";
|
|
241029
|
+
var SECRET_KEYS = new Set(["apiKey", "password", "caPem", "ciphertext"]);
|
|
241030
|
+
var SMTP_UPDATE_TARGET_FIELDS = ["host", "port", "security", "fromEmail", "fromName"];
|
|
241031
|
+
var SMTP_UPDATE_FLAG_BY_FIELD = {
|
|
241032
|
+
host: "--host",
|
|
241033
|
+
port: "--port",
|
|
241034
|
+
security: "--security",
|
|
241035
|
+
fromEmail: "--from-email",
|
|
241036
|
+
fromName: "--from-name"
|
|
241037
|
+
};
|
|
241038
|
+
function assertCompleteSmtpUpdateTarget(body) {
|
|
241039
|
+
if (body.transport !== "smtp")
|
|
241040
|
+
return;
|
|
241041
|
+
const missing = SMTP_UPDATE_TARGET_FIELDS.filter((field) => body[field] === undefined || body[field] === "");
|
|
241042
|
+
if (missing.length === 0)
|
|
241043
|
+
return;
|
|
241044
|
+
const flags = missing.map((field) => SMTP_UPDATE_FLAG_BY_FIELD[field]).join(", ");
|
|
241045
|
+
throw new Error(`SMTP updates that set --transport smtp require a complete target (host, port, security, from-email, from-name). Missing: ${flags}. Update does not default --security/--port (create still defaults to starttls and the matching port). Metadata-only updates omit --transport.`);
|
|
241046
|
+
}
|
|
241047
|
+
function countTruthy(values) {
|
|
241048
|
+
return values.filter(Boolean).length;
|
|
241049
|
+
}
|
|
241050
|
+
function assertExclusiveConfigSource(explicitFieldCount, opts, command) {
|
|
241051
|
+
const configSources = countTruthy([opts.configJson, opts.configFile]);
|
|
241052
|
+
if (configSources > 1) {
|
|
241053
|
+
throw new Error("Pass only one of --config-json or --config-file.");
|
|
241054
|
+
}
|
|
241055
|
+
if (configSources > 0 && explicitFieldCount > 0) {
|
|
241056
|
+
throw new Error(`${command} accepts either explicit flags or --config-json/--config-file, not both.`);
|
|
241057
|
+
}
|
|
241058
|
+
if (configSources === 0 && explicitFieldCount === 0 && command === "create") {
|
|
241059
|
+
throw new Error("create requires explicit fields or --config-json/--config-file (plus secret input for Resend or authenticated SMTP).");
|
|
241060
|
+
}
|
|
241061
|
+
}
|
|
241062
|
+
function readConfigObject(opts) {
|
|
241063
|
+
if (opts.configJson) {
|
|
241064
|
+
let parsed;
|
|
241065
|
+
try {
|
|
241066
|
+
parsed = JSON.parse(opts.configJson);
|
|
241067
|
+
} catch {
|
|
241068
|
+
throw new Error("--config-json must be valid JSON.");
|
|
241069
|
+
}
|
|
241070
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
241071
|
+
throw new Error("--config-json must be a JSON object.");
|
|
241072
|
+
}
|
|
241073
|
+
return parsed;
|
|
241074
|
+
}
|
|
241075
|
+
if (opts.configFile) {
|
|
241076
|
+
const filePath = opts.configFile === "-" ? undefined : resolve4(opts.configFile);
|
|
241077
|
+
let raw;
|
|
241078
|
+
try {
|
|
241079
|
+
raw = opts.configFile === "-" ? readFileSync14(0, "utf8") : readFileSync14(filePath, "utf8");
|
|
241080
|
+
} catch (err) {
|
|
241081
|
+
const code = err && typeof err === "object" && "code" in err ? String(err.code) : "";
|
|
241082
|
+
if (code === "ENOENT") {
|
|
241083
|
+
throw new Error(`Config file not found: ${resolve4(opts.configFile)}`);
|
|
241084
|
+
}
|
|
241085
|
+
throw err;
|
|
241086
|
+
}
|
|
241087
|
+
let parsed;
|
|
241088
|
+
try {
|
|
241089
|
+
parsed = JSON.parse(raw);
|
|
241090
|
+
} catch {
|
|
241091
|
+
throw new Error("--config-file must contain a JSON object.");
|
|
241092
|
+
}
|
|
241093
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
241094
|
+
throw new Error("--config-file must contain a JSON object.");
|
|
241095
|
+
}
|
|
241096
|
+
return parsed;
|
|
241097
|
+
}
|
|
241098
|
+
return {};
|
|
241099
|
+
}
|
|
241100
|
+
function rejectInlineSecrets(body) {
|
|
241101
|
+
for (const key of SECRET_KEYS) {
|
|
241102
|
+
if (key in body && body[key] != null) {
|
|
241103
|
+
throw new Error(`Secret field "${key}" cannot be set in --config-json/--config-file. Use the matching *-stdin or *-file flag, or answer the secure prompt.`);
|
|
241104
|
+
}
|
|
241105
|
+
}
|
|
241106
|
+
}
|
|
241107
|
+
async function readSecretInput2(label, opts, required) {
|
|
241108
|
+
const selected = countTruthy([opts.stdin, opts.file]);
|
|
241109
|
+
if (selected > 1) {
|
|
241110
|
+
throw new Error(`Pass only one of --${label}-stdin or --${label}-file.`);
|
|
241111
|
+
}
|
|
241112
|
+
if (opts.stdin) {
|
|
241113
|
+
return readFileSync14(0, "utf8").replace(/\n$/, "");
|
|
241114
|
+
}
|
|
241115
|
+
if (opts.file) {
|
|
241116
|
+
const filePath = opts.file === "-" ? undefined : resolve4(opts.file);
|
|
241117
|
+
try {
|
|
241118
|
+
return (opts.file === "-" ? readFileSync14(0, "utf8") : readFileSync14(filePath, "utf8")).replace(/\n$/, "");
|
|
241119
|
+
} catch (err) {
|
|
241120
|
+
const code = err && typeof err === "object" && "code" in err ? String(err.code) : "";
|
|
241121
|
+
if (code === "ENOENT") {
|
|
241122
|
+
throw new Error(`Secret file not found: ${resolve4(opts.file)}`);
|
|
241123
|
+
}
|
|
241124
|
+
throw err;
|
|
241125
|
+
}
|
|
241126
|
+
}
|
|
241127
|
+
if (!required)
|
|
241128
|
+
return;
|
|
241129
|
+
if (process.stdin.isTTY && process.stdout.isTTY) {
|
|
241130
|
+
await Promise.resolve().then(() => init_dist4());
|
|
241131
|
+
const answer = await Ce({ message: `${label} (input hidden)` });
|
|
241132
|
+
if (q(answer)) {
|
|
241133
|
+
me("Cancelled");
|
|
241134
|
+
process.exit(1);
|
|
241135
|
+
}
|
|
241136
|
+
return String(answer);
|
|
241137
|
+
}
|
|
241138
|
+
throw new Error(`${label} is required in noninteractive mode (use --${label}-stdin or --${label}-file).`);
|
|
241139
|
+
}
|
|
241140
|
+
function parseEnabled(opts) {
|
|
241141
|
+
if (opts.enabled && opts.disabled) {
|
|
241142
|
+
throw new Error("Pass only one of --enabled or --disabled.");
|
|
241143
|
+
}
|
|
241144
|
+
if (opts.disabled)
|
|
241145
|
+
return false;
|
|
241146
|
+
if (opts.enabled)
|
|
241147
|
+
return true;
|
|
241148
|
+
return;
|
|
241149
|
+
}
|
|
241150
|
+
async function buildCreateRequest(opts) {
|
|
241151
|
+
const explicitCount = countTruthy([
|
|
241152
|
+
opts.name,
|
|
241153
|
+
opts.transport,
|
|
241154
|
+
opts.fromEmail,
|
|
241155
|
+
opts.fromName,
|
|
241156
|
+
opts.enabled,
|
|
241157
|
+
opts.disabled,
|
|
241158
|
+
opts.host,
|
|
241159
|
+
opts.port,
|
|
241160
|
+
opts.security,
|
|
241161
|
+
opts.username
|
|
241162
|
+
]);
|
|
241163
|
+
assertExclusiveConfigSource(explicitCount, opts, "create");
|
|
241164
|
+
const body = {};
|
|
241165
|
+
if (countTruthy([opts.configJson, opts.configFile]) > 0) {
|
|
241166
|
+
Object.assign(body, readConfigObject(opts));
|
|
241167
|
+
rejectInlineSecrets(body);
|
|
241168
|
+
}
|
|
241169
|
+
if (opts.name !== undefined)
|
|
241170
|
+
body.name = opts.name;
|
|
241171
|
+
if (opts.transport !== undefined)
|
|
241172
|
+
body.transport = opts.transport;
|
|
241173
|
+
if (opts.fromEmail !== undefined)
|
|
241174
|
+
body.fromEmail = opts.fromEmail;
|
|
241175
|
+
if (opts.fromName !== undefined)
|
|
241176
|
+
body.fromName = opts.fromName;
|
|
241177
|
+
const enabled = parseEnabled(opts);
|
|
241178
|
+
if (enabled !== undefined)
|
|
241179
|
+
body.enabled = enabled;
|
|
241180
|
+
if (opts.host !== undefined)
|
|
241181
|
+
body.host = opts.host;
|
|
241182
|
+
if (opts.port !== undefined)
|
|
241183
|
+
body.port = opts.port;
|
|
241184
|
+
if (opts.security !== undefined)
|
|
241185
|
+
body.security = opts.security;
|
|
241186
|
+
if (opts.username !== undefined)
|
|
241187
|
+
body.username = opts.username;
|
|
241188
|
+
const apiKey = await readSecretInput2("api-key", { stdin: opts.apiKeyStdin, file: opts.apiKeyFile }, false);
|
|
241189
|
+
if (apiKey !== undefined)
|
|
241190
|
+
body.apiKey = apiKey;
|
|
241191
|
+
const password = await readSecretInput2("password", { stdin: opts.passwordStdin, file: opts.passwordFile }, false);
|
|
241192
|
+
if (password !== undefined)
|
|
241193
|
+
body.password = password;
|
|
241194
|
+
const caPem = await readSecretInput2("ca-pem", { stdin: opts.caPemStdin, file: opts.caPemFile }, false);
|
|
241195
|
+
if (caPem !== undefined)
|
|
241196
|
+
body.caPem = caPem;
|
|
241197
|
+
const transport = body.transport;
|
|
241198
|
+
if (transport === "resend" && body.apiKey === undefined) {
|
|
241199
|
+
body.apiKey = await readSecretInput2("api-key", { stdin: opts.apiKeyStdin, file: opts.apiKeyFile }, true);
|
|
241200
|
+
}
|
|
241201
|
+
if (body.transport === "smtp" && typeof body.username === "string" && body.username.length > 0 && body.password === undefined) {
|
|
241202
|
+
body.password = await readSecretInput2("password", { stdin: opts.passwordStdin, file: opts.passwordFile }, true);
|
|
241203
|
+
}
|
|
241204
|
+
return CreateEmailServerRequestSchema.parse(body);
|
|
241205
|
+
}
|
|
241206
|
+
async function buildUpdateRequest(input) {
|
|
241207
|
+
const { existing, opts } = input;
|
|
241208
|
+
const explicitCount = countTruthy([
|
|
241209
|
+
opts.name,
|
|
241210
|
+
opts.transport,
|
|
241211
|
+
opts.fromEmail,
|
|
241212
|
+
opts.fromName,
|
|
241213
|
+
opts.enabled,
|
|
241214
|
+
opts.disabled,
|
|
241215
|
+
opts.host,
|
|
241216
|
+
opts.port,
|
|
241217
|
+
opts.security,
|
|
241218
|
+
opts.username,
|
|
241219
|
+
opts.clearCaPem,
|
|
241220
|
+
opts.clearUsername
|
|
241221
|
+
]);
|
|
241222
|
+
assertExclusiveConfigSource(explicitCount, opts, "update");
|
|
241223
|
+
const body = {};
|
|
241224
|
+
if (countTruthy([opts.configJson, opts.configFile]) > 0) {
|
|
241225
|
+
Object.assign(body, readConfigObject(opts));
|
|
241226
|
+
rejectInlineSecrets(body);
|
|
241227
|
+
}
|
|
241228
|
+
if (opts.name !== undefined)
|
|
241229
|
+
body.name = opts.name;
|
|
241230
|
+
const enabled = parseEnabled(opts);
|
|
241231
|
+
if (enabled !== undefined)
|
|
241232
|
+
body.enabled = enabled;
|
|
241233
|
+
if (opts.transport !== undefined)
|
|
241234
|
+
body.transport = opts.transport;
|
|
241235
|
+
if (opts.fromEmail !== undefined)
|
|
241236
|
+
body.fromEmail = opts.fromEmail;
|
|
241237
|
+
if (opts.fromName !== undefined)
|
|
241238
|
+
body.fromName = opts.fromName;
|
|
241239
|
+
if (opts.host !== undefined)
|
|
241240
|
+
body.host = opts.host;
|
|
241241
|
+
if (opts.port !== undefined)
|
|
241242
|
+
body.port = opts.port;
|
|
241243
|
+
if (opts.security !== undefined)
|
|
241244
|
+
body.security = opts.security;
|
|
241245
|
+
if (opts.clearUsername)
|
|
241246
|
+
body.username = null;
|
|
241247
|
+
else if (opts.username !== undefined)
|
|
241248
|
+
body.username = opts.username;
|
|
241249
|
+
if (opts.clearCaPem)
|
|
241250
|
+
body.caPem = null;
|
|
241251
|
+
const apiKey = await readSecretInput2("api-key", { stdin: opts.apiKeyStdin, file: opts.apiKeyFile }, false);
|
|
241252
|
+
if (apiKey !== undefined)
|
|
241253
|
+
body.apiKey = apiKey;
|
|
241254
|
+
const password = await readSecretInput2("password", { stdin: opts.passwordStdin, file: opts.passwordFile }, false);
|
|
241255
|
+
if (password !== undefined)
|
|
241256
|
+
body.password = password;
|
|
241257
|
+
const caPem = await readSecretInput2("ca-pem", { stdin: opts.caPemStdin, file: opts.caPemFile }, false);
|
|
241258
|
+
if (caPem !== undefined)
|
|
241259
|
+
body.caPem = caPem;
|
|
241260
|
+
if (Object.keys(body).length === 0) {
|
|
241261
|
+
throw new Error("No changes requested. Pass fields to update or --config-json/--config-file.");
|
|
241262
|
+
}
|
|
241263
|
+
assertCompleteSmtpUpdateTarget(body);
|
|
241264
|
+
if (body.transport === "resend" && existing.transport !== "resend" && body.apiKey === undefined) {
|
|
241265
|
+
body.apiKey = await readSecretInput2("api-key", { stdin: opts.apiKeyStdin, file: opts.apiKeyFile }, true);
|
|
241266
|
+
}
|
|
241267
|
+
if (body.transport === "smtp" && body.password === undefined) {
|
|
241268
|
+
const targetUsername = body.username === null ? null : typeof body.username === "string" ? body.username : existing.username ?? null;
|
|
241269
|
+
const destinationChanged = existing.transport !== "smtp" || typeof body.host === "string" && existing.host !== undefined && body.host !== existing.host || targetUsername !== (existing.username ?? null);
|
|
241270
|
+
if (destinationChanged && targetUsername) {
|
|
241271
|
+
body.password = await readSecretInput2("password", { stdin: opts.passwordStdin, file: opts.passwordFile }, true);
|
|
241272
|
+
}
|
|
241273
|
+
}
|
|
241274
|
+
const patch = UpdateEmailServerRequestSchema.parse(body);
|
|
241275
|
+
const transportError = getEmailServerUpdateError(existing.transport, patch, {
|
|
241276
|
+
host: existing.host,
|
|
241277
|
+
username: existing.username,
|
|
241278
|
+
passwordConfigured: existing.passwordConfigured
|
|
241279
|
+
});
|
|
241280
|
+
if (transportError)
|
|
241281
|
+
throw new Error(transportError);
|
|
241282
|
+
return patch;
|
|
241283
|
+
}
|
|
241284
|
+
function redactValue(key, value) {
|
|
241285
|
+
if (SECRET_KEYS.has(key))
|
|
241286
|
+
return "[redacted]";
|
|
241287
|
+
if (value && typeof value === "object") {
|
|
241288
|
+
if (Array.isArray(value))
|
|
241289
|
+
return value.map((item) => redactUnknown(item));
|
|
241290
|
+
return redactUnknown(value);
|
|
241291
|
+
}
|
|
241292
|
+
return value;
|
|
241293
|
+
}
|
|
241294
|
+
function redactUnknown(value) {
|
|
241295
|
+
if (value == null || typeof value !== "object")
|
|
241296
|
+
return value;
|
|
241297
|
+
if (Array.isArray(value))
|
|
241298
|
+
return value.map((item) => redactUnknown(item));
|
|
241299
|
+
const out = {};
|
|
241300
|
+
for (const [key, nested] of Object.entries(value)) {
|
|
241301
|
+
out[key] = redactValue(key, nested);
|
|
241302
|
+
}
|
|
241303
|
+
return out;
|
|
241304
|
+
}
|
|
241305
|
+
function redactEmailServerPayload(value) {
|
|
241306
|
+
return redactUnknown(value);
|
|
241307
|
+
}
|
|
241308
|
+
function formatEmailServerHuman(server) {
|
|
241309
|
+
const lines = [];
|
|
241310
|
+
lines.push(`${server.id} ${server.name}${server.enabled ? "" : " (disabled)"}`);
|
|
241311
|
+
lines.push(` transport ${server.transport}`);
|
|
241312
|
+
lines.push(` from ${server.fromName} <${server.fromEmail}>`);
|
|
241313
|
+
if (server.transport === "resend") {
|
|
241314
|
+
lines.push(` api key configured`);
|
|
241315
|
+
} else {
|
|
241316
|
+
lines.push(` host ${server.host}:${server.port} (${server.security})`);
|
|
241317
|
+
lines.push(` username ${server.username ?? "-"}`);
|
|
241318
|
+
lines.push(` password ${server.passwordConfigured ? "configured" : "not configured"}`);
|
|
241319
|
+
lines.push(` ca pem ${server.caPemConfigured ? "configured" : "not configured"}`);
|
|
241320
|
+
}
|
|
241321
|
+
lines.push(` updated ${server.updatedAt instanceof Date ? server.updatedAt.toISOString() : server.updatedAt}`);
|
|
241322
|
+
return lines.join(`
|
|
241323
|
+
`);
|
|
241324
|
+
}
|
|
241325
|
+
|
|
241326
|
+
// src/commands/email-servers.ts
|
|
241327
|
+
var LIST_COLUMNS = [
|
|
241328
|
+
{ key: "id", header: "id" },
|
|
241329
|
+
{ key: "name", header: "name" },
|
|
241330
|
+
{ key: "transport", header: "transport" },
|
|
241331
|
+
{
|
|
241332
|
+
key: "enabled",
|
|
241333
|
+
header: "enabled",
|
|
241334
|
+
format: (value) => value ? "yes" : "no"
|
|
241335
|
+
},
|
|
241336
|
+
{ key: "fromEmail", header: "from" },
|
|
241337
|
+
{
|
|
241338
|
+
key: "host",
|
|
241339
|
+
header: "host",
|
|
241340
|
+
format: (_value, row) => row.transport === "smtp" ? String(row.host) : "-"
|
|
241341
|
+
},
|
|
241342
|
+
{
|
|
241343
|
+
key: "updatedAt",
|
|
241344
|
+
header: "updated",
|
|
241345
|
+
format: (value) => formatTimestamp(value)
|
|
241346
|
+
}
|
|
241347
|
+
];
|
|
241348
|
+
function buildClient2(opts) {
|
|
241349
|
+
const config = resolveConfig(opts);
|
|
241350
|
+
requireApiKey(config);
|
|
241351
|
+
return new ApiClient(config);
|
|
241352
|
+
}
|
|
241353
|
+
function printJson2(value) {
|
|
241354
|
+
console.log(JSON.stringify(value, null, 2));
|
|
241355
|
+
}
|
|
241356
|
+
function sharedCreateOptions(cmd) {
|
|
241357
|
+
return cmd.option("--config-json <json>", "JSON object (non-secret fields only; use secret *-stdin/*-file flags)").option("--config-file <path>", "JSON file path (`-` reads stdin; non-secret fields only)").option("--name <name>", "Display name").option("--transport <kind>", "Transport: resend or smtp").option("--from-email <email>", "From address").option("--from-name <name>", "From display name (no control characters or <>)").option("--enabled", "Enable the server (default on create)").option("--disabled", "Disable the server").option("--host <host>", "SMTP host (required on update when --transport smtp)").option("--port <n>", "SMTP port. Required on update when --transport smtp; create defaults from --security", intArg).option("--security <mode>", "SMTP security: starttls, tls, or none (unauthenticated trusted relays; credentials are rejected). Required on update when --transport smtp; create defaults to starttls").option("--username <user>", "SMTP username (non-secret)").option("--api-key-stdin", "Read the Resend API key from stdin").option("--api-key-file <path>", "Read the Resend API key from a file (`-` for stdin)").option("--password-stdin", "Read the SMTP password from stdin").option("--password-file <path>", "Read the SMTP password from a file (`-` for stdin)").option("--ca-pem-stdin", "Read a custom SMTP CA PEM from stdin").option("--ca-pem-file <path>", "Read a custom SMTP CA PEM from a file (`-` for stdin)");
|
|
241358
|
+
}
|
|
241359
|
+
function sharedUpdateOptions(cmd) {
|
|
241360
|
+
return sharedCreateOptions(cmd).option("--clear-ca-pem", "Remove a stored custom SMTP CA certificate").option("--clear-username", "Clear stored SMTP username/password pair");
|
|
241361
|
+
}
|
|
241362
|
+
var EMAIL_SERVERS_EXAMPLES = `
|
|
241363
|
+
Examples:
|
|
241364
|
+
$ eigenpal email-servers list --json
|
|
241365
|
+
$ eigenpal email-servers get ems_... --json
|
|
241366
|
+
$ eigenpal email-servers create --transport resend --name Alerts \\
|
|
241367
|
+
--from-email alerts@example.com --from-name Alerts --api-key-stdin
|
|
241368
|
+
$ eigenpal email-servers create --transport smtp --name "Corp SMTP" --host smtp.example.com \\
|
|
241369
|
+
--from-email noreply@example.com --from-name Eigenpal
|
|
241370
|
+
$ eigenpal email-servers create --config-file ./resend.json --api-key-file ./re.key
|
|
241371
|
+
$ eigenpal email-servers update ems_... --name "Ops alerts"
|
|
241372
|
+
$ eigenpal email-servers update ems_... --transport smtp --host smtp.example.com \\
|
|
241373
|
+
--port 587 --security starttls --from-email noreply@example.com \\
|
|
241374
|
+
--from-name Eigenpal --password-stdin
|
|
241375
|
+
$ eigenpal email-servers delete ems_... --yes
|
|
241376
|
+
$ eigenpal email-servers test ems_... --to you@example.com
|
|
241377
|
+
|
|
241378
|
+
Secrets never belong on the command line. Provide Resend API keys, SMTP passwords,
|
|
241379
|
+
and CA PEM material via --*-stdin, --*-file, or the secure TTY prompt.
|
|
241380
|
+
`;
|
|
241381
|
+
function registerEmailServersCommands(program) {
|
|
241382
|
+
const emailServers = program.command("email-servers").alias("email-server").description("Manage outbound email servers (ems_…): list, inspect, create, update, delete, and send a real test message.").addHelpText("after", EMAIL_SERVERS_EXAMPLES);
|
|
241383
|
+
const listCmd = emailServers.command("list").description("List outbound email servers for the current workspace.");
|
|
241384
|
+
addJsonFlag(withBaseUrl(withPagination(listCmd))).action(action(async (opts) => {
|
|
241385
|
+
const client = buildClient2(opts);
|
|
241386
|
+
const raw = await client.get(apiPath("/email-servers"), {
|
|
241387
|
+
limit: String(opts.limit),
|
|
241388
|
+
offset: String(opts.offset)
|
|
241389
|
+
});
|
|
241390
|
+
renderListResult(raw, LIST_COLUMNS, {
|
|
241391
|
+
json: opts.json,
|
|
241392
|
+
entityLabel: "email server"
|
|
241393
|
+
});
|
|
241394
|
+
}));
|
|
241395
|
+
const getCmd = emailServers.command("get <id>").description("Inspect one email server. Human output is redacted even if the API regresses.");
|
|
241396
|
+
addJsonFlag(withBaseUrl(getCmd)).action(action(async (id, opts) => {
|
|
241397
|
+
const client = buildClient2(opts);
|
|
241398
|
+
const raw = await client.get(apiPath(`/email-servers/${encodeURIComponent(id)}`));
|
|
241399
|
+
const redacted = redactEmailServerPayload(raw);
|
|
241400
|
+
if (opts.json) {
|
|
241401
|
+
printJson2(redacted);
|
|
241402
|
+
return;
|
|
241403
|
+
}
|
|
241404
|
+
console.log(formatEmailServerHuman(redacted));
|
|
241405
|
+
}));
|
|
241406
|
+
const createCmd = emailServers.command("create").description("Create an outbound email server. Resend requires an API key; SMTP accepts optional username/password except with --security none, plus optional CA PEM, and defaults to starttls on port 587.");
|
|
241407
|
+
addJsonFlag(withBaseUrl(sharedCreateOptions(createCmd))).action(action(async (opts) => {
|
|
241408
|
+
const body = await buildCreateRequest(opts);
|
|
241409
|
+
const client = buildClient2(opts);
|
|
241410
|
+
const created = await client.post(apiPath("/email-servers"), body);
|
|
241411
|
+
const redacted = redactEmailServerPayload(created);
|
|
241412
|
+
if (opts.json) {
|
|
241413
|
+
printJson2(redacted);
|
|
241414
|
+
return;
|
|
241415
|
+
}
|
|
241416
|
+
success(`Created ${ui.bold(redacted.id)} (${redacted.transport})`);
|
|
241417
|
+
console.log(formatEmailServerHuman(redacted));
|
|
241418
|
+
}));
|
|
241419
|
+
const updateCmd = emailServers.command("update <id>").description("Update metadata or replace transport configuration. Omitted secrets are retained. Passing --transport smtp requires --host, --port, --security, --from-email, and --from-name (no security/port defaults). Metadata-only updates omit --transport.");
|
|
241420
|
+
addJsonFlag(withBaseUrl(sharedUpdateOptions(updateCmd))).action(action(async (id, opts) => {
|
|
241421
|
+
const client = buildClient2(opts);
|
|
241422
|
+
const existing = await client.get(apiPath(`/email-servers/${encodeURIComponent(id)}`));
|
|
241423
|
+
const body = await buildUpdateRequest({ existing, opts });
|
|
241424
|
+
const updated = await client.patch(apiPath(`/email-servers/${encodeURIComponent(id)}`), body);
|
|
241425
|
+
const redacted = redactEmailServerPayload(updated);
|
|
241426
|
+
if (opts.json) {
|
|
241427
|
+
printJson2(redacted);
|
|
241428
|
+
return;
|
|
241429
|
+
}
|
|
241430
|
+
success(`Updated ${ui.bold(redacted.id)}`);
|
|
241431
|
+
console.log(formatEmailServerHuman(redacted));
|
|
241432
|
+
}));
|
|
241433
|
+
const deleteCmd = emailServers.command("delete <id>").description("Soft-delete an outbound email server.").option("--yes", "Required for non-TTY shells", false);
|
|
241434
|
+
addJsonFlag(withBaseUrl(deleteCmd)).action(action(async (id, opts) => {
|
|
241435
|
+
if (!opts.yes && !process.stdout.isTTY) {
|
|
241436
|
+
throw new Error("email-servers delete is destructive and requires --yes when run non-interactively");
|
|
241437
|
+
}
|
|
241438
|
+
const client = buildClient2(opts);
|
|
241439
|
+
const result = await client.delete(apiPath(`/email-servers/${encodeURIComponent(id)}`));
|
|
241440
|
+
if (opts.json) {
|
|
241441
|
+
printJson2(result);
|
|
241442
|
+
return;
|
|
241443
|
+
}
|
|
241444
|
+
success(`Deleted ${ui.bold(id)}`);
|
|
241445
|
+
}));
|
|
241446
|
+
const testCmd = emailServers.command("test <id>").description("Send a real connectivity test email through the stored server to --to. Disabled servers fail with a conflict.").requiredOption("--to <email>", "Recipient for the live test message");
|
|
241447
|
+
addJsonFlag(withBaseUrl(testCmd)).action(action(async (id, opts) => {
|
|
241448
|
+
const client = buildClient2(opts);
|
|
241449
|
+
const result = await client.post(apiPath(`/email-servers/${encodeURIComponent(id)}/test`), {
|
|
241450
|
+
to: opts.to
|
|
241451
|
+
});
|
|
241452
|
+
if (opts.json) {
|
|
241453
|
+
printJson2(result);
|
|
241454
|
+
if (!result.ok)
|
|
241455
|
+
process.exit(1);
|
|
241456
|
+
return;
|
|
241457
|
+
}
|
|
241458
|
+
if (result.ok) {
|
|
241459
|
+
success(`Test email sent via ${ui.bold(result.transport)} (${ui.dim(result.messageId)})`);
|
|
241460
|
+
return;
|
|
241461
|
+
}
|
|
241462
|
+
throw new Error(result.error);
|
|
241463
|
+
}));
|
|
241464
|
+
}
|
|
241465
|
+
|
|
240646
241466
|
// src/commands/init/index.ts
|
|
240647
241467
|
init_dist4();
|
|
240648
241468
|
import {
|
|
240649
241469
|
copyFileSync,
|
|
240650
|
-
existsSync as
|
|
241470
|
+
existsSync as existsSync15,
|
|
240651
241471
|
mkdirSync as mkdirSync5,
|
|
240652
241472
|
readdirSync as readdirSync4,
|
|
240653
|
-
readFileSync as
|
|
241473
|
+
readFileSync as readFileSync15,
|
|
240654
241474
|
statSync as statSync4,
|
|
240655
241475
|
writeFileSync as writeFileSync7
|
|
240656
241476
|
} from "node:fs";
|
|
240657
|
-
import { dirname as dirname4, join as join7, relative as relative2, resolve as
|
|
241477
|
+
import { dirname as dirname4, join as join7, relative as relative2, resolve as resolve5 } from "node:path";
|
|
240658
241478
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
240659
241479
|
var TEMPLATE_NAMES = ["blank", "pdf-extraction", "text-classification"];
|
|
240660
241480
|
var TEMPLATE_DESCRIPTIONS = {
|
|
@@ -240667,11 +241487,11 @@ function isValidProjectName(name) {
|
|
|
240667
241487
|
}
|
|
240668
241488
|
function resolveTemplatesRoot() {
|
|
240669
241489
|
const here = dirname4(fileURLToPath6(import.meta.url));
|
|
240670
|
-
const srcCandidate =
|
|
240671
|
-
if (
|
|
241490
|
+
const srcCandidate = resolve5(here, "..", "..", "templates");
|
|
241491
|
+
if (existsSync15(srcCandidate))
|
|
240672
241492
|
return srcCandidate;
|
|
240673
|
-
const distCandidate =
|
|
240674
|
-
if (
|
|
241493
|
+
const distCandidate = resolve5(here, "templates");
|
|
241494
|
+
if (existsSync15(distCandidate))
|
|
240675
241495
|
return distCandidate;
|
|
240676
241496
|
throw new Error(`Cannot locate bundled templates. Looked in:
|
|
240677
241497
|
${srcCandidate}
|
|
@@ -240681,9 +241501,9 @@ async function init(name, opts) {
|
|
|
240681
241501
|
if (!isValidProjectName(name)) {
|
|
240682
241502
|
throw new Error(`Invalid project name "${name}". Use lowercase kebab/snake-case (e.g. parse-invoices), max 60 chars.`);
|
|
240683
241503
|
}
|
|
240684
|
-
const target =
|
|
241504
|
+
const target = resolve5(process.cwd(), opts.dir ?? name);
|
|
240685
241505
|
assertSafeTargetDir(target, opts.dir);
|
|
240686
|
-
if (
|
|
241506
|
+
if (existsSync15(target) && readdirSync4(target).length > 0) {
|
|
240687
241507
|
throw new Error(`Target directory ${relative2(process.cwd(), target)} exists and is not empty.`);
|
|
240688
241508
|
}
|
|
240689
241509
|
let template;
|
|
@@ -240698,7 +241518,7 @@ async function init(name, opts) {
|
|
|
240698
241518
|
template = await promptForTemplate();
|
|
240699
241519
|
}
|
|
240700
241520
|
const sourceRoot = join7(resolveTemplatesRoot(), template);
|
|
240701
|
-
if (!
|
|
241521
|
+
if (!existsSync15(sourceRoot)) {
|
|
240702
241522
|
throw new Error(`Template directory missing on disk: ${sourceRoot}`);
|
|
240703
241523
|
}
|
|
240704
241524
|
const written = copyTemplate(sourceRoot, target, name);
|
|
@@ -240751,7 +241571,7 @@ function copyTemplate(src, dst, projectName) {
|
|
|
240751
241571
|
}
|
|
240752
241572
|
mkdirSync5(dirname4(targetPath), { recursive: true });
|
|
240753
241573
|
if (isTextFile(sourcePath)) {
|
|
240754
|
-
const text =
|
|
241574
|
+
const text = readFileSync15(sourcePath, "utf-8").replaceAll(PLACEHOLDER, projectName);
|
|
240755
241575
|
writeFileSync7(targetPath, text);
|
|
240756
241576
|
} else {
|
|
240757
241577
|
copyFileSync(sourcePath, targetPath);
|
|
@@ -240878,20 +241698,6 @@ function multipartMaxBytesFromEnv(raw = env.EIGENPAL_MULTIPART_MAX_BYTES) {
|
|
|
240878
241698
|
|
|
240879
241699
|
// src/lib/upload-reusable-file.ts
|
|
240880
241700
|
import { randomUUID } from "node:crypto";
|
|
240881
|
-
|
|
240882
|
-
// src/lib/api-paths.ts
|
|
240883
|
-
var API_PREFIX = "/v1";
|
|
240884
|
-
function apiPath(suffix) {
|
|
240885
|
-
if (suffix === "/v1" || suffix.startsWith("/v1/"))
|
|
240886
|
-
return suffix;
|
|
240887
|
-
if (suffix === "/api/v1" || suffix.startsWith("/api/v1/")) {
|
|
240888
|
-
return `${API_PREFIX}${suffix.slice("/api/v1".length)}`;
|
|
240889
|
-
}
|
|
240890
|
-
const normalized = suffix.startsWith("/") ? suffix : `/${suffix}`;
|
|
240891
|
-
return `${API_PREFIX}${normalized}`;
|
|
240892
|
-
}
|
|
240893
|
-
|
|
240894
|
-
// src/lib/upload-reusable-file.ts
|
|
240895
241701
|
function newIdempotencyKey() {
|
|
240896
241702
|
return randomUUID();
|
|
240897
241703
|
}
|
|
@@ -241046,8 +241852,8 @@ function parseInputFileSpecs(inputFile) {
|
|
|
241046
241852
|
|
|
241047
241853
|
// src/lib/format-eigenpal.ts
|
|
241048
241854
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
241049
|
-
import { existsSync as
|
|
241050
|
-
import { join as join8, resolve as
|
|
241855
|
+
import { existsSync as existsSync16, readFileSync as readFileSync16 } from "fs";
|
|
241856
|
+
import { join as join8, resolve as resolve6 } from "path";
|
|
241051
241857
|
var PRETTRC_NAMES = [
|
|
241052
241858
|
".prettierrc",
|
|
241053
241859
|
".prettierrc.json",
|
|
@@ -241060,14 +241866,14 @@ var PRETTRC_NAMES = [
|
|
|
241060
241866
|
];
|
|
241061
241867
|
function hasPrettierConfig(cwd) {
|
|
241062
241868
|
for (const name of PRETTRC_NAMES) {
|
|
241063
|
-
if (
|
|
241869
|
+
if (existsSync16(join8(cwd, name)))
|
|
241064
241870
|
return true;
|
|
241065
241871
|
}
|
|
241066
241872
|
try {
|
|
241067
241873
|
const pkgPath = join8(cwd, "package.json");
|
|
241068
|
-
if (!
|
|
241874
|
+
if (!existsSync16(pkgPath))
|
|
241069
241875
|
return false;
|
|
241070
|
-
const raw =
|
|
241876
|
+
const raw = readFileSync16(pkgPath, "utf-8");
|
|
241071
241877
|
const pkg = JSON.parse(raw);
|
|
241072
241878
|
return pkg != null && typeof pkg === "object" && "prettier" in pkg;
|
|
241073
241879
|
} catch {
|
|
@@ -241076,8 +241882,8 @@ function hasPrettierConfig(cwd) {
|
|
|
241076
241882
|
}
|
|
241077
241883
|
function formatEigenpalDirIfAvailable(dir) {
|
|
241078
241884
|
const cwd = process.cwd();
|
|
241079
|
-
const absDir =
|
|
241080
|
-
if (!
|
|
241885
|
+
const absDir = resolve6(cwd, dir);
|
|
241886
|
+
if (!existsSync16(absDir))
|
|
241081
241887
|
return;
|
|
241082
241888
|
if (!hasPrettierConfig(cwd))
|
|
241083
241889
|
return;
|
|
@@ -241204,17 +242010,17 @@ async function rerunTarget(runId, opts) {
|
|
|
241204
242010
|
init_dist4();
|
|
241205
242011
|
import { createHash as createHash5 } from "node:crypto";
|
|
241206
242012
|
import {
|
|
241207
|
-
existsSync as
|
|
242013
|
+
existsSync as existsSync17,
|
|
241208
242014
|
lstatSync,
|
|
241209
242015
|
mkdirSync as mkdirSync6,
|
|
241210
|
-
readFileSync as
|
|
242016
|
+
readFileSync as readFileSync17,
|
|
241211
242017
|
readdirSync as readdirSync5,
|
|
241212
242018
|
rmSync as rmSync2,
|
|
241213
242019
|
rmdirSync,
|
|
241214
242020
|
unlinkSync as unlinkSync2,
|
|
241215
242021
|
writeFileSync as writeFileSync8
|
|
241216
242022
|
} from "node:fs";
|
|
241217
|
-
import { sep as PATH_SEP, dirname as dirname5, join as join10, relative as relative3, resolve as
|
|
242023
|
+
import { sep as PATH_SEP, dirname as dirname5, join as join10, relative as relative3, resolve as resolve7 } from "node:path";
|
|
241218
242024
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
241219
242025
|
|
|
241220
242026
|
// src/commands/skill/tools.ts
|
|
@@ -241289,11 +242095,11 @@ var TOOLS = [
|
|
|
241289
242095
|
var MANIFEST_NAME = ".eigenpal-manifest.json";
|
|
241290
242096
|
function resolveSkillSource() {
|
|
241291
242097
|
const here = dirname5(fileURLToPath7(import.meta.url));
|
|
241292
|
-
const srcCandidate =
|
|
241293
|
-
if (
|
|
242098
|
+
const srcCandidate = resolve7(here, "..", "..", "skill");
|
|
242099
|
+
if (existsSync17(srcCandidate))
|
|
241294
242100
|
return srcCandidate;
|
|
241295
|
-
const distCandidate =
|
|
241296
|
-
if (
|
|
242101
|
+
const distCandidate = resolve7(here, "skill");
|
|
242102
|
+
if (existsSync17(distCandidate))
|
|
241297
242103
|
return distCandidate;
|
|
241298
242104
|
throw new Error(`Cannot locate bundled skill content. Looked in:
|
|
241299
242105
|
${srcCandidate}
|
|
@@ -241330,15 +242136,15 @@ async function installSkill(opts) {
|
|
|
241330
242136
|
for (const relativePath of sourceFiles) {
|
|
241331
242137
|
const sourcePath = join10(source, relativePath);
|
|
241332
242138
|
const targetPath = join10(target, relativePath);
|
|
241333
|
-
const sourceBytes = templateSourceFile(relativePath,
|
|
242139
|
+
const sourceBytes = templateSourceFile(relativePath, readFileSync17(sourcePath), cliVersion);
|
|
241334
242140
|
const sourceHash = sha256(sourceBytes);
|
|
241335
|
-
if (!
|
|
242141
|
+
if (!existsSync17(targetPath)) {
|
|
241336
242142
|
mkdirSync6(dirname5(targetPath), { recursive: true });
|
|
241337
242143
|
writeFileSync8(targetPath, sourceBytes);
|
|
241338
242144
|
written += 1;
|
|
241339
242145
|
continue;
|
|
241340
242146
|
}
|
|
241341
|
-
const targetBytes =
|
|
242147
|
+
const targetBytes = readFileSync17(targetPath);
|
|
241342
242148
|
const targetHash = sha256(targetBytes);
|
|
241343
242149
|
if (targetHash === sourceHash) {
|
|
241344
242150
|
skipped += 1;
|
|
@@ -241370,9 +242176,9 @@ async function installSkill(opts) {
|
|
|
241370
242176
|
const manifestEntries = [];
|
|
241371
242177
|
for (const relativePath of sourceFiles) {
|
|
241372
242178
|
const targetPath = join10(target, relativePath);
|
|
241373
|
-
if (!
|
|
242179
|
+
if (!existsSync17(targetPath))
|
|
241374
242180
|
continue;
|
|
241375
|
-
manifestEntries.push({ path: relativePath, sha256: sha256(
|
|
242181
|
+
manifestEntries.push({ path: relativePath, sha256: sha256(readFileSync17(targetPath)) });
|
|
241376
242182
|
}
|
|
241377
242183
|
const manifest = {
|
|
241378
242184
|
cliVersion,
|
|
@@ -241403,19 +242209,19 @@ async function uninstallSkill(opts) {
|
|
|
241403
242209
|
} else if (!opts.yes) {
|
|
241404
242210
|
throw new Error(nonInteractiveYesRequired("Uninstall skill from custom --target path"));
|
|
241405
242211
|
}
|
|
241406
|
-
const targetReal =
|
|
242212
|
+
const targetReal = resolve7(target);
|
|
241407
242213
|
const safeBase = targetReal + PATH_SEP;
|
|
241408
242214
|
let removed = 0;
|
|
241409
242215
|
let kept = 0;
|
|
241410
242216
|
for (const entry of manifest.files) {
|
|
241411
|
-
const path =
|
|
242217
|
+
const path = resolve7(targetReal, entry.path);
|
|
241412
242218
|
if (path !== targetReal && !path.startsWith(safeBase)) {
|
|
241413
242219
|
console.error(`Refusing to touch ${path}: manifest path escapes ${targetReal}`);
|
|
241414
242220
|
continue;
|
|
241415
242221
|
}
|
|
241416
|
-
if (!
|
|
242222
|
+
if (!existsSync17(path))
|
|
241417
242223
|
continue;
|
|
241418
|
-
const currentHash = sha256(
|
|
242224
|
+
const currentHash = sha256(readFileSync17(path));
|
|
241419
242225
|
if (currentHash !== entry.sha256 && !opts.yes) {
|
|
241420
242226
|
kept += 1;
|
|
241421
242227
|
continue;
|
|
@@ -241616,10 +242422,10 @@ function hintFor(tool, installed, detected) {
|
|
|
241616
242422
|
return tool.relativePath;
|
|
241617
242423
|
}
|
|
241618
242424
|
function isInstalled(cwd, tool) {
|
|
241619
|
-
return
|
|
242425
|
+
return existsSync17(join10(cwd, tool.relativePath, MANIFEST_NAME));
|
|
241620
242426
|
}
|
|
241621
242427
|
function isProjectUsing(cwd, tool) {
|
|
241622
|
-
return tool.detectPaths.some((p) =>
|
|
242428
|
+
return tool.detectPaths.some((p) => existsSync17(join10(cwd, p)));
|
|
241623
242429
|
}
|
|
241624
242430
|
function listFiles(root) {
|
|
241625
242431
|
const out = [];
|
|
@@ -241643,10 +242449,10 @@ function listFiles(root) {
|
|
|
241643
242449
|
}
|
|
241644
242450
|
function readManifest(target) {
|
|
241645
242451
|
const path = join10(target, MANIFEST_NAME);
|
|
241646
|
-
if (!
|
|
242452
|
+
if (!existsSync17(path))
|
|
241647
242453
|
return null;
|
|
241648
242454
|
try {
|
|
241649
|
-
return JSON.parse(
|
|
242455
|
+
return JSON.parse(readFileSync17(path, "utf-8"));
|
|
241650
242456
|
} catch {
|
|
241651
242457
|
return null;
|
|
241652
242458
|
}
|
|
@@ -241655,13 +242461,13 @@ function readCliVersion() {
|
|
|
241655
242461
|
try {
|
|
241656
242462
|
const here = dirname5(fileURLToPath7(import.meta.url));
|
|
241657
242463
|
const candidates = [
|
|
241658
|
-
|
|
241659
|
-
|
|
241660
|
-
|
|
242464
|
+
resolve7(here, "..", "..", "..", "package.json"),
|
|
242465
|
+
resolve7(here, "..", "..", "package.json"),
|
|
242466
|
+
resolve7(here, "..", "package.json")
|
|
241661
242467
|
];
|
|
241662
242468
|
for (const candidate of candidates) {
|
|
241663
|
-
if (
|
|
241664
|
-
const pkg = JSON.parse(
|
|
242469
|
+
if (existsSync17(candidate)) {
|
|
242470
|
+
const pkg = JSON.parse(readFileSync17(candidate, "utf-8"));
|
|
241665
242471
|
if (pkg.name && pkg.name !== "@eigenpal/cli")
|
|
241666
242472
|
continue;
|
|
241667
242473
|
if (pkg.version)
|
|
@@ -241672,7 +242478,7 @@ function readCliVersion() {
|
|
|
241672
242478
|
return "unknown";
|
|
241673
242479
|
}
|
|
241674
242480
|
function pruneEmptyDirs(root) {
|
|
241675
|
-
if (!
|
|
242481
|
+
if (!existsSync17(root))
|
|
241676
242482
|
return;
|
|
241677
242483
|
const stack = [];
|
|
241678
242484
|
const collect = (dir) => {
|
|
@@ -242462,13 +243268,13 @@ function looksLikeFreeform(prop) {
|
|
|
242462
243268
|
return prop.pattern !== undefined || prop.format !== undefined;
|
|
242463
243269
|
}
|
|
242464
243270
|
// src/commands/workflow/index.ts
|
|
242465
|
-
import { existsSync as
|
|
243271
|
+
import { existsSync as existsSync23, promises as fs20 } from "node:fs";
|
|
242466
243272
|
import path18 from "node:path";
|
|
242467
243273
|
|
|
242468
243274
|
// src/lib/local-templates.ts
|
|
242469
243275
|
init_src();
|
|
242470
|
-
import { existsSync as
|
|
242471
|
-
import { basename, dirname as dirname6, isAbsolute, relative as relative4, resolve as
|
|
243276
|
+
import { existsSync as existsSync18, promises as fs17, realpathSync as realpathSync3, statSync as statSync5 } from "node:fs";
|
|
243277
|
+
import { basename, dirname as dirname6, isAbsolute, relative as relative4, resolve as resolve8, sep } from "node:path";
|
|
242472
243278
|
|
|
242473
243279
|
// src/lib/office-template.ts
|
|
242474
243280
|
import { createHash as createHash6 } from "node:crypto";
|
|
@@ -242709,8 +243515,8 @@ function walkTemplateSteps(steps, visit) {
|
|
|
242709
243515
|
}
|
|
242710
243516
|
}
|
|
242711
243517
|
function resolveWorkflowProjectRoot(workflowFile) {
|
|
242712
|
-
const abs =
|
|
242713
|
-
if (!
|
|
243518
|
+
const abs = resolve8(workflowFile);
|
|
243519
|
+
if (!existsSync18(abs)) {
|
|
242714
243520
|
throw new Error(`Workflow file not found: ${abs}`);
|
|
242715
243521
|
}
|
|
242716
243522
|
return dirname6(realpathSync3(abs));
|
|
@@ -242729,11 +243535,11 @@ function resolveWorkflowTemplatePath(workflowFile, templatePath, opts = {}) {
|
|
|
242729
243535
|
throw new Error(`Invalid local template path "${templatePath}". Use a relative .docx or .xlsx path such as ./templates/foo.xlsx.`);
|
|
242730
243536
|
}
|
|
242731
243537
|
const projectRoot = resolveWorkflowProjectRoot(workflowFile);
|
|
242732
|
-
const candidate =
|
|
243538
|
+
const candidate = resolve8(projectRoot, templatePath);
|
|
242733
243539
|
if (!opts.allowExternal) {
|
|
242734
243540
|
assertInsideProject(projectRoot, templatePath, candidate);
|
|
242735
243541
|
}
|
|
242736
|
-
if (!
|
|
243542
|
+
if (!existsSync18(candidate)) {
|
|
242737
243543
|
throw new Error(`Local template not found: ${candidate}`);
|
|
242738
243544
|
}
|
|
242739
243545
|
const real = realpathSync3(candidate);
|
|
@@ -242915,11 +243721,11 @@ function rewriteLocalTemplateYaml(yamlText, resolved) {
|
|
|
242915
243721
|
}
|
|
242916
243722
|
|
|
242917
243723
|
// src/commands/workflow/clear.ts
|
|
242918
|
-
import { existsSync as
|
|
243724
|
+
import { existsSync as existsSync19, readdirSync as readdirSync6, rmSync as rmSync3, statSync as statSync6 } from "fs";
|
|
242919
243725
|
import { basename as basename2, join as join11 } from "path";
|
|
242920
243726
|
var EMPTY_REPORT = { removed: 0, kept: 0, touched: 0 };
|
|
242921
243727
|
function getDirectoryEntries(path) {
|
|
242922
|
-
if (!
|
|
243728
|
+
if (!existsSync19(path))
|
|
242923
243729
|
return [];
|
|
242924
243730
|
return readdirSync6(path).filter((entry) => statSync6(join11(path, entry)).isDirectory()).sort();
|
|
242925
243731
|
}
|
|
@@ -242940,7 +243746,7 @@ function removeDirEntriesWithRetention(path, removeAll) {
|
|
|
242940
243746
|
return { removed, kept: keepSet.size, touched: entries.length };
|
|
242941
243747
|
}
|
|
242942
243748
|
function removeJudgeSummaryFilesWithRetention(exampleDir, removeAll) {
|
|
242943
|
-
if (!
|
|
243749
|
+
if (!existsSync19(exampleDir))
|
|
242944
243750
|
return EMPTY_REPORT;
|
|
242945
243751
|
const stampByFile = new Map;
|
|
242946
243752
|
for (const fileName of readdirSync6(exampleDir).sort()) {
|
|
@@ -243012,7 +243818,7 @@ async function clearEvalOutputs(dir, exampleNames = [], options = {}) {
|
|
|
243012
243818
|
runSection({
|
|
243013
243819
|
exampleDirs,
|
|
243014
243820
|
clean: (exampleDir) => removeDirEntriesWithRetention(join11(exampleDir, "executions"), removeAll),
|
|
243015
|
-
shouldCount: (exampleDir) =>
|
|
243821
|
+
shouldCount: (exampleDir) => existsSync19(join11(exampleDir, "executions")),
|
|
243016
243822
|
successLabel: "Execution cleanup complete",
|
|
243017
243823
|
scannedLabel: "examples scanned:",
|
|
243018
243824
|
seenLabel: "runs seen: ",
|
|
@@ -243024,7 +243830,7 @@ async function clearEvalOutputs(dir, exampleNames = [], options = {}) {
|
|
|
243024
243830
|
runSection({
|
|
243025
243831
|
exampleDirs,
|
|
243026
243832
|
clean: (exampleDir) => removeJudgeSummaryFilesWithRetention(exampleDir, removeAll),
|
|
243027
|
-
shouldCount: (exampleDir) =>
|
|
243833
|
+
shouldCount: (exampleDir) => existsSync19(exampleDir),
|
|
243028
243834
|
successLabel: "Judge summary cleanup complete",
|
|
243029
243835
|
scannedLabel: "examples scanned: ",
|
|
243030
243836
|
seenLabel: "summary files seen: ",
|
|
@@ -243137,24 +243943,24 @@ function registerStepExecCommands(workflow) {
|
|
|
243137
243943
|
|
|
243138
243944
|
// src/commands/workflow/templates.ts
|
|
243139
243945
|
init_src();
|
|
243140
|
-
import { existsSync as
|
|
243141
|
-
import { basename as basename3, resolve as
|
|
243142
|
-
function
|
|
243946
|
+
import { existsSync as existsSync20, promises as fs19 } from "node:fs";
|
|
243947
|
+
import { basename as basename3, resolve as resolve9 } from "node:path";
|
|
243948
|
+
function buildClient3(opts) {
|
|
243143
243949
|
const config = resolveConfig(opts);
|
|
243144
243950
|
requireApiKey(config);
|
|
243145
243951
|
return new ApiClient(config);
|
|
243146
243952
|
}
|
|
243147
|
-
function
|
|
243953
|
+
function printJson3(value) {
|
|
243148
243954
|
console.log(JSON.stringify(value, null, 2));
|
|
243149
243955
|
}
|
|
243150
243956
|
async function readJsonFixtureFile(fixturePath) {
|
|
243151
243957
|
let raw;
|
|
243152
243958
|
try {
|
|
243153
|
-
raw = await fs19.readFile(
|
|
243959
|
+
raw = await fs19.readFile(resolve9(fixturePath), "utf8");
|
|
243154
243960
|
} catch (err) {
|
|
243155
243961
|
const code = err && typeof err === "object" && "code" in err ? String(err.code) : "";
|
|
243156
243962
|
if (code === "ENOENT") {
|
|
243157
|
-
throw new Error(`JSON fixture file not found: ${
|
|
243963
|
+
throw new Error(`JSON fixture file not found: ${resolve9(fixturePath)}`);
|
|
243158
243964
|
}
|
|
243159
243965
|
throw err;
|
|
243160
243966
|
}
|
|
@@ -243201,9 +244007,9 @@ function registerTemplateCommands(parent) {
|
|
|
243201
244007
|
const templates = parent.command("templates").description("Manage workspace DOCX/XLSX templates (tmpl_…): upload, list, inspect, download, replace, delete, and smoke-fill.").addHelpText("after", TEMPLATES_EXAMPLES);
|
|
243202
244008
|
const uploadCmd = templates.command("upload <file>").description("Upload a DOCX or XLSX file as a new tmpl_… resource with an immutable tmpr_… revision.").option("--name <name>", "Display name (defaults to the filename without extension)").option("--description <text>", "Optional description");
|
|
243203
244009
|
addJsonFlag(withBaseUrl(uploadCmd)).action(action(async (file, opts) => {
|
|
243204
|
-
const filePath =
|
|
244010
|
+
const filePath = resolve9(file);
|
|
243205
244011
|
const bytes = await fs19.readFile(filePath);
|
|
243206
|
-
const client =
|
|
244012
|
+
const client = buildClient3(opts);
|
|
243207
244013
|
const template = await uploadWorkspaceTemplate(client, {
|
|
243208
244014
|
bytes,
|
|
243209
244015
|
filename: basename3(filePath),
|
|
@@ -243211,7 +244017,7 @@ function registerTemplateCommands(parent) {
|
|
|
243211
244017
|
description: opts.description
|
|
243212
244018
|
});
|
|
243213
244019
|
if (opts.json) {
|
|
243214
|
-
|
|
244020
|
+
printJson3(template);
|
|
243215
244021
|
return;
|
|
243216
244022
|
}
|
|
243217
244023
|
success(`Uploaded ${ui.bold(template.id)} revision ${ui.bold(template.currentRevision?.id ?? "-")} (${template.format})`);
|
|
@@ -243219,10 +244025,10 @@ function registerTemplateCommands(parent) {
|
|
|
243219
244025
|
}));
|
|
243220
244026
|
const listCmd = templates.command("list").description("List workspace templates.");
|
|
243221
244027
|
addJsonFlag(withBaseUrl(withPagination(listCmd))).action(action(async (opts) => {
|
|
243222
|
-
const client =
|
|
244028
|
+
const client = buildClient3(opts);
|
|
243223
244029
|
const result = await listPublicTemplates(client, { limit: opts.limit, offset: opts.offset });
|
|
243224
244030
|
if (opts.json) {
|
|
243225
|
-
|
|
244031
|
+
printJson3(result);
|
|
243226
244032
|
return;
|
|
243227
244033
|
}
|
|
243228
244034
|
console.log(table(result.items.map((row) => ({
|
|
@@ -243247,10 +244053,10 @@ function registerTemplateCommands(parent) {
|
|
|
243247
244053
|
}));
|
|
243248
244054
|
const getCmd = templates.command("get <template-id>").alias("inspect").description("Inspect a tmpl_… resource: current tmpr_…, format, checksum, tokens, grammar.");
|
|
243249
244055
|
addJsonFlag(withBaseUrl(getCmd)).action(action(async (templateId, opts) => {
|
|
243250
|
-
const client =
|
|
244056
|
+
const client = buildClient3(opts);
|
|
243251
244057
|
const template = await getPublicTemplate(client, templateId);
|
|
243252
244058
|
if (opts.json) {
|
|
243253
|
-
|
|
244059
|
+
printJson3(template);
|
|
243254
244060
|
return;
|
|
243255
244061
|
}
|
|
243256
244062
|
printTemplateHuman(template);
|
|
@@ -243259,21 +244065,21 @@ function registerTemplateCommands(parent) {
|
|
|
243259
244065
|
withBaseUrl(downloadCmd).action(action(async (templateId, opts) => {
|
|
243260
244066
|
if (!opts.out)
|
|
243261
244067
|
throw new Error("Missing --out <path>.");
|
|
243262
|
-
const client =
|
|
244068
|
+
const client = buildClient3(opts);
|
|
243263
244069
|
const downloaded = await downloadTemplateBytes(client, templateId, opts.revisionId);
|
|
243264
244070
|
await fs19.writeFile(opts.out, downloaded.bytes);
|
|
243265
244071
|
success(`Wrote ${ui.bold(opts.out)} ${ui.dim(`(${downloaded.bytes.byteLength} bytes)`)}`);
|
|
243266
244072
|
}));
|
|
243267
244073
|
const replaceCmd = templates.command("replace <template-id> <file>").description("Append an immutable revision and advance the tmpl_… pointer.");
|
|
243268
244074
|
addJsonFlag(withBaseUrl(replaceCmd)).action(action(async (templateId, file, opts) => {
|
|
243269
|
-
const filePath =
|
|
244075
|
+
const filePath = resolve9(file);
|
|
243270
244076
|
const bytes = await fs19.readFile(filePath);
|
|
243271
|
-
const client =
|
|
244077
|
+
const client = buildClient3(opts);
|
|
243272
244078
|
const current = await getPublicTemplate(client, templateId);
|
|
243273
244079
|
const nextInspection = inspectOfficeTemplateBytes(bytes, basename3(filePath));
|
|
243274
244080
|
if (current.currentRevision?.sha256 === nextInspection.sha256 || current.sha256 === nextInspection.sha256) {
|
|
243275
244081
|
if (opts.json) {
|
|
243276
|
-
|
|
244082
|
+
printJson3({ ...current, reused: true });
|
|
243277
244083
|
return;
|
|
243278
244084
|
}
|
|
243279
244085
|
success(`Checksum matches current revision ${ui.bold(current.currentRevision?.id ?? "-")} — skipped upload`);
|
|
@@ -243285,7 +244091,7 @@ function registerTemplateCommands(parent) {
|
|
|
243285
244091
|
filename: basename3(filePath)
|
|
243286
244092
|
});
|
|
243287
244093
|
if (opts.json) {
|
|
243288
|
-
|
|
244094
|
+
printJson3(template);
|
|
243289
244095
|
return;
|
|
243290
244096
|
}
|
|
243291
244097
|
success(`Replaced ${ui.bold(template.id)} → revision ${ui.bold(template.currentRevision?.id ?? "-")}`);
|
|
@@ -243296,10 +244102,10 @@ function registerTemplateCommands(parent) {
|
|
|
243296
244102
|
if (!opts.yes && !process.stdout.isTTY) {
|
|
243297
244103
|
throw new Error("templates delete is destructive and requires --yes when run non-interactively");
|
|
243298
244104
|
}
|
|
243299
|
-
const client =
|
|
244105
|
+
const client = buildClient3(opts);
|
|
243300
244106
|
const result = await deleteWorkspaceTemplate(client, templateId);
|
|
243301
244107
|
if (opts.json) {
|
|
243302
|
-
|
|
244108
|
+
printJson3(result);
|
|
243303
244109
|
return;
|
|
243304
244110
|
}
|
|
243305
244111
|
success(`Deleted ${ui.bold(templateId)}`);
|
|
@@ -243312,13 +244118,13 @@ function registerTemplateCommands(parent) {
|
|
|
243312
244118
|
let filename;
|
|
243313
244119
|
const isTmpl = TemplateIdSchema.safeParse(templateArg).success;
|
|
243314
244120
|
if (isTmpl) {
|
|
243315
|
-
const client =
|
|
244121
|
+
const client = buildClient3(opts);
|
|
243316
244122
|
const downloaded = await downloadTemplateBytes(client, templateArg, opts.revisionId);
|
|
243317
244123
|
bytes = downloaded.bytes;
|
|
243318
244124
|
filename = downloaded.filename;
|
|
243319
244125
|
} else {
|
|
243320
|
-
const filePath =
|
|
243321
|
-
if (!
|
|
244126
|
+
const filePath = resolve9(templateArg);
|
|
244127
|
+
if (!existsSync20(filePath)) {
|
|
243322
244128
|
throw new Error(`Template file not found: ${filePath}. Pass a local .docx/.xlsx path or a tmpl_… id.`);
|
|
243323
244129
|
}
|
|
243324
244130
|
bytes = await fs19.readFile(filePath);
|
|
@@ -243340,7 +244146,7 @@ function registerTemplateCommands(parent) {
|
|
|
243340
244146
|
bytes: rendered.output.byteLength
|
|
243341
244147
|
};
|
|
243342
244148
|
if (opts.json) {
|
|
243343
|
-
|
|
244149
|
+
printJson3(payload);
|
|
243344
244150
|
return;
|
|
243345
244151
|
}
|
|
243346
244152
|
success(`Wrote ${ui.bold(opts.out)} (${rendered.inspection.format}, ${rendered.output.byteLength} bytes)`);
|
|
@@ -243360,12 +244166,12 @@ function registerTemplateCommands(parent) {
|
|
|
243360
244166
|
|
|
243361
244167
|
// src/commands/workflow/validation.ts
|
|
243362
244168
|
init_src();
|
|
243363
|
-
import { existsSync as
|
|
243364
|
-
import { join as join12, resolve as
|
|
244169
|
+
import { existsSync as existsSync22, readdirSync as readdirSync7, readFileSync as readFileSync19, statSync as statSync7 } from "fs";
|
|
244170
|
+
import { join as join12, resolve as resolve10 } from "path";
|
|
243365
244171
|
|
|
243366
244172
|
// src/lib/template-diagnostics.ts
|
|
243367
244173
|
init_src();
|
|
243368
|
-
import { existsSync as
|
|
244174
|
+
import { existsSync as existsSync21, readFileSync as readFileSync18 } from "node:fs";
|
|
243369
244175
|
function walkSteps(steps, pathPrefix, visit) {
|
|
243370
244176
|
if (!Array.isArray(steps))
|
|
243371
244177
|
return;
|
|
@@ -243490,7 +244296,7 @@ async function diagnoseTemplateSteps(args) {
|
|
|
243490
244296
|
});
|
|
243491
244297
|
continue;
|
|
243492
244298
|
}
|
|
243493
|
-
if (!
|
|
244299
|
+
if (!existsSync21(absolute)) {
|
|
243494
244300
|
diagnostics.push({
|
|
243495
244301
|
field: `${info.fieldPath}.template`,
|
|
243496
244302
|
message: `File not found: ${absolute}`,
|
|
@@ -243499,7 +244305,7 @@ async function diagnoseTemplateSteps(args) {
|
|
|
243499
244305
|
continue;
|
|
243500
244306
|
}
|
|
243501
244307
|
try {
|
|
243502
|
-
const bytes =
|
|
244308
|
+
const bytes = readFileSync18(absolute);
|
|
243503
244309
|
const inspection = inspectOfficeTemplateBytes(bytes, absolute);
|
|
243504
244310
|
diagnostics.push(...formatDiagnostics(info, inspection));
|
|
243505
244311
|
} catch (err) {
|
|
@@ -243635,7 +244441,7 @@ function countInvokeWorkflowSteps(steps) {
|
|
|
243635
244441
|
return count;
|
|
243636
244442
|
}
|
|
243637
244443
|
function validateWorkflowYaml(path) {
|
|
243638
|
-
if (!
|
|
244444
|
+
if (!existsSync22(path)) {
|
|
243639
244445
|
return {
|
|
243640
244446
|
issues: [{ field: path, message: "File not found." }],
|
|
243641
244447
|
warnings: [],
|
|
@@ -243644,7 +244450,7 @@ function validateWorkflowYaml(path) {
|
|
|
243644
244450
|
steps: []
|
|
243645
244451
|
};
|
|
243646
244452
|
}
|
|
243647
|
-
const text =
|
|
244453
|
+
const text = readFileSync19(path, "utf-8");
|
|
243648
244454
|
try {
|
|
243649
244455
|
const definition = parseWorkflow(text);
|
|
243650
244456
|
let warnings = [];
|
|
@@ -243745,10 +244551,10 @@ function printSchemaQualityWarnings(path, warnings) {
|
|
|
243745
244551
|
}
|
|
243746
244552
|
}
|
|
243747
244553
|
function validateEvaluatorsYaml(path) {
|
|
243748
|
-
if (!
|
|
244554
|
+
if (!existsSync22(path)) {
|
|
243749
244555
|
return [{ field: path, message: "File not found." }];
|
|
243750
244556
|
}
|
|
243751
|
-
const text =
|
|
244557
|
+
const text = readFileSync19(path, "utf-8");
|
|
243752
244558
|
let parsed;
|
|
243753
244559
|
try {
|
|
243754
244560
|
parsed = $parse(text);
|
|
@@ -243765,17 +244571,17 @@ function validateEvaluatorsYaml(path) {
|
|
|
243765
244571
|
}
|
|
243766
244572
|
function validateDatasetFolder(root) {
|
|
243767
244573
|
const issues = [];
|
|
243768
|
-
if (!
|
|
244574
|
+
if (!existsSync22(root)) {
|
|
243769
244575
|
return [{ field: root, message: "Folder not found." }];
|
|
243770
244576
|
}
|
|
243771
|
-
if (
|
|
244577
|
+
if (existsSync22(join12(root, "manifest.json"))) {
|
|
243772
244578
|
issues.push({
|
|
243773
244579
|
field: "manifest.json",
|
|
243774
244580
|
message: "Top-level manifest.json is the legacy format. Re-export the dataset using the folder convention."
|
|
243775
244581
|
});
|
|
243776
244582
|
}
|
|
243777
244583
|
const examplesDir = join12(root, "examples");
|
|
243778
|
-
if (!
|
|
244584
|
+
if (!existsSync22(examplesDir)) {
|
|
243779
244585
|
issues.push({ field: "examples/", message: "No examples/ directory found at dataset root." });
|
|
243780
244586
|
return issues;
|
|
243781
244587
|
}
|
|
@@ -243791,7 +244597,7 @@ function validateDatasetFolder(root) {
|
|
|
243791
244597
|
continue;
|
|
243792
244598
|
}
|
|
243793
244599
|
const inputJsonPath = join12(exampleFolder, "input.json");
|
|
243794
|
-
const hasInputJson =
|
|
244600
|
+
const hasInputJson = existsSync22(inputJsonPath);
|
|
243795
244601
|
if (!hasInputJson) {
|
|
243796
244602
|
issues.push({
|
|
243797
244603
|
field: `examples/${exampleName}/input.json`,
|
|
@@ -243801,7 +244607,7 @@ function validateDatasetFolder(root) {
|
|
|
243801
244607
|
}
|
|
243802
244608
|
let args;
|
|
243803
244609
|
try {
|
|
243804
|
-
const parsed = JSON.parse(
|
|
244610
|
+
const parsed = JSON.parse(readFileSync19(inputJsonPath, "utf-8"));
|
|
243805
244611
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
243806
244612
|
issues.push({
|
|
243807
244613
|
field: `examples/${exampleName}/input.json`,
|
|
@@ -243818,7 +244624,7 @@ function validateDatasetFolder(root) {
|
|
|
243818
244624
|
continue;
|
|
243819
244625
|
}
|
|
243820
244626
|
const inputDir = join12(exampleFolder, "input");
|
|
243821
|
-
if (
|
|
244627
|
+
if (existsSync22(join12(inputDir, "arguments.json"))) {
|
|
243822
244628
|
issues.push({
|
|
243823
244629
|
field: `examples/${exampleName}/input/arguments.json`,
|
|
243824
244630
|
message: "Legacy input/arguments.json is no longer accepted. Use input.json instead."
|
|
@@ -243835,7 +244641,7 @@ function validateDatasetFolder(root) {
|
|
|
243835
244641
|
}
|
|
243836
244642
|
const expectedDir = join12(exampleFolder, "expected");
|
|
243837
244643
|
const expectedJsonPath = join12(exampleFolder, "expected.json");
|
|
243838
|
-
if (
|
|
244644
|
+
if (existsSync22(expectedDir)) {
|
|
243839
244645
|
for (const entry of readdirSync7(expectedDir)) {
|
|
243840
244646
|
if (entry === "output.json" || entry === "error.json") {
|
|
243841
244647
|
issues.push({
|
|
@@ -243871,10 +244677,10 @@ function validateDatasetFolder(root) {
|
|
|
243871
244677
|
}
|
|
243872
244678
|
}
|
|
243873
244679
|
}
|
|
243874
|
-
if (
|
|
244680
|
+
if (existsSync22(expectedJsonPath)) {
|
|
243875
244681
|
let parsed;
|
|
243876
244682
|
try {
|
|
243877
|
-
parsed = JSON.parse(
|
|
244683
|
+
parsed = JSON.parse(readFileSync19(expectedJsonPath, "utf-8"));
|
|
243878
244684
|
} catch {
|
|
243879
244685
|
issues.push({
|
|
243880
244686
|
field: `examples/${exampleName}/expected.json`,
|
|
@@ -243953,7 +244759,7 @@ function validateFileRefs2(args) {
|
|
|
243953
244759
|
});
|
|
243954
244760
|
continue;
|
|
243955
244761
|
}
|
|
243956
|
-
if (!
|
|
244762
|
+
if (!existsSync22(join12(args.filesRoot, relative))) {
|
|
243957
244763
|
issues.push({
|
|
243958
244764
|
field: `${args.fieldPrefix}:${ref.jsonPath}`,
|
|
243959
244765
|
message: `Referenced file does not exist: ${ref.path}.`
|
|
@@ -243974,7 +244780,7 @@ function parseDatasetFileRef(path, root) {
|
|
|
243974
244780
|
return parts.join("/");
|
|
243975
244781
|
}
|
|
243976
244782
|
function rootDir(opts) {
|
|
243977
|
-
return
|
|
244783
|
+
return resolve10(opts.dir ?? process.cwd());
|
|
243978
244784
|
}
|
|
243979
244785
|
async function onlineInvokeIssues(yamlText, opts) {
|
|
243980
244786
|
const config = resolveConfig(opts);
|
|
@@ -243984,8 +244790,8 @@ async function onlineInvokeIssues(yamlText, opts) {
|
|
|
243984
244790
|
return res.issues ?? [];
|
|
243985
244791
|
}
|
|
243986
244792
|
function discoverWorkflowProjectRoots(rootPath) {
|
|
243987
|
-
const root =
|
|
243988
|
-
if (
|
|
244793
|
+
const root = resolve10(rootPath);
|
|
244794
|
+
if (existsSync22(join12(root, "workflow.yaml")))
|
|
243989
244795
|
return [root];
|
|
243990
244796
|
const candidates = [
|
|
243991
244797
|
join12(root, "eigenpal", "workflows"),
|
|
@@ -243993,9 +244799,9 @@ function discoverWorkflowProjectRoots(rootPath) {
|
|
|
243993
244799
|
root.endsWith(join12("eigenpal", "workflows")) ? root : ""
|
|
243994
244800
|
].filter(Boolean);
|
|
243995
244801
|
for (const parent of candidates) {
|
|
243996
|
-
if (!
|
|
244802
|
+
if (!existsSync22(parent) || !statSync7(parent).isDirectory())
|
|
243997
244803
|
continue;
|
|
243998
|
-
const projects = readdirSync7(parent, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.isSymbolicLink() &&
|
|
244804
|
+
const projects = readdirSync7(parent, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.isSymbolicLink() && existsSync22(join12(parent, entry.name, "workflow.yaml"))).map((entry) => join12(parent, entry.name)).sort();
|
|
243999
244805
|
if (projects.length > 0)
|
|
244000
244806
|
return projects;
|
|
244001
244807
|
}
|
|
@@ -244012,10 +244818,10 @@ async function validateProjectRoot(root, opts) {
|
|
|
244012
244818
|
}
|
|
244013
244819
|
const evOk = printIssues("evaluators.yaml", relPath(root, join12(root, "evaluators.yaml")), validateEvaluatorsYaml(join12(root, "evaluators.yaml")));
|
|
244014
244820
|
const dsOk = printIssues("dataset/", relPath(root, join12(root, "dataset")), validateDatasetFolder(join12(root, "dataset")));
|
|
244015
|
-
const templateOk = wfOk &&
|
|
244821
|
+
const templateOk = wfOk && existsSync22(wfFile) ? await runTemplateDiagnostics(wfFile, wfResult.steps, opts) : true;
|
|
244016
244822
|
let onlineOk = true;
|
|
244017
|
-
if (wfOk && opts.online &&
|
|
244018
|
-
onlineOk = printIssues("invoke refs (server)", wfPath, await onlineInvokeIssues(
|
|
244823
|
+
if (wfOk && opts.online && existsSync22(wfFile)) {
|
|
244824
|
+
onlineOk = printIssues("invoke refs (server)", wfPath, await onlineInvokeIssues(readFileSync19(wfFile, "utf-8"), opts));
|
|
244019
244825
|
}
|
|
244020
244826
|
return wfOk && evOk && dsOk && templateOk && onlineOk;
|
|
244021
244827
|
}
|
|
@@ -244031,8 +244837,8 @@ Note
|
|
|
244031
244837
|
` + ` project unless you pass --allow-external-templates.
|
|
244032
244838
|
`);
|
|
244033
244839
|
withBaseUrl(cmd).action(action(async (path, opts) => {
|
|
244034
|
-
if (path && (!
|
|
244035
|
-
const target =
|
|
244840
|
+
if (path && (!existsSync22(resolve10(path)) || !statSync7(resolve10(path)).isDirectory())) {
|
|
244841
|
+
const target = resolve10(path);
|
|
244036
244842
|
const wfResult = validateWorkflowYaml(target);
|
|
244037
244843
|
const wfOk = printIssues("workflow.yaml", target, wfResult.issues);
|
|
244038
244844
|
if (wfOk) {
|
|
@@ -244042,13 +244848,13 @@ Note
|
|
|
244042
244848
|
const templateOk = wfOk ? await runTemplateDiagnostics(target, wfResult.steps, opts) : true;
|
|
244043
244849
|
let onlineOk = true;
|
|
244044
244850
|
if (wfOk && opts.online) {
|
|
244045
|
-
onlineOk = printIssues("invoke refs (server)", target, await onlineInvokeIssues(
|
|
244851
|
+
onlineOk = printIssues("invoke refs (server)", target, await onlineInvokeIssues(readFileSync19(target, "utf-8"), opts));
|
|
244046
244852
|
}
|
|
244047
244853
|
if (!wfOk || !templateOk || !onlineOk)
|
|
244048
244854
|
process.exit(1);
|
|
244049
244855
|
return;
|
|
244050
244856
|
}
|
|
244051
|
-
const requestedRoot = path ?
|
|
244857
|
+
const requestedRoot = path ? resolve10(path) : rootDir(opts);
|
|
244052
244858
|
const projects = discoverWorkflowProjectRoots(requestedRoot);
|
|
244053
244859
|
if (projects.length === 0) {
|
|
244054
244860
|
if (!await validateProjectRoot(requestedRoot, opts))
|
|
@@ -244070,14 +244876,14 @@ Note
|
|
|
244070
244876
|
}
|
|
244071
244877
|
function registerEvaluatorsValidateCommand(parent) {
|
|
244072
244878
|
parent.command("validate [path]").description("Validate an evaluators YAML file against the EvalConfig schema. Defaults to ./evaluators.yaml.").action((path) => {
|
|
244073
|
-
const target =
|
|
244879
|
+
const target = resolve10(path ?? "evaluators.yaml");
|
|
244074
244880
|
if (!printIssues("evaluators", target, validateEvaluatorsYaml(target)))
|
|
244075
244881
|
process.exit(1);
|
|
244076
244882
|
});
|
|
244077
244883
|
}
|
|
244078
244884
|
function registerDatasetValidateCommand(parent) {
|
|
244079
244885
|
parent.command("validate [path]").description("Validate a dataset folder against the examples/<name>/{input,expected,meta} convention. Defaults to ./dataset/.").action((path) => {
|
|
244080
|
-
const target =
|
|
244886
|
+
const target = resolve10(path ?? "dataset");
|
|
244081
244887
|
if (!printIssues("dataset", target, validateDatasetFolder(target)))
|
|
244082
244888
|
process.exit(1);
|
|
244083
244889
|
});
|
|
@@ -244091,20 +244897,20 @@ function relPath(root, target) {
|
|
|
244091
244897
|
}
|
|
244092
244898
|
|
|
244093
244899
|
// src/commands/workflow/index.ts
|
|
244094
|
-
function
|
|
244900
|
+
function buildClient4(opts) {
|
|
244095
244901
|
const config = resolveConfig(opts);
|
|
244096
244902
|
requireApiKey(config);
|
|
244097
244903
|
return new ApiClient(config);
|
|
244098
244904
|
}
|
|
244099
244905
|
async function buildClientForWorkflow(workflowIdOrSlug, opts) {
|
|
244100
|
-
const client =
|
|
244906
|
+
const client = buildClient4(opts);
|
|
244101
244907
|
const workflowId = await resolveWorkflowId(client, workflowIdOrSlug);
|
|
244102
244908
|
return { client, workflowId };
|
|
244103
244909
|
}
|
|
244104
244910
|
function descriptionFor(tool) {
|
|
244105
244911
|
return WORKFLOW_TOOL_METADATA[tool].description;
|
|
244106
244912
|
}
|
|
244107
|
-
function
|
|
244913
|
+
function printJson4(value) {
|
|
244108
244914
|
console.log(JSON.stringify(value, null, 2));
|
|
244109
244915
|
}
|
|
244110
244916
|
function extractWorkflowVersion(yaml) {
|
|
@@ -244205,7 +245011,7 @@ YAML's \`name:\` field). Both:
|
|
|
244205
245011
|
function registerWorkflowCoreCommands(parent) {
|
|
244206
245012
|
const listCmd = parent.command("list").description(descriptionFor("workflow_list")).option("--search <q>", "Filter by name");
|
|
244207
245013
|
addJsonFlag(withBaseUrl(withPagination(listCmd))).action(action(async (opts) => {
|
|
244208
|
-
const client =
|
|
245014
|
+
const client = buildClient4(opts);
|
|
244209
245015
|
const params = {
|
|
244210
245016
|
limit: String(opts.limit),
|
|
244211
245017
|
offset: String(opts.offset)
|
|
@@ -244293,7 +245099,7 @@ new uploads are deleted. The file on disk is not rewritten.
|
|
|
244293
245099
|
defaultValue: "workflow.yaml",
|
|
244294
245100
|
validate: (value) => {
|
|
244295
245101
|
const p = value || "workflow.yaml";
|
|
244296
|
-
if (!
|
|
245102
|
+
if (!existsSync23(p))
|
|
244297
245103
|
return `Not found: ${p}`;
|
|
244298
245104
|
return;
|
|
244299
245105
|
}
|
|
@@ -244308,7 +245114,7 @@ new uploads are deleted. The file on disk is not rewritten.
|
|
|
244308
245114
|
}
|
|
244309
245115
|
}
|
|
244310
245116
|
const yamlOnDisk = await fs20.readFile(filePath, "utf8");
|
|
244311
|
-
const client =
|
|
245117
|
+
const client = buildClient4(opts);
|
|
244312
245118
|
const definition = parseWorkflowOrThrow(yamlOnDisk);
|
|
244313
245119
|
const loadedTemplates = await loadLocalTemplatesForPush(filePath, definition.steps, {
|
|
244314
245120
|
allowExternal: Boolean(opts.allowExternalTemplates)
|
|
@@ -244366,7 +245172,7 @@ new uploads are deleted. The file on disk is not rewritten.
|
|
|
244366
245172
|
});
|
|
244367
245173
|
await finalizeCreatedWorkspaceTemplates(client, created);
|
|
244368
245174
|
if (opts.json) {
|
|
244369
|
-
|
|
245175
|
+
printJson4(withLocalTemplates(result, resolvedTemplates));
|
|
244370
245176
|
return;
|
|
244371
245177
|
}
|
|
244372
245178
|
success(`Pushed ${ui.bold(workflowId)} (v${result.version ?? nextVersion})`);
|
|
@@ -244380,7 +245186,7 @@ new uploads are deleted. The file on disk is not rewritten.
|
|
|
244380
245186
|
});
|
|
244381
245187
|
await finalizeCreatedWorkspaceTemplates(client, created);
|
|
244382
245188
|
if (opts.json) {
|
|
244383
|
-
|
|
245189
|
+
printJson4(withLocalTemplates(result, resolvedTemplates));
|
|
244384
245190
|
return;
|
|
244385
245191
|
}
|
|
244386
245192
|
const id = result.workflow?.id ?? result.id ?? "?";
|
|
@@ -244399,7 +245205,7 @@ new uploads are deleted. The file on disk is not rewritten.
|
|
|
244399
245205
|
folderPath: opts.folder
|
|
244400
245206
|
});
|
|
244401
245207
|
if (opts.json) {
|
|
244402
|
-
|
|
245208
|
+
printJson4(result);
|
|
244403
245209
|
return;
|
|
244404
245210
|
}
|
|
244405
245211
|
const target = opts.folder.trim() === "/" ? "root" : opts.folder;
|
|
@@ -244572,7 +245378,7 @@ function registerEvaluatorsCommands(parent) {
|
|
|
244572
245378
|
yaml
|
|
244573
245379
|
});
|
|
244574
245380
|
if (opts.json) {
|
|
244575
|
-
|
|
245381
|
+
printJson4(result);
|
|
244576
245382
|
return;
|
|
244577
245383
|
}
|
|
244578
245384
|
let count = null;
|
|
@@ -244680,7 +245486,7 @@ skip in CI). Folder layout reference: \`packages/cli/src/skill/reference/dataset
|
|
|
244680
245486
|
}));
|
|
244681
245487
|
if (issues.length === 0) {
|
|
244682
245488
|
error2("Import aborted with no structured issues — server-side bug.");
|
|
244683
|
-
|
|
245489
|
+
printJson4(terminal);
|
|
244684
245490
|
} else {
|
|
244685
245491
|
printIssues("dataset", opts.file, issues);
|
|
244686
245492
|
if (errPayload.limitMb != null && errPayload.actualMb != null) {
|
|
@@ -244701,7 +245507,7 @@ skip in CI). Folder layout reference: \`packages/cli/src/skill/reference/dataset
|
|
|
244701
245507
|
if (terminal.phase === "done") {
|
|
244702
245508
|
const done = terminal;
|
|
244703
245509
|
if (opts.json) {
|
|
244704
|
-
|
|
245510
|
+
printJson4(done);
|
|
244705
245511
|
return;
|
|
244706
245512
|
}
|
|
244707
245513
|
const created = done.created ?? 0;
|
|
@@ -244719,7 +245525,7 @@ skip in CI). Folder layout reference: \`packages/cli/src/skill/reference/dataset
|
|
|
244719
245525
|
}
|
|
244720
245526
|
} else {
|
|
244721
245527
|
error2(`Import response had unexpected terminal phase: ${terminal.phase}`);
|
|
244722
|
-
|
|
245528
|
+
printJson4(terminal);
|
|
244723
245529
|
process.exit(1);
|
|
244724
245530
|
}
|
|
244725
245531
|
}));
|
|
@@ -244779,7 +245585,7 @@ exclusive. To attach files without a dataset folder, pass ingress refs in JSON:
|
|
|
244779
245585
|
const { client, workflowId } = await buildClientForWorkflow(workflow, opts);
|
|
244780
245586
|
const result = await client.post(`/v1/automations/${workflowId}/examples`, body);
|
|
244781
245587
|
if (opts.json) {
|
|
244782
|
-
|
|
245588
|
+
printJson4(result);
|
|
244783
245589
|
return;
|
|
244784
245590
|
}
|
|
244785
245591
|
success(`Created example ${ui.bold(opts.name)} (${result.id}) in ${ui.bold(workflowId)}`);
|
|
@@ -244805,7 +245611,7 @@ exclusive. To attach files without a dataset folder, pass ingress refs in JSON:
|
|
|
244805
245611
|
const { client, workflowId } = await buildClientForWorkflow(workflow, opts);
|
|
244806
245612
|
const result = await client.patch(`/v1/automations/${workflowId}/examples/${encodeURIComponent(exampleId)}`, body);
|
|
244807
245613
|
if (opts.json) {
|
|
244808
|
-
|
|
245614
|
+
printJson4(result);
|
|
244809
245615
|
return;
|
|
244810
245616
|
}
|
|
244811
245617
|
const fields = Object.keys(body).join(", ");
|
|
@@ -244819,7 +245625,7 @@ exclusive. To attach files without a dataset folder, pass ingress refs in JSON:
|
|
|
244819
245625
|
const { client, workflowId } = await buildClientForWorkflow(workflow, opts);
|
|
244820
245626
|
const deleted = await client.delete(`/v1/automations/${workflowId}/examples/${encodeURIComponent(exampleId)}`);
|
|
244821
245627
|
if (opts.json) {
|
|
244822
|
-
|
|
245628
|
+
printJson4(deleted);
|
|
244823
245629
|
return;
|
|
244824
245630
|
}
|
|
244825
245631
|
success(`Deleted example ${ui.bold(deleted.name ?? exampleId)} ${ui.dim(`(${exampleId})`)} from ${ui.bold(workflowId)}`);
|
|
@@ -244829,7 +245635,7 @@ exclusive. To attach files without a dataset folder, pass ingress refs in JSON:
|
|
|
244829
245635
|
const { client, workflowId } = await buildClientForWorkflow(workflow, opts);
|
|
244830
245636
|
const row = await client.get(`/v1/automations/${workflowId}/examples/${encodeURIComponent(exampleId)}`);
|
|
244831
245637
|
if (opts.json) {
|
|
244832
|
-
|
|
245638
|
+
printJson4(row);
|
|
244833
245639
|
return;
|
|
244834
245640
|
}
|
|
244835
245641
|
renderExampleHuman(row);
|
|
@@ -244956,7 +245762,7 @@ returns immediately with \`{ batchId, total }\`; poll
|
|
|
244956
245762
|
const total = start.runCount ?? start.total ?? 0;
|
|
244957
245763
|
if (!opts.wait) {
|
|
244958
245764
|
if (opts.json) {
|
|
244959
|
-
|
|
245765
|
+
printJson4({ ...start, batchId: experimentId, total });
|
|
244960
245766
|
return;
|
|
244961
245767
|
}
|
|
244962
245768
|
success(`Started experiment ${ui.bold(experimentId)} ${ui.dim(`(${total} run${total === 1 ? "" : "s"} queued)`)}`);
|
|
@@ -244970,7 +245776,7 @@ returns immediately with \`{ batchId, total }\`; poll
|
|
|
244970
245776
|
const status = await client.get(`/v1/automations/${workflowId}/experiments/${experimentId}`);
|
|
244971
245777
|
if (status.status === "completed") {
|
|
244972
245778
|
if (opts.json) {
|
|
244973
|
-
|
|
245779
|
+
printJson4({
|
|
244974
245780
|
...status,
|
|
244975
245781
|
batchId: experimentId,
|
|
244976
245782
|
total: status.runCount ?? status.total
|
|
@@ -244990,7 +245796,7 @@ returns immediately with \`{ batchId, total }\`; poll
|
|
|
244990
245796
|
}
|
|
244991
245797
|
if (Date.now() >= deadline) {
|
|
244992
245798
|
if (opts.json) {
|
|
244993
|
-
|
|
245799
|
+
printJson4({
|
|
244994
245800
|
...status,
|
|
244995
245801
|
batchId: experimentId,
|
|
244996
245802
|
total: status.runCount ?? status.total
|
|
@@ -245030,12 +245836,12 @@ returns immediately with \`{ batchId, total }\`; poll
|
|
|
245030
245836
|
const summary = summarizeExperimentExecutions(execs);
|
|
245031
245837
|
if (execs.length === 0) {
|
|
245032
245838
|
if (opts.json)
|
|
245033
|
-
|
|
245839
|
+
printJson4({ ...result, summary: rollupForJson(summary) });
|
|
245034
245840
|
error2(`Experiment ${batchId} still has no executions after retrying — check the batch id.`);
|
|
245035
245841
|
process.exit(1);
|
|
245036
245842
|
}
|
|
245037
245843
|
if (opts.json) {
|
|
245038
|
-
|
|
245844
|
+
printJson4({ ...result, summary: rollupForJson(summary) });
|
|
245039
245845
|
return;
|
|
245040
245846
|
}
|
|
245041
245847
|
if (opts.short) {
|
|
@@ -245067,7 +245873,7 @@ returns immediately with \`{ batchId, total }\`; poll
|
|
|
245067
245873
|
maxWait: opts.maxWait,
|
|
245068
245874
|
onTerminal: (result, summary) => {
|
|
245069
245875
|
if (wantPayload) {
|
|
245070
|
-
|
|
245876
|
+
printJson4({ ...result, summary: rollupForJson(summary) });
|
|
245071
245877
|
} else {
|
|
245072
245878
|
process.stderr.write(`${ui.dim(`use --include payload (or --json) for the full per-execution snapshot`)}
|
|
245073
245879
|
`);
|
|
@@ -245075,7 +245881,7 @@ returns immediately with \`{ batchId, total }\`; poll
|
|
|
245075
245881
|
},
|
|
245076
245882
|
onDeadline: (result, summary) => {
|
|
245077
245883
|
if (wantPayload)
|
|
245078
|
-
|
|
245884
|
+
printJson4({ ...result, summary: rollupForJson(summary) });
|
|
245079
245885
|
}
|
|
245080
245886
|
});
|
|
245081
245887
|
}));
|
|
@@ -245099,7 +245905,7 @@ Behavior:
|
|
|
245099
245905
|
const { client, workflowId } = await buildClientForWorkflow(workflow, opts);
|
|
245100
245906
|
const result = await client.post(`/v1/automations/${workflowId}/experiments/${batchId}/cancel`);
|
|
245101
245907
|
if (opts.json) {
|
|
245102
|
-
|
|
245908
|
+
printJson4(result);
|
|
245103
245909
|
return;
|
|
245104
245910
|
}
|
|
245105
245911
|
const c = result.counts;
|
|
@@ -245173,7 +245979,7 @@ batches must belong to the same workflow within the caller's tenant.
|
|
|
245173
245979
|
if (!Number.isFinite(threshold) || threshold < 0) {
|
|
245174
245980
|
throw new Error("--regression-threshold must be a non-negative number");
|
|
245175
245981
|
}
|
|
245176
|
-
const client =
|
|
245982
|
+
const client = buildClient4(opts);
|
|
245177
245983
|
if (opts.outputs) {
|
|
245178
245984
|
const [outputsA, outputsB] = await Promise.all([
|
|
245179
245985
|
fetchExperimentOutputs(client, batchIdA),
|
|
@@ -245189,7 +245995,7 @@ batches must belong to the same workflow within the caller's tenant.
|
|
|
245189
245995
|
rowsB: outputsB.rows
|
|
245190
245996
|
});
|
|
245191
245997
|
if (opts.json)
|
|
245192
|
-
|
|
245998
|
+
printJson4(outputDiff);
|
|
245193
245999
|
else
|
|
245194
246000
|
renderExperimentOutputDiffHuman(outputDiff);
|
|
245195
246001
|
return;
|
|
@@ -245207,7 +246013,7 @@ batches must belong to the same workflow within the caller's tenant.
|
|
|
245207
246013
|
regressionThreshold: threshold
|
|
245208
246014
|
});
|
|
245209
246015
|
if (opts.json) {
|
|
245210
|
-
|
|
246016
|
+
printJson4(diff);
|
|
245211
246017
|
return;
|
|
245212
246018
|
}
|
|
245213
246019
|
renderBatchDiffHuman(diff);
|
|
@@ -245245,7 +246051,7 @@ Behavior:
|
|
|
245245
246051
|
const dest = opts.pull ? opts.pullOnComplete ?? `./results-${batchId}.${opts.format}` : null;
|
|
245246
246052
|
if (dest) {
|
|
245247
246053
|
const dir = path18.dirname(dest);
|
|
245248
|
-
if (!
|
|
246054
|
+
if (!existsSync23(dir)) {
|
|
245249
246055
|
error2(`Destination directory does not exist: ${dir}. Create it first or pass a path under an existing directory.`);
|
|
245250
246056
|
process.exit(2);
|
|
245251
246057
|
}
|
|
@@ -245492,7 +246298,7 @@ sent to the server is replaced with \`templateId\` + \`templateRevisionId\`.
|
|
|
245492
246298
|
const result = await client.post(automationVersionsPath(workflowId), body).catch((err) => rethrowAfterTemplateCleanup(client, created, err));
|
|
245493
246299
|
await finalizeCreatedWorkspaceTemplates(client, created);
|
|
245494
246300
|
if (opts.json) {
|
|
245495
|
-
|
|
246301
|
+
printJson4(withLocalTemplates(result, resolvedTemplates));
|
|
245496
246302
|
return;
|
|
245497
246303
|
}
|
|
245498
246304
|
const id = typeof result.id === "string" ? result.id : "?";
|
|
@@ -245515,7 +246321,7 @@ restore HEAD) return 404 — create a tagged copy first.
|
|
|
245515
246321
|
const { client, workflowId } = await buildClientForWorkflow(workflow, opts);
|
|
245516
246322
|
const result = await client.post(automationVersionsPath(workflowId, `/${encodeURIComponent(versionId)}/promote`));
|
|
245517
246323
|
if (opts.json) {
|
|
245518
|
-
|
|
246324
|
+
printJson4(result);
|
|
245519
246325
|
return;
|
|
245520
246326
|
}
|
|
245521
246327
|
const label = formatWorkflowVersionLabel(result.version);
|
|
@@ -245538,7 +246344,7 @@ promoted until you create a tagged copy.
|
|
|
245538
246344
|
const body = opts.message ? { message: opts.message } : {};
|
|
245539
246345
|
const result = await client.post(automationVersionsPath(workflowId, `/${encodeURIComponent(versionId)}/restore`), body);
|
|
245540
246346
|
if (opts.json) {
|
|
245541
|
-
|
|
246347
|
+
printJson4(result);
|
|
245542
246348
|
return;
|
|
245543
246349
|
}
|
|
245544
246350
|
const id = typeof result.id === "string" ? result.id : "?";
|
|
@@ -245787,7 +246593,7 @@ var HELP_GROUPS = [
|
|
|
245787
246593
|
{
|
|
245788
246594
|
title: "Authenticate",
|
|
245789
246595
|
description: "Profiles in ~/.config/eigenpal/credentials.json",
|
|
245790
|
-
commands: ["auth", "status", "models"]
|
|
246596
|
+
commands: ["auth", "status", "models", "email-servers"]
|
|
245791
246597
|
},
|
|
245792
246598
|
{
|
|
245793
246599
|
title: "Workflows",
|
|
@@ -246015,6 +246821,7 @@ authCmd.command("use [profile]").description("Switch the active profile (persist
|
|
|
246015
246821
|
registerWorkflowCommands(program2);
|
|
246016
246822
|
registerAgentCommands(program2);
|
|
246017
246823
|
registerModelsCommands(program2);
|
|
246824
|
+
registerEmailServersCommands(program2);
|
|
246018
246825
|
registerRunCommands(program2);
|
|
246019
246826
|
registerRunsCommands(program2);
|
|
246020
246827
|
registerGitCommands(program2);
|