@eigenpal/cli 0.5.9 → 0.5.10

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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @eigenpal/cli
2
2
 
3
+ ## 0.5.10
4
+
5
+ ### Patch Changes
6
+
7
+ - aee7e0c: Add hidden Git source commands for editing trigger policy and encrypted secrets.
8
+
3
9
  ## 0.5.9
4
10
 
5
11
  ### 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.string().email()).default([])
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.9",
181741
+ version: "0.5.10",
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) {
@@ -185098,6 +185251,144 @@ async function sync(target, opts) {
185098
185251
  }
185099
185252
  await syncLatestAutomation(new ApiClient(resolveConfig(opts)), packagePath);
185100
185253
  }
185254
+ function setEmailTriggerAlias(email3, opts) {
185255
+ const context = requirePackageContext(opts);
185256
+ const manifest = readMutablePackageManifest(context.packageRoot);
185257
+ const triggers = { ...manifest.triggers ?? {} };
185258
+ const emailConfig = { ...triggers.email ?? {} };
185259
+ const aliases = Array.isArray(emailConfig.aliases) ? [...emailConfig.aliases] : [];
185260
+ const nextAlias = {
185261
+ address: email3,
185262
+ enabled: !opts.disabled,
185263
+ allowlist: opts.allow ?? [],
185264
+ replyConfig: {
185265
+ ...opts.replyOn ? { on: opts.replyOn } : {},
185266
+ ...opts.replyMode ? { mode: opts.replyMode } : {}
185267
+ },
185268
+ requireSenderAuth: opts.requireSenderAuth ?? true
185269
+ };
185270
+ const filtered = aliases.filter((alias) => typeof alias === "string" ? alias.toLowerCase() !== email3.toLowerCase() : alias.address?.toLowerCase() !== email3.toLowerCase());
185271
+ manifest.triggers = {
185272
+ ...triggers,
185273
+ email: { ...emailConfig, enabled: true, aliases: [...filtered, nextAlias] }
185274
+ };
185275
+ writeMutablePackageManifest(context.packageRoot, manifest);
185276
+ success2(`Updated email trigger ${ui.bold(email3)} in eigenpal.yaml.`);
185277
+ }
185278
+ function setApiTrigger(enabled, opts) {
185279
+ const context = requirePackageContext(opts);
185280
+ const manifest = readMutablePackageManifest(context.packageRoot);
185281
+ const triggers = { ...manifest.triggers ?? {} };
185282
+ manifest.triggers = { ...triggers, api: enabled };
185283
+ writeMutablePackageManifest(context.packageRoot, manifest);
185284
+ success2(`${enabled ? "Enabled" : "Disabled"} API trigger in eigenpal.yaml.`);
185285
+ }
185286
+ function encryptLocalSecret(input) {
185287
+ if (input.key.byteLength !== 32)
185288
+ throw new Error("Secret encryption key must be 32 bytes.");
185289
+ const nonce = randomBytes(12);
185290
+ const cipher = createCipheriv("aes-256-gcm", input.key, nonce);
185291
+ cipher.setAAD(Buffer.from(JSON.stringify({
185292
+ keyId: input.keyId,
185293
+ organizationId: input.organizationId,
185294
+ sourcePath: input.sourcePath,
185295
+ secretName: input.secretName
185296
+ })));
185297
+ const ciphertext = Buffer.concat([cipher.update(input.plaintext, "utf8"), cipher.final()]);
185298
+ return {
185299
+ algorithm: "aes-256-gcm",
185300
+ keyId: input.keyId,
185301
+ nonce: nonce.toString("base64url"),
185302
+ ciphertext: ciphertext.toString("base64url"),
185303
+ tag: cipher.getAuthTag().toString("base64url")
185304
+ };
185305
+ }
185306
+ function readSecretsFile(packageRoot) {
185307
+ const filePath = path2.join(packageRoot, SOURCE_SECRETS_FILENAME);
185308
+ if (!existsSync3(filePath))
185309
+ return { schemaVersion: 1, secrets: {} };
185310
+ return SourceSecretsFileSchema.parse(readYamlFile(filePath));
185311
+ }
185312
+ function writeSecretsFile(packageRoot, value) {
185313
+ const secretsFile = SourceSecretsFileSchema.parse(value);
185314
+ writeYamlFile(path2.join(packageRoot, SOURCE_SECRETS_FILENAME), secretsFile);
185315
+ }
185316
+ async function readSecretInput(opts) {
185317
+ const selected = [opts.stdin, opts.valueFile].filter(Boolean).length;
185318
+ if (selected > 1)
185319
+ throw new Error("Pass only one of --stdin or --value-file.");
185320
+ if (opts.stdin)
185321
+ return readFileSync3(0, "utf8").replace(/\n$/, "");
185322
+ if (opts.valueFile)
185323
+ return readFileSync3(opts.valueFile, "utf8").replace(/\n$/, "");
185324
+ if (process.stdin.isTTY && process.stdout.isTTY) {
185325
+ const { password, isCancel, cancel } = await Promise.resolve().then(() => (init_dist4(), exports_dist));
185326
+ const answer = await password({ message: "Secret value" });
185327
+ if (isCancel(answer)) {
185328
+ cancel("Cancelled");
185329
+ process.exit(1);
185330
+ }
185331
+ return String(answer);
185332
+ }
185333
+ throw new Error("Secret value input is required in noninteractive mode.");
185334
+ }
185335
+ async function setSecret(name, opts) {
185336
+ const context = requirePackageContext(opts);
185337
+ const sourcePath = `${context.packagePath}/${SOURCE_SECRETS_FILENAME}`;
185338
+ const secretsFile = readSecretsFile(context.packageRoot);
185339
+ const secrets = { ...secretsFile.secrets };
185340
+ secrets[name] = {
185341
+ ...opts.description ? { description: opts.description } : {},
185342
+ encrypted: encryptLocalSecret({
185343
+ plaintext: await readSecretInput(opts),
185344
+ keyId: opts.keyId,
185345
+ key: readSecretKeyFile(opts.keyFile),
185346
+ organizationId: opts.organizationId,
185347
+ sourcePath,
185348
+ secretName: name
185349
+ })
185350
+ };
185351
+ writeSecretsFile(context.packageRoot, { schemaVersion: 1, secrets });
185352
+ success2(`Encrypted ${ui.bold(name)} into secrets.enc.yaml.`);
185353
+ }
185354
+ function unsetSecret(name, opts) {
185355
+ const context = requirePackageContext(opts);
185356
+ const secretsFile = readSecretsFile(context.packageRoot);
185357
+ const secrets = { ...secretsFile.secrets };
185358
+ delete secrets[name];
185359
+ writeSecretsFile(context.packageRoot, { schemaVersion: 1, secrets });
185360
+ success2(`Removed ${ui.bold(name)} from secrets.enc.yaml.`);
185361
+ }
185362
+ async function importSecrets(envFile, opts) {
185363
+ const content = readFileSync3(envFile, "utf8");
185364
+ for (const line of content.split(/\r?\n/)) {
185365
+ const trimmed = line.trim();
185366
+ if (!trimmed || trimmed.startsWith("#"))
185367
+ continue;
185368
+ const idx = trimmed.indexOf("=");
185369
+ if (idx === -1)
185370
+ continue;
185371
+ const context = requirePackageContext(opts);
185372
+ const sourcePath = `${context.packagePath}/${SOURCE_SECRETS_FILENAME}`;
185373
+ const secretsFile = readSecretsFile(context.packageRoot);
185374
+ const secrets = { ...secretsFile.secrets };
185375
+ const name = trimmed.slice(0, idx);
185376
+ secrets[name] = {
185377
+ encrypted: encryptLocalSecret({
185378
+ plaintext: trimmed.slice(idx + 1),
185379
+ keyId: opts.keyId,
185380
+ key: readSecretKeyFile(opts.keyFile),
185381
+ organizationId: opts.organizationId,
185382
+ sourcePath,
185383
+ secretName: name
185384
+ })
185385
+ };
185386
+ writeSecretsFile(context.packageRoot, { schemaVersion: 1, secrets });
185387
+ }
185388
+ }
185389
+ function readSecretKeyFile(keyFile) {
185390
+ return Buffer.from(readFileSync3(keyFile, "utf8").trim(), "base64url");
185391
+ }
185101
185392
  async function install(packageRef, opts) {
185102
185393
  const config2 = resolveConfig(opts);
185103
185394
  const context = resolveGitSourceContext();
@@ -185401,6 +185692,16 @@ function parseReleaseVersion(value) {
185401
185692
  }
185402
185693
  return value;
185403
185694
  }
185695
+ function parseBoolean(value) {
185696
+ if (value === "true" || value === "enabled" || value === "on")
185697
+ return true;
185698
+ if (value === "false" || value === "disabled" || value === "off")
185699
+ return false;
185700
+ throw new InvalidArgumentError("Expected true/false, enabled/disabled, or on/off");
185701
+ }
185702
+ function collect2(value, previous) {
185703
+ return [...previous, value];
185704
+ }
185404
185705
  function parseType(value) {
185405
185706
  if (!["agent", "workflow"].includes(value))
185406
185707
  throw new InvalidArgumentError("type must be agent or workflow");
@@ -185431,6 +185732,14 @@ function registerGitCommands(program2) {
185431
185732
  addJsonFlag(withBaseUrl(git.command("versions <package>"))).description("List package release versions.").action(action(versions2));
185432
185733
  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
185734
  withBaseUrl(git.command("sync [automation]")).description("Sync an automation from the latest Git source release.").option("--dir <dir>", "Directory to inspect").action(action(sync));
185735
+ const trigger = git.command("trigger").description("Edit trigger policy in eigenpal.yaml.");
185736
+ 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)));
185737
+ const triggerEmail = trigger.command("email").description("Edit email trigger policy.");
185738
+ 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)));
185739
+ const secret = git.command("secret").description("Edit encrypted secrets.enc.yaml.");
185740
+ 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));
185741
+ 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)));
185742
+ 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
185743
  }
185435
185744
 
185436
185745
  // src/commands/init.ts
@@ -186029,15 +186338,15 @@ function pruneEmptyDirs(root) {
186029
186338
  if (!existsSync5(root))
186030
186339
  return;
186031
186340
  const stack = [];
186032
- const collect2 = (dir) => {
186341
+ const collect3 = (dir) => {
186033
186342
  for (const entry of readdirSync3(dir)) {
186034
186343
  const full = join3(dir, entry);
186035
186344
  if (lstatSync(full).isDirectory())
186036
- collect2(full);
186345
+ collect3(full);
186037
186346
  }
186038
186347
  stack.push(dir);
186039
186348
  };
186040
- collect2(root);
186349
+ collect3(root);
186041
186350
  for (const dir of stack) {
186042
186351
  try {
186043
186352
  if (readdirSync3(dir).length === 0)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eigenpal/cli",
3
- "version": "0.5.9",
3
+ "version": "0.5.10",
4
4
  "description": "Eigenpal CLI — author and run document workflows from your terminal. Agent-ready.",
5
5
  "keywords": [
6
6
  "eigenpal",