@eigenpal/cli 0.5.9 → 0.5.11
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 +322 -8
- package/dist/skill/examples/hello-world/workflow.yaml +1 -1
- package/dist/skill/reference/workflow-yaml.md +6 -6
- package/dist/templates/blank/workflow.yaml +1 -2
- package/dist/templates/pdf-extraction/workflow.yaml +1 -1
- package/dist/templates/text-classification/workflow.yaml +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @eigenpal/cli
|
|
2
2
|
|
|
3
|
+
## 0.5.11
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 2958f4d: Fix Git-backed source smoke-test polish: hidden `git show` and `git sync` now accept bare agent slugs, and workflow scaffolds use the current `triggerMethods` YAML shape.
|
|
8
|
+
|
|
9
|
+
## 0.5.10
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- aee7e0c: Add hidden Git source commands for editing trigger policy and encrypted secrets.
|
|
14
|
+
|
|
3
15
|
## 0.5.9
|
|
4
16
|
|
|
5
17
|
### Major Changes
|
package/dist/cli.js
CHANGED
|
@@ -68021,7 +68021,63 @@ var init_eval = __esm(() => {
|
|
|
68021
68021
|
init_workflow_tool_metadata();
|
|
68022
68022
|
});
|
|
68023
68023
|
|
|
68024
|
+
// ../types/src/git-source/cutover.ts
|
|
68025
|
+
function resolveAgentSourceCutover(settings) {
|
|
68026
|
+
const parsed = AgentSourceCutoverSettingsSchema.safeParse(settings ?? {});
|
|
68027
|
+
if (!parsed.success)
|
|
68028
|
+
return { mode: "legacy", reason: "invalid_settings" };
|
|
68029
|
+
const agents = parsed.data.gitBackedSource?.agents;
|
|
68030
|
+
if (!agents)
|
|
68031
|
+
return { mode: "legacy", reason: "settings_missing" };
|
|
68032
|
+
if (agents.migrationState === "rolled_back")
|
|
68033
|
+
return { mode: "legacy", reason: "rolled_back" };
|
|
68034
|
+
if (agents.runtime !== "git")
|
|
68035
|
+
return { mode: "legacy", reason: "runtime_legacy" };
|
|
68036
|
+
if (agents.migrationState !== "cutover") {
|
|
68037
|
+
return { mode: "legacy", reason: "migration_not_cutover" };
|
|
68038
|
+
}
|
|
68039
|
+
return { mode: "git", reason: "cutover_enabled" };
|
|
68040
|
+
}
|
|
68041
|
+
function isGitBackedAgentSourceEnabled(settings) {
|
|
68042
|
+
return resolveAgentSourceCutover(settings).mode === "git";
|
|
68043
|
+
}
|
|
68044
|
+
var AgentSourceRuntimeModeSchema, AgentSourceMigrationStateSchema, AgentSourceCutoverSettingsSchema;
|
|
68045
|
+
var init_cutover = __esm(() => {
|
|
68046
|
+
init_zod();
|
|
68047
|
+
AgentSourceRuntimeModeSchema = exports_external.enum(["legacy", "git"]);
|
|
68048
|
+
AgentSourceMigrationStateSchema = exports_external.enum([
|
|
68049
|
+
"disabled",
|
|
68050
|
+
"shadow",
|
|
68051
|
+
"validated",
|
|
68052
|
+
"cutover",
|
|
68053
|
+
"rolled_back"
|
|
68054
|
+
]);
|
|
68055
|
+
AgentSourceCutoverSettingsSchema = exports_external.object({
|
|
68056
|
+
gitBackedSource: exports_external.object({
|
|
68057
|
+
agents: exports_external.object({
|
|
68058
|
+
runtime: AgentSourceRuntimeModeSchema.optional(),
|
|
68059
|
+
migrationState: AgentSourceMigrationStateSchema.optional(),
|
|
68060
|
+
legacySourceRetained: exports_external.boolean().optional(),
|
|
68061
|
+
rollbackReason: exports_external.string().optional()
|
|
68062
|
+
}).passthrough().optional()
|
|
68063
|
+
}).passthrough().optional()
|
|
68064
|
+
}).passthrough();
|
|
68065
|
+
});
|
|
68066
|
+
|
|
68024
68067
|
// ../types/src/git-source/grammar.ts
|
|
68068
|
+
function parseAutomationTarget(target) {
|
|
68069
|
+
const parsed = AutomationTargetSchema.parse(target);
|
|
68070
|
+
const [rawPackageName, rawRef] = parsed.split("@");
|
|
68071
|
+
const packagePath = dottedPackageNameToPath(rawPackageName);
|
|
68072
|
+
const [type, ...slugParts] = packagePath.split("/");
|
|
68073
|
+
return {
|
|
68074
|
+
packageName: DottedPackageNameSchema.parse(rawPackageName),
|
|
68075
|
+
packagePath,
|
|
68076
|
+
type,
|
|
68077
|
+
slug: slugParts.join("/"),
|
|
68078
|
+
ref: SourceVersionRefSchema.parse(rawRef ?? "latest")
|
|
68079
|
+
};
|
|
68080
|
+
}
|
|
68025
68081
|
function pathToDottedPackageName(path2) {
|
|
68026
68082
|
const parsed = SourcePackagePathSchema.parse(path2);
|
|
68027
68083
|
return DottedPackageNameSchema.parse(parsed.split("/").join("."));
|
|
@@ -68353,7 +68409,16 @@ var init_manifests = __esm(() => {
|
|
|
68353
68409
|
api: exports_external.boolean().optional(),
|
|
68354
68410
|
email: exports_external.object({
|
|
68355
68411
|
enabled: exports_external.boolean().default(true),
|
|
68356
|
-
aliases: exports_external.array(exports_external.
|
|
68412
|
+
aliases: exports_external.array(exports_external.union([
|
|
68413
|
+
exports_external.string().includes("@"),
|
|
68414
|
+
exports_external.object({
|
|
68415
|
+
address: exports_external.string().includes("@"),
|
|
68416
|
+
allowlist: exports_external.array(exports_external.string()).default([]),
|
|
68417
|
+
replyConfig: exports_external.record(exports_external.string(), exports_external.unknown()).default({}),
|
|
68418
|
+
requireSenderAuth: exports_external.boolean().default(true),
|
|
68419
|
+
enabled: exports_external.boolean().optional()
|
|
68420
|
+
}).strict()
|
|
68421
|
+
])).default([])
|
|
68357
68422
|
}).strict().optional()
|
|
68358
68423
|
}).strict();
|
|
68359
68424
|
CommonPackageManifestFields = {
|
|
@@ -68422,10 +68487,63 @@ var init_manifests = __esm(() => {
|
|
|
68422
68487
|
SOURCE_TEMPLATE_FILE_PATTERN = /\.(?:docx|xlsx)$/i;
|
|
68423
68488
|
});
|
|
68424
68489
|
|
|
68490
|
+
// ../types/src/git-source/secrets.ts
|
|
68491
|
+
var SOURCE_SECRETS_FILENAME = "secrets.enc.yaml", SecretNameSchema, Base64LikeSchema, EncryptedSecretValueSchema, SourceSecretEntrySchema, SourceSecretsFileSchema;
|
|
68492
|
+
var init_secrets = __esm(() => {
|
|
68493
|
+
init_zod();
|
|
68494
|
+
init_manifests();
|
|
68495
|
+
SecretNameSchema = exports_external.string().regex(/^[A-Z][A-Z0-9_]*$/, "Secret names must be uppercase env-style identifiers");
|
|
68496
|
+
Base64LikeSchema = exports_external.string().min(1).regex(/^[A-Za-z0-9+/=_-]+$/, {
|
|
68497
|
+
message: "Encrypted secret fields must be encoded strings"
|
|
68498
|
+
});
|
|
68499
|
+
EncryptedSecretValueSchema = exports_external.object({
|
|
68500
|
+
algorithm: exports_external.literal("aes-256-gcm"),
|
|
68501
|
+
keyId: exports_external.string().min(1),
|
|
68502
|
+
nonce: Base64LikeSchema,
|
|
68503
|
+
ciphertext: Base64LikeSchema,
|
|
68504
|
+
tag: Base64LikeSchema
|
|
68505
|
+
}).strict();
|
|
68506
|
+
SourceSecretEntrySchema = exports_external.object({
|
|
68507
|
+
description: exports_external.string().optional(),
|
|
68508
|
+
encrypted: EncryptedSecretValueSchema.optional()
|
|
68509
|
+
}).passthrough().superRefine((entry, ctx) => {
|
|
68510
|
+
const raw = entry;
|
|
68511
|
+
if ("value" in raw || "plaintext" in raw || "secret" in raw) {
|
|
68512
|
+
ctx.addIssue({
|
|
68513
|
+
code: "custom",
|
|
68514
|
+
message: "secrets.enc.yaml must not contain plaintext secret values"
|
|
68515
|
+
});
|
|
68516
|
+
}
|
|
68517
|
+
if (!raw.encrypted) {
|
|
68518
|
+
ctx.addIssue({
|
|
68519
|
+
code: "custom",
|
|
68520
|
+
path: ["encrypted"],
|
|
68521
|
+
message: "Encrypted secret values are required"
|
|
68522
|
+
});
|
|
68523
|
+
}
|
|
68524
|
+
const extraKeys = Object.keys(raw).filter((key) => key !== "description" && key !== "encrypted");
|
|
68525
|
+
for (const key of extraKeys) {
|
|
68526
|
+
if (key === "value" || key === "plaintext" || key === "secret")
|
|
68527
|
+
continue;
|
|
68528
|
+
ctx.addIssue({
|
|
68529
|
+
code: "custom",
|
|
68530
|
+
path: [key],
|
|
68531
|
+
message: `Unknown secret metadata field: ${key}`
|
|
68532
|
+
});
|
|
68533
|
+
}
|
|
68534
|
+
});
|
|
68535
|
+
SourceSecretsFileSchema = exports_external.object({
|
|
68536
|
+
schemaVersion: SourceManifestSchemaVersionSchema,
|
|
68537
|
+
secrets: exports_external.record(SecretNameSchema, SourceSecretEntrySchema)
|
|
68538
|
+
}).strict();
|
|
68539
|
+
});
|
|
68540
|
+
|
|
68425
68541
|
// ../types/src/git-source/index.ts
|
|
68426
68542
|
var init_git_source = __esm(() => {
|
|
68543
|
+
init_cutover();
|
|
68427
68544
|
init_grammar();
|
|
68428
68545
|
init_manifests();
|
|
68546
|
+
init_secrets();
|
|
68429
68547
|
});
|
|
68430
68548
|
|
|
68431
68549
|
// ../types/src/storage/paths.ts
|
|
@@ -68729,11 +68847,13 @@ __export(exports_src, {
|
|
|
68729
68847
|
runInputKey: () => runInputKey,
|
|
68730
68848
|
rootS3Path: () => rootS3Path,
|
|
68731
68849
|
resolveEffectiveMimeType: () => resolveEffectiveMimeType,
|
|
68850
|
+
resolveAgentSourceCutover: () => resolveAgentSourceCutover,
|
|
68732
68851
|
requiresSpecializedParser: () => requiresSpecializedParser,
|
|
68733
68852
|
pathToDottedPackageName: () => pathToDottedPackageName,
|
|
68734
68853
|
parseStepType: () => parseStepType,
|
|
68735
68854
|
parseReleaseTag: () => parseReleaseTag,
|
|
68736
68855
|
parseFileKey: () => parseFileKey,
|
|
68856
|
+
parseAutomationTarget: () => parseAutomationTarget,
|
|
68737
68857
|
noopTracingContext: () => noopTracingContext,
|
|
68738
68858
|
mapOCRAttributes: () => mapOCRAttributes,
|
|
68739
68859
|
mapLLMAttributes: () => mapLLMAttributes,
|
|
@@ -68748,6 +68868,7 @@ __export(exports_src, {
|
|
|
68748
68868
|
isOutputSchemaUnknown: () => isOutputSchemaUnknown,
|
|
68749
68869
|
isNonSuccessTerminalExecutionStatus: () => isNonSuccessTerminalExecutionStatus,
|
|
68750
68870
|
isLocalAgentResourcePath: () => isLocalAgentResourcePath,
|
|
68871
|
+
isGitBackedAgentSourceEnabled: () => isGitBackedAgentSourceEnabled,
|
|
68751
68872
|
isFilePathDescriptor: () => isFilePathDescriptor,
|
|
68752
68873
|
isFileOutput: () => isFileOutput,
|
|
68753
68874
|
hasTriggerMethod: () => hasTriggerMethod,
|
|
@@ -68863,6 +68984,7 @@ __export(exports_src, {
|
|
|
68863
68984
|
SpanKindMap: () => SpanKindMap,
|
|
68864
68985
|
SpanKind: () => import_api.SpanKind,
|
|
68865
68986
|
SourceVersionRefSchema: () => SourceVersionRefSchema,
|
|
68987
|
+
SourceSecretsFileSchema: () => SourceSecretsFileSchema,
|
|
68866
68988
|
SourcePackageTypeSchema: () => SourcePackageTypeSchema,
|
|
68867
68989
|
SourcePackageSegmentSchema: () => SourcePackageSegmentSchema,
|
|
68868
68990
|
SourcePackagePathSchema: () => SourcePackagePathSchema,
|
|
@@ -68872,6 +68994,7 @@ __export(exports_src, {
|
|
|
68872
68994
|
SharedResourcePackageManifestSchema: () => SharedResourcePackageManifestSchema,
|
|
68873
68995
|
SharedEvaluatorReferenceSchema: () => SharedEvaluatorReferenceSchema,
|
|
68874
68996
|
SharedEvaluatorCompositionItemSchema: () => SharedEvaluatorCompositionItemSchema,
|
|
68997
|
+
SecretNameSchema: () => SecretNameSchema,
|
|
68875
68998
|
ScopeStackSchema: () => ScopeStackSchema,
|
|
68876
68999
|
ScopeEntryTypeSchema: () => ScopeEntryTypeSchema,
|
|
68877
69000
|
ScopeEntrySchema: () => ScopeEntrySchema,
|
|
@@ -68880,6 +69003,7 @@ __export(exports_src, {
|
|
|
68880
69003
|
STEP_EXECUTION_STATUSES: () => STEP_EXECUTION_STATUSES,
|
|
68881
69004
|
SOURCE_VERSION_RANGE_PATTERN: () => SOURCE_VERSION_RANGE_PATTERN,
|
|
68882
69005
|
SOURCE_SEMVER_PATTERN: () => SOURCE_SEMVER_PATTERN,
|
|
69006
|
+
SOURCE_SECRETS_FILENAME: () => SOURCE_SECRETS_FILENAME,
|
|
68883
69007
|
SOURCE_PACKAGE_SEGMENT_PATTERN: () => SOURCE_PACKAGE_SEGMENT_PATTERN,
|
|
68884
69008
|
SOURCE_MANIFEST_FILENAME: () => SOURCE_MANIFEST_FILENAME,
|
|
68885
69009
|
SOURCE_COMMIT_SHA_PATTERN: () => SOURCE_COMMIT_SHA_PATTERN,
|
|
@@ -68963,6 +69087,7 @@ __export(exports_src, {
|
|
|
68963
69087
|
EvalOverridesSchema: () => EvalOverridesSchema,
|
|
68964
69088
|
EvalExampleMetaSchema: () => EvalExampleMetaSchema,
|
|
68965
69089
|
EvalConfigYamlSchema: () => EvalConfigYamlSchema,
|
|
69090
|
+
EncryptedSecretValueSchema: () => EncryptedSecretValueSchema,
|
|
68966
69091
|
EmailTriggerMethodSchema: () => EmailTriggerMethodSchema,
|
|
68967
69092
|
Eigenpal: () => Eigenpal,
|
|
68968
69093
|
EXECUTION_TYPES: () => EXECUTION_TYPES,
|
|
@@ -69025,6 +69150,9 @@ __export(exports_src, {
|
|
|
69025
69150
|
AiParseConfigSchema: () => AiParseConfigSchema,
|
|
69026
69151
|
AiExtractOutputSchema: () => AiExtractOutputSchema,
|
|
69027
69152
|
AiExtractConfigSchema: () => AiExtractConfigSchema,
|
|
69153
|
+
AgentSourceRuntimeModeSchema: () => AgentSourceRuntimeModeSchema,
|
|
69154
|
+
AgentSourceMigrationStateSchema: () => AgentSourceMigrationStateSchema,
|
|
69155
|
+
AgentSourceCutoverSettingsSchema: () => AgentSourceCutoverSettingsSchema,
|
|
69028
69156
|
AgentPackageManifestSchema: () => AgentPackageManifestSchema,
|
|
69029
69157
|
ActionTypeValue: () => ActionTypeValue,
|
|
69030
69158
|
ActionTypeSchema: () => ActionTypeSchema,
|
|
@@ -181610,7 +181738,7 @@ import { fileURLToPath as fileURLToPath6 } from "url";
|
|
|
181610
181738
|
// package.json
|
|
181611
181739
|
var package_default = {
|
|
181612
181740
|
name: "@eigenpal/cli",
|
|
181613
|
-
version: "0.5.
|
|
181741
|
+
version: "0.5.11",
|
|
181614
181742
|
description: "Eigenpal CLI — author and run document workflows from your terminal. Agent-ready.",
|
|
181615
181743
|
keywords: [
|
|
181616
181744
|
"eigenpal",
|
|
@@ -184117,7 +184245,7 @@ init_src();
|
|
|
184117
184245
|
init_zod();
|
|
184118
184246
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
184119
184247
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
184120
|
-
import { createHash as createHash2 } from "node:crypto";
|
|
184248
|
+
import { createCipheriv, createHash as createHash2, randomBytes } from "node:crypto";
|
|
184121
184249
|
import {
|
|
184122
184250
|
existsSync as existsSync3,
|
|
184123
184251
|
mkdirSync as mkdirSync2,
|
|
@@ -184280,6 +184408,9 @@ function listRelativeFiles(dir) {
|
|
|
184280
184408
|
function readYamlFile(filePath) {
|
|
184281
184409
|
return import_yaml2.default.parse(readFileSync3(filePath, "utf8"));
|
|
184282
184410
|
}
|
|
184411
|
+
function writeYamlFile(filePath, value) {
|
|
184412
|
+
writeFileSync2(filePath, import_yaml2.default.stringify(value));
|
|
184413
|
+
}
|
|
184283
184414
|
function packageManifestExists(gitRoot, packagePath) {
|
|
184284
184415
|
return existsSync3(path2.join(gitRoot, packagePath, "eigenpal.yaml"));
|
|
184285
184416
|
}
|
|
@@ -184290,6 +184421,28 @@ function releaseTagExists(gitRoot, packagePath, version2) {
|
|
|
184290
184421
|
function readPackageManifest(packageRoot) {
|
|
184291
184422
|
return SourcePackageManifestSchema.parse(readYamlFile(path2.join(packageRoot, "eigenpal.yaml")));
|
|
184292
184423
|
}
|
|
184424
|
+
function requirePackageContext(opts = {}) {
|
|
184425
|
+
const context = resolveGitSourceContext(opts);
|
|
184426
|
+
if (!context.gitRoot || !context.packageRoot || !context.packagePath) {
|
|
184427
|
+
throw new Error("Run this command inside a source package, or pass --dir.");
|
|
184428
|
+
}
|
|
184429
|
+
return {
|
|
184430
|
+
gitRoot: context.gitRoot,
|
|
184431
|
+
packageRoot: context.packageRoot,
|
|
184432
|
+
packagePath: context.packagePath
|
|
184433
|
+
};
|
|
184434
|
+
}
|
|
184435
|
+
function readMutablePackageManifest(packageRoot) {
|
|
184436
|
+
const manifest = readYamlFile(path2.join(packageRoot, "eigenpal.yaml"));
|
|
184437
|
+
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
184438
|
+
throw new Error("Package eigenpal.yaml must be a YAML object.");
|
|
184439
|
+
}
|
|
184440
|
+
return manifest;
|
|
184441
|
+
}
|
|
184442
|
+
function writeMutablePackageManifest(packageRoot, manifest) {
|
|
184443
|
+
SourcePackageManifestSchema.parse(manifest);
|
|
184444
|
+
writeYamlFile(path2.join(packageRoot, "eigenpal.yaml"), manifest);
|
|
184445
|
+
}
|
|
184293
184446
|
function parsePackageRef(input) {
|
|
184294
184447
|
const [rawPackage, rawRef, extra] = input.split("@");
|
|
184295
184448
|
if (!rawPackage || extra !== undefined) {
|
|
@@ -184631,6 +184784,11 @@ function checkRepoVersion(gitRoot, mutation) {
|
|
|
184631
184784
|
function resolvePackagePath(target) {
|
|
184632
184785
|
return target.includes("/") ? SourcePackagePathSchema.parse(target) : dottedPackageNameToPath(DottedPackageNameSchema.parse(target));
|
|
184633
184786
|
}
|
|
184787
|
+
function resolveAgentPackagePath(target) {
|
|
184788
|
+
if (target.includes("/") || target.includes("."))
|
|
184789
|
+
return resolvePackagePath(target);
|
|
184790
|
+
return SourcePackagePathSchema.parse(`agents/${target}`);
|
|
184791
|
+
}
|
|
184634
184792
|
function isAutomationPackagePath(packagePath) {
|
|
184635
184793
|
return packagePath.startsWith("agents/") || packagePath.startsWith("workflows/");
|
|
184636
184794
|
}
|
|
@@ -184976,7 +185134,7 @@ async function list(opts) {
|
|
|
184976
185134
|
}
|
|
184977
185135
|
}
|
|
184978
185136
|
async function show(target, opts) {
|
|
184979
|
-
const packagePath =
|
|
185137
|
+
const packagePath = resolveAgentPackagePath(target);
|
|
184980
185138
|
const slug = packagePath.replace(/^agents\//, "");
|
|
184981
185139
|
const client = new ApiClient(resolveConfig(opts));
|
|
184982
185140
|
const payload = await client.get(`/api/v1/agents/${encodeURIComponent(slug)}`, {
|
|
@@ -185089,7 +185247,7 @@ async function sync(target, opts) {
|
|
|
185089
185247
|
if (target?.includes("@")) {
|
|
185090
185248
|
throw new Error("Sync always uses latest; do not pass a versioned target.");
|
|
185091
185249
|
}
|
|
185092
|
-
const packagePath = target ?
|
|
185250
|
+
const packagePath = target ? resolveAgentPackagePath(target) : context.packagePath;
|
|
185093
185251
|
if (!packagePath) {
|
|
185094
185252
|
throw new Error("Pass an automation target or run sync inside a source package.");
|
|
185095
185253
|
}
|
|
@@ -185098,6 +185256,144 @@ async function sync(target, opts) {
|
|
|
185098
185256
|
}
|
|
185099
185257
|
await syncLatestAutomation(new ApiClient(resolveConfig(opts)), packagePath);
|
|
185100
185258
|
}
|
|
185259
|
+
function setEmailTriggerAlias(email3, opts) {
|
|
185260
|
+
const context = requirePackageContext(opts);
|
|
185261
|
+
const manifest = readMutablePackageManifest(context.packageRoot);
|
|
185262
|
+
const triggers = { ...manifest.triggers ?? {} };
|
|
185263
|
+
const emailConfig = { ...triggers.email ?? {} };
|
|
185264
|
+
const aliases = Array.isArray(emailConfig.aliases) ? [...emailConfig.aliases] : [];
|
|
185265
|
+
const nextAlias = {
|
|
185266
|
+
address: email3,
|
|
185267
|
+
enabled: !opts.disabled,
|
|
185268
|
+
allowlist: opts.allow ?? [],
|
|
185269
|
+
replyConfig: {
|
|
185270
|
+
...opts.replyOn ? { on: opts.replyOn } : {},
|
|
185271
|
+
...opts.replyMode ? { mode: opts.replyMode } : {}
|
|
185272
|
+
},
|
|
185273
|
+
requireSenderAuth: opts.requireSenderAuth ?? true
|
|
185274
|
+
};
|
|
185275
|
+
const filtered = aliases.filter((alias) => typeof alias === "string" ? alias.toLowerCase() !== email3.toLowerCase() : alias.address?.toLowerCase() !== email3.toLowerCase());
|
|
185276
|
+
manifest.triggers = {
|
|
185277
|
+
...triggers,
|
|
185278
|
+
email: { ...emailConfig, enabled: true, aliases: [...filtered, nextAlias] }
|
|
185279
|
+
};
|
|
185280
|
+
writeMutablePackageManifest(context.packageRoot, manifest);
|
|
185281
|
+
success2(`Updated email trigger ${ui.bold(email3)} in eigenpal.yaml.`);
|
|
185282
|
+
}
|
|
185283
|
+
function setApiTrigger(enabled, opts) {
|
|
185284
|
+
const context = requirePackageContext(opts);
|
|
185285
|
+
const manifest = readMutablePackageManifest(context.packageRoot);
|
|
185286
|
+
const triggers = { ...manifest.triggers ?? {} };
|
|
185287
|
+
manifest.triggers = { ...triggers, api: enabled };
|
|
185288
|
+
writeMutablePackageManifest(context.packageRoot, manifest);
|
|
185289
|
+
success2(`${enabled ? "Enabled" : "Disabled"} API trigger in eigenpal.yaml.`);
|
|
185290
|
+
}
|
|
185291
|
+
function encryptLocalSecret(input) {
|
|
185292
|
+
if (input.key.byteLength !== 32)
|
|
185293
|
+
throw new Error("Secret encryption key must be 32 bytes.");
|
|
185294
|
+
const nonce = randomBytes(12);
|
|
185295
|
+
const cipher = createCipheriv("aes-256-gcm", input.key, nonce);
|
|
185296
|
+
cipher.setAAD(Buffer.from(JSON.stringify({
|
|
185297
|
+
keyId: input.keyId,
|
|
185298
|
+
organizationId: input.organizationId,
|
|
185299
|
+
sourcePath: input.sourcePath,
|
|
185300
|
+
secretName: input.secretName
|
|
185301
|
+
})));
|
|
185302
|
+
const ciphertext = Buffer.concat([cipher.update(input.plaintext, "utf8"), cipher.final()]);
|
|
185303
|
+
return {
|
|
185304
|
+
algorithm: "aes-256-gcm",
|
|
185305
|
+
keyId: input.keyId,
|
|
185306
|
+
nonce: nonce.toString("base64url"),
|
|
185307
|
+
ciphertext: ciphertext.toString("base64url"),
|
|
185308
|
+
tag: cipher.getAuthTag().toString("base64url")
|
|
185309
|
+
};
|
|
185310
|
+
}
|
|
185311
|
+
function readSecretsFile(packageRoot) {
|
|
185312
|
+
const filePath = path2.join(packageRoot, SOURCE_SECRETS_FILENAME);
|
|
185313
|
+
if (!existsSync3(filePath))
|
|
185314
|
+
return { schemaVersion: 1, secrets: {} };
|
|
185315
|
+
return SourceSecretsFileSchema.parse(readYamlFile(filePath));
|
|
185316
|
+
}
|
|
185317
|
+
function writeSecretsFile(packageRoot, value) {
|
|
185318
|
+
const secretsFile = SourceSecretsFileSchema.parse(value);
|
|
185319
|
+
writeYamlFile(path2.join(packageRoot, SOURCE_SECRETS_FILENAME), secretsFile);
|
|
185320
|
+
}
|
|
185321
|
+
async function readSecretInput(opts) {
|
|
185322
|
+
const selected = [opts.stdin, opts.valueFile].filter(Boolean).length;
|
|
185323
|
+
if (selected > 1)
|
|
185324
|
+
throw new Error("Pass only one of --stdin or --value-file.");
|
|
185325
|
+
if (opts.stdin)
|
|
185326
|
+
return readFileSync3(0, "utf8").replace(/\n$/, "");
|
|
185327
|
+
if (opts.valueFile)
|
|
185328
|
+
return readFileSync3(opts.valueFile, "utf8").replace(/\n$/, "");
|
|
185329
|
+
if (process.stdin.isTTY && process.stdout.isTTY) {
|
|
185330
|
+
const { password, isCancel, cancel } = await Promise.resolve().then(() => (init_dist4(), exports_dist));
|
|
185331
|
+
const answer = await password({ message: "Secret value" });
|
|
185332
|
+
if (isCancel(answer)) {
|
|
185333
|
+
cancel("Cancelled");
|
|
185334
|
+
process.exit(1);
|
|
185335
|
+
}
|
|
185336
|
+
return String(answer);
|
|
185337
|
+
}
|
|
185338
|
+
throw new Error("Secret value input is required in noninteractive mode.");
|
|
185339
|
+
}
|
|
185340
|
+
async function setSecret(name, opts) {
|
|
185341
|
+
const context = requirePackageContext(opts);
|
|
185342
|
+
const sourcePath = `${context.packagePath}/${SOURCE_SECRETS_FILENAME}`;
|
|
185343
|
+
const secretsFile = readSecretsFile(context.packageRoot);
|
|
185344
|
+
const secrets = { ...secretsFile.secrets };
|
|
185345
|
+
secrets[name] = {
|
|
185346
|
+
...opts.description ? { description: opts.description } : {},
|
|
185347
|
+
encrypted: encryptLocalSecret({
|
|
185348
|
+
plaintext: await readSecretInput(opts),
|
|
185349
|
+
keyId: opts.keyId,
|
|
185350
|
+
key: readSecretKeyFile(opts.keyFile),
|
|
185351
|
+
organizationId: opts.organizationId,
|
|
185352
|
+
sourcePath,
|
|
185353
|
+
secretName: name
|
|
185354
|
+
})
|
|
185355
|
+
};
|
|
185356
|
+
writeSecretsFile(context.packageRoot, { schemaVersion: 1, secrets });
|
|
185357
|
+
success2(`Encrypted ${ui.bold(name)} into secrets.enc.yaml.`);
|
|
185358
|
+
}
|
|
185359
|
+
function unsetSecret(name, opts) {
|
|
185360
|
+
const context = requirePackageContext(opts);
|
|
185361
|
+
const secretsFile = readSecretsFile(context.packageRoot);
|
|
185362
|
+
const secrets = { ...secretsFile.secrets };
|
|
185363
|
+
delete secrets[name];
|
|
185364
|
+
writeSecretsFile(context.packageRoot, { schemaVersion: 1, secrets });
|
|
185365
|
+
success2(`Removed ${ui.bold(name)} from secrets.enc.yaml.`);
|
|
185366
|
+
}
|
|
185367
|
+
async function importSecrets(envFile, opts) {
|
|
185368
|
+
const content = readFileSync3(envFile, "utf8");
|
|
185369
|
+
for (const line of content.split(/\r?\n/)) {
|
|
185370
|
+
const trimmed = line.trim();
|
|
185371
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
185372
|
+
continue;
|
|
185373
|
+
const idx = trimmed.indexOf("=");
|
|
185374
|
+
if (idx === -1)
|
|
185375
|
+
continue;
|
|
185376
|
+
const context = requirePackageContext(opts);
|
|
185377
|
+
const sourcePath = `${context.packagePath}/${SOURCE_SECRETS_FILENAME}`;
|
|
185378
|
+
const secretsFile = readSecretsFile(context.packageRoot);
|
|
185379
|
+
const secrets = { ...secretsFile.secrets };
|
|
185380
|
+
const name = trimmed.slice(0, idx);
|
|
185381
|
+
secrets[name] = {
|
|
185382
|
+
encrypted: encryptLocalSecret({
|
|
185383
|
+
plaintext: trimmed.slice(idx + 1),
|
|
185384
|
+
keyId: opts.keyId,
|
|
185385
|
+
key: readSecretKeyFile(opts.keyFile),
|
|
185386
|
+
organizationId: opts.organizationId,
|
|
185387
|
+
sourcePath,
|
|
185388
|
+
secretName: name
|
|
185389
|
+
})
|
|
185390
|
+
};
|
|
185391
|
+
writeSecretsFile(context.packageRoot, { schemaVersion: 1, secrets });
|
|
185392
|
+
}
|
|
185393
|
+
}
|
|
185394
|
+
function readSecretKeyFile(keyFile) {
|
|
185395
|
+
return Buffer.from(readFileSync3(keyFile, "utf8").trim(), "base64url");
|
|
185396
|
+
}
|
|
185101
185397
|
async function install(packageRef, opts) {
|
|
185102
185398
|
const config2 = resolveConfig(opts);
|
|
185103
185399
|
const context = resolveGitSourceContext();
|
|
@@ -185401,6 +185697,16 @@ function parseReleaseVersion(value) {
|
|
|
185401
185697
|
}
|
|
185402
185698
|
return value;
|
|
185403
185699
|
}
|
|
185700
|
+
function parseBoolean(value) {
|
|
185701
|
+
if (value === "true" || value === "enabled" || value === "on")
|
|
185702
|
+
return true;
|
|
185703
|
+
if (value === "false" || value === "disabled" || value === "off")
|
|
185704
|
+
return false;
|
|
185705
|
+
throw new InvalidArgumentError("Expected true/false, enabled/disabled, or on/off");
|
|
185706
|
+
}
|
|
185707
|
+
function collect2(value, previous) {
|
|
185708
|
+
return [...previous, value];
|
|
185709
|
+
}
|
|
185404
185710
|
function parseType(value) {
|
|
185405
185711
|
if (!["agent", "workflow"].includes(value))
|
|
185406
185712
|
throw new InvalidArgumentError("type must be agent or workflow");
|
|
@@ -185431,6 +185737,14 @@ function registerGitCommands(program2) {
|
|
|
185431
185737
|
addJsonFlag(withBaseUrl(git.command("versions <package>"))).description("List package release versions.").action(action(versions2));
|
|
185432
185738
|
withBaseUrl(git.command("release")).description("Create and push a package release tag.").argument("<version>", "Version or bump level", parseReleaseVersion).argument("[dir]", "Package directory").addOption(new Option("-m, --message <message>", "Annotated tag message").makeOptionMandatory()).action(action(async (versionOrBump, dir, opts) => release(versionOrBump, dir, opts)));
|
|
185433
185739
|
withBaseUrl(git.command("sync [automation]")).description("Sync an automation from the latest Git source release.").option("--dir <dir>", "Directory to inspect").action(action(sync));
|
|
185740
|
+
const trigger = git.command("trigger").description("Edit trigger policy in eigenpal.yaml.");
|
|
185741
|
+
trigger.command("api <enabled>").description("Enable or disable API trigger policy in eigenpal.yaml.").option("--dir <dir>", "Directory to inspect").action(action(async (enabled, opts) => setApiTrigger(parseBoolean(enabled), opts)));
|
|
185742
|
+
const triggerEmail = trigger.command("email").description("Edit email trigger policy.");
|
|
185743
|
+
triggerEmail.command("set <email>").description("Add or update an email trigger alias in eigenpal.yaml.").option("--dir <dir>", "Directory to inspect").option("--disabled", "Write the alias as disabled").option("--allow <entry>", "Allowed sender entry; repeatable", collect2, []).option("--reply-on <never|always>", "Reply behavior").option("--reply-mode <sender|all>", "Reply recipient mode").option("--no-require-sender-auth", "Disable sender-auth checks for this alias").action(action(async (email3, opts) => setEmailTriggerAlias(email3, opts)));
|
|
185744
|
+
const secret = git.command("secret").description("Edit encrypted secrets.enc.yaml.");
|
|
185745
|
+
secret.command("set <name>").description("Encrypt and set a secret value in secrets.enc.yaml.").option("--dir <dir>", "Directory to inspect").option("--stdin", "Read the secret value from stdin").option("--value-file <path>", "Read the secret value from a file").requiredOption("--key-id <id>", "Organization decrypt key id").requiredOption("--key-file <path>", "File containing the base64url-encoded organization key").requiredOption("--organization-id <id>", "Organization id for authenticated data").option("--description <text>", "Secret description").action(action(setSecret));
|
|
185746
|
+
secret.command("unset <name>").description("Remove a secret from secrets.enc.yaml.").option("--dir <dir>", "Directory to inspect").action(action(async (name, opts) => unsetSecret(name, opts)));
|
|
185747
|
+
secret.command("import <env-file>").description("Import KEY=value entries from an env file into secrets.enc.yaml.").option("--dir <dir>", "Directory to inspect").requiredOption("--key-id <id>", "Organization decrypt key id").requiredOption("--key-file <path>", "File containing the base64url-encoded organization key").requiredOption("--organization-id <id>", "Organization id for authenticated data").action(action(importSecrets));
|
|
185434
185748
|
}
|
|
185435
185749
|
|
|
185436
185750
|
// src/commands/init.ts
|
|
@@ -186029,15 +186343,15 @@ function pruneEmptyDirs(root) {
|
|
|
186029
186343
|
if (!existsSync5(root))
|
|
186030
186344
|
return;
|
|
186031
186345
|
const stack = [];
|
|
186032
|
-
const
|
|
186346
|
+
const collect3 = (dir) => {
|
|
186033
186347
|
for (const entry of readdirSync3(dir)) {
|
|
186034
186348
|
const full = join3(dir, entry);
|
|
186035
186349
|
if (lstatSync(full).isDirectory())
|
|
186036
|
-
|
|
186350
|
+
collect3(full);
|
|
186037
186351
|
}
|
|
186038
186352
|
stack.push(dir);
|
|
186039
186353
|
};
|
|
186040
|
-
|
|
186354
|
+
collect3(root);
|
|
186041
186355
|
for (const dir of stack) {
|
|
186042
186356
|
try {
|
|
186043
186357
|
if (readdirSync3(dir).length === 0)
|
|
@@ -16,7 +16,7 @@ eigenpal workflow step-type get <type> # JSON Schema for one type's config + o
|
|
|
16
16
|
name: extract-invoices # string, lowercase kebab/snake-case, unique within tenant
|
|
17
17
|
version: 1.0.0 # bare semver `MAJOR.MINOR.PATCH`, no leading `v`
|
|
18
18
|
description: Parse a PDF and extract invoice fields. # string, optional
|
|
19
|
-
triggerMethods: [api] # array, ≥1 entry
|
|
19
|
+
triggerMethods: [{ type: api }] # array, ≥1 entry with type: api | manual | email
|
|
20
20
|
inputs: [...] # array of input definitions (see below)
|
|
21
21
|
steps: [...] # array of steps, executed in topological order
|
|
22
22
|
output: {...} # object — the workflow's return shape
|
|
@@ -36,13 +36,13 @@ folder.
|
|
|
36
36
|
|
|
37
37
|
### `triggerMethods`
|
|
38
38
|
|
|
39
|
-
Required. Each entry adds an invocation surface:
|
|
39
|
+
Required. Each entry is an object that adds an invocation surface:
|
|
40
40
|
|
|
41
|
-
- `api` — the workflow can be called via REST or the CLI's `workflow execution run`
|
|
42
|
-
- `
|
|
43
|
-
- `
|
|
41
|
+
- `{ type: api }` — the workflow can be called via REST or the CLI's `workflow execution run`
|
|
42
|
+
- `{ type: manual }` — the workflow can be started manually
|
|
43
|
+
- `{ type: email, whitelist?: ... }` — inbound email
|
|
44
44
|
|
|
45
|
-
If `api` is missing, `eigenpal workflow execution run`
|
|
45
|
+
If `{ type: api }` is missing, `eigenpal workflow execution run` rejects with a
|
|
46
46
|
403 / "Workflow does not have API trigger enabled."
|
|
47
47
|
|
|
48
48
|
### `inputs`
|
|
@@ -4,9 +4,8 @@ description: Replace this with what your workflow does.
|
|
|
4
4
|
|
|
5
5
|
# `triggerMethods` controls how this workflow can be invoked:
|
|
6
6
|
# - api: workflow can be called via the REST API and CLI
|
|
7
|
-
# - cron: workflow can be scheduled (set `cron` field below)
|
|
8
7
|
triggerMethods:
|
|
9
|
-
- api
|
|
8
|
+
- type: api
|
|
10
9
|
|
|
11
10
|
# `inputs` declares the schema of arguments the workflow accepts. Each entry
|
|
12
11
|
# becomes a top-level key on the call's `triggerInput` object. Use `file: true`
|