@4pm/cli 1.5.29 → 1.5.30

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.
Files changed (2) hide show
  1. package/dist/index.js +55 -14
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -32954,6 +32954,15 @@ var dispatchCommandRequestSchema = external_exports.object({
32954
32954
  * **mutually exclusive with `aiOneShot`** (a run is one-shot | read-only | full-agent).
32955
32955
  */
32956
32956
  aiReadOnly: external_exports.boolean().optional(),
32957
+ /**
32958
+ * Write-capable agent AI mode (ADR-0271): a full agent that must run file + git/`gh`/`glab`
32959
+ * writes **headless without approval prompts** (the project-template "Update", which creates a
32960
+ * branch and opens a PR). The cli runs claude under `--permission-mode bypassPermissions` (codex
32961
+ * full-auto) so the run doesn't stall on an interactive approval it can't answer. Still bounded by
32962
+ * the folder-scope guard (ADR-0181). Only meaningful with `ai:true`; **mutually exclusive with
32963
+ * `aiOneShot`/`aiReadOnly`** (a run is one-shot | read-only | full-agent [| write-capable]).
32964
+ */
32965
+ aiBypass: external_exports.boolean().optional(),
32957
32966
  /**
32958
32967
  * Per-run AI execution overrides (ADR-0261): model/thinking/temperature chosen in the web
32959
32968
  * "AI settings" modal (per-user localStorage), layered over the profile default by the cli.
@@ -32975,6 +32984,13 @@ var dispatchCommandRequestSchema = external_exports.object({
32975
32984
  message: "aiOneShot and aiReadOnly are mutually exclusive."
32976
32985
  });
32977
32986
  }
32987
+ if (v.aiBypass && (v.aiOneShot || v.aiReadOnly)) {
32988
+ ctx.addIssue({
32989
+ code: external_exports.ZodIssueCode.custom,
32990
+ path: ["aiBypass"],
32991
+ message: "aiBypass is mutually exclusive with aiOneShot and aiReadOnly."
32992
+ });
32993
+ }
32978
32994
  if (!v.ai && v.command.length > COMMAND_MAX_LEN) {
32979
32995
  ctx.addIssue({
32980
32996
  code: external_exports.ZodIssueCode.too_big,
@@ -33363,6 +33379,25 @@ var putSpecDraftRequestSchema = external_exports.object({
33363
33379
  var putProjectSpecRequestSchema = external_exports.object({
33364
33380
  spec: external_exports.record(external_exports.unknown())
33365
33381
  });
33382
+ var TEMPLATE_ANALYSIS_MAX_BYTES = 512 * 1024;
33383
+ var TEMPLATE_UPDATE_MAX_BYTES = 512 * 1024;
33384
+ var putTemplateAnalysisRequestSchema = external_exports.object({
33385
+ report: external_exports.string().min(1),
33386
+ instruction: external_exports.string().nullable(),
33387
+ fromVersion: external_exports.string().nullable(),
33388
+ toVersion: external_exports.string().min(1)
33389
+ });
33390
+ var putTemplateUpdateRequestSchema = external_exports.object({
33391
+ output: external_exports.string().min(1),
33392
+ status: external_exports.enum(["success", "warning", "failed"]),
33393
+ pullRequestId: external_exports.string().nullable(),
33394
+ pullRequestUrl: external_exports.string().nullable(),
33395
+ branch: external_exports.string().nullable(),
33396
+ message: external_exports.string().nullable(),
33397
+ instruction: external_exports.string().nullable(),
33398
+ fromVersion: external_exports.string().nullable(),
33399
+ toVersion: external_exports.string().min(1)
33400
+ });
33366
33401
  var ARTIFACT_MAX_BYTES = 512 * 1024;
33367
33402
  var listArtifactsQuerySchema = external_exports.object({
33368
33403
  kind: external_exports.enum(TEMPLATE_KINDS).optional()
@@ -34596,6 +34631,11 @@ function readOnlyArgs(cmd) {
34596
34631
  if (cmd.includes("codex")) return ["--sandbox", "read-only"];
34597
34632
  return [];
34598
34633
  }
34634
+ function bypassArgs(cmd) {
34635
+ if (cmd.includes("claude")) return ["--permission-mode", "bypassPermissions"];
34636
+ if (cmd.includes("codex")) return ["--dangerously-bypass-approvals-and-sandbox"];
34637
+ return [];
34638
+ }
34599
34639
  function requiredArgs(cmd) {
34600
34640
  if (cmd.includes("claude")) return REQUIRED_AI_ARGS.claude;
34601
34641
  if (cmd.includes("codex")) return REQUIRED_AI_ARGS.codex;
@@ -34669,12 +34709,12 @@ function overrideEnv(cmd, o) {
34669
34709
  const budget = THINKING_TOKENS[o.thinking];
34670
34710
  return budget ? { MAX_THINKING_TOKENS: String(budget) } : {};
34671
34711
  }
34672
- function buildRunArgs(profile, cmd, resumeId, oneShot = false, override, readOnly = false) {
34712
+ function buildRunArgs(profile, cmd, resumeId, oneShot = false, override, readOnly = false, bypass = false) {
34673
34713
  const extras = profile.args ?? [];
34674
34714
  const model = override?.model?.trim() || profile.model?.trim();
34675
34715
  const modelArgs = model ? ["--model", model] : [];
34676
34716
  const resumeArgs = resumeId && cmd.includes("claude") ? ["--resume", resumeId] : [];
34677
- const modeExtra = oneShot ? oneShotArgs(cmd) : readOnly ? readOnlyArgs(cmd) : [];
34717
+ const modeExtra = oneShot ? oneShotArgs(cmd) : readOnly ? readOnlyArgs(cmd) : bypass ? bypassArgs(cmd) : [];
34678
34718
  return [
34679
34719
  ...requiredArgs(cmd),
34680
34720
  ...resumeArgs,
@@ -34721,10 +34761,10 @@ function resolveClaudeProfiles(config, workingDir) {
34721
34761
  if (idx > 0) profiles.unshift(profiles.splice(idx, 1)[0]);
34722
34762
  return profiles;
34723
34763
  }
34724
- function planAiRun(prompt, config, hint = {}, resume = /* @__PURE__ */ new Map(), oneShot = false, override, readOnly = false) {
34725
- return isUnifiedConfig(config) ? planUnifiedRun(prompt, config, hint.credential ?? null, resume, oneShot, override, readOnly) : planLegacyRun(prompt, config, hint.dir ?? null, resume, oneShot, override, readOnly);
34764
+ function planAiRun(prompt, config, hint = {}, resume = /* @__PURE__ */ new Map(), oneShot = false, override, readOnly = false, bypass = false) {
34765
+ return isUnifiedConfig(config) ? planUnifiedRun(prompt, config, hint.credential ?? null, resume, oneShot, override, readOnly, bypass) : planLegacyRun(prompt, config, hint.dir ?? null, resume, oneShot, override, readOnly, bypass);
34726
34766
  }
34727
- function planUnifiedRun(prompt, config, workingCredential, resume, oneShot, override, readOnly = false) {
34767
+ function planUnifiedRun(prompt, config, workingCredential, resume, oneShot, override, readOnly = false, bypass = false) {
34728
34768
  const baseEnv = config.aiEnv ?? {};
34729
34769
  const active = activeProvider(config);
34730
34770
  const usable = config.aiProfiles.filter(isUsableCredential);
@@ -34733,7 +34773,7 @@ function planUnifiedRun(prompt, config, workingCredential, resume, oneShot, over
34733
34773
  return {
34734
34774
  cmd: active,
34735
34775
  attempts: [
34736
- { cmd: active, label: "default", dir: null, key: null, args: buildRunArgs({ profile: "" }, active, void 0, oneShot, override, readOnly), stdin: prompt, env: { ...baseEnv, ...overrideEnv(active, override) } }
34776
+ { cmd: active, label: "default", dir: null, key: null, args: buildRunArgs({ profile: "" }, active, void 0, oneShot, override, readOnly, bypass), stdin: prompt, env: { ...baseEnv, ...overrideEnv(active, override) } }
34737
34777
  ]
34738
34778
  };
34739
34779
  }
@@ -34751,20 +34791,20 @@ function planUnifiedRun(prompt, config, workingCredential, resume, oneShot, over
34751
34791
  label: cred.label?.trim() || profileDisplayLabel(dir2),
34752
34792
  dir: dir2,
34753
34793
  key,
34754
- args: buildRunArgs(cred, cmd, resume.get(key), oneShot, override, readOnly),
34794
+ args: buildRunArgs(cred, cmd, resume.get(key), oneShot, override, readOnly, bypass),
34755
34795
  stdin: prompt,
34756
34796
  env: envVar ? { ...baseEnv, [envVar]: dir2, ...overrideEnv(cmd, override) } : { ...baseEnv, ...overrideEnv(cmd, override) }
34757
34797
  }));
34758
34798
  return { cmd: attempts[0]?.cmd ?? DEFAULT_AI_CLI, attempts };
34759
34799
  }
34760
- function planLegacyRun(prompt, config, workingDir, resume, oneShot, override, readOnly = false) {
34800
+ function planLegacyRun(prompt, config, workingDir, resume, oneShot, override, readOnly = false, bypass = false) {
34761
34801
  const cmd = config.aiCli || DEFAULT_AI_CLI;
34762
34802
  const baseEnv = config.aiEnv ?? {};
34763
34803
  const envVar = profileEnvVar(cmd);
34764
34804
  const defaultPlan = {
34765
34805
  cmd,
34766
34806
  attempts: [
34767
- { cmd, label: "default", dir: null, key: null, args: buildRunArgs({ profile: "" }, cmd, void 0, oneShot, override, readOnly), stdin: prompt, env: { ...baseEnv, ...overrideEnv(cmd, override) } }
34807
+ { cmd, label: "default", dir: null, key: null, args: buildRunArgs({ profile: "" }, cmd, void 0, oneShot, override, readOnly, bypass), stdin: prompt, env: { ...baseEnv, ...overrideEnv(cmd, override) } }
34768
34808
  ]
34769
34809
  };
34770
34810
  if (!envVar) return defaultPlan;
@@ -34781,7 +34821,7 @@ function planLegacyRun(prompt, config, workingDir, resume, oneShot, override, re
34781
34821
  label: profileDisplayLabel(dir2),
34782
34822
  dir: dir2,
34783
34823
  key,
34784
- args: buildRunArgs(profile, cmd, resume.get(key), oneShot, override, readOnly),
34824
+ args: buildRunArgs(profile, cmd, resume.get(key), oneShot, override, readOnly, bypass),
34785
34825
  stdin: prompt,
34786
34826
  env: { ...baseEnv, [envVar]: dir2, ...overrideEnv(cmd, override) }
34787
34827
  };
@@ -36460,7 +36500,8 @@ function handleCommandChannels(ctx, message, payload) {
36460
36500
  dispatch.aiOneShot ?? false,
36461
36501
  dispatch.images,
36462
36502
  dispatch.aiConfig,
36463
- dispatch.aiReadOnly ?? false
36503
+ dispatch.aiReadOnly ?? false,
36504
+ dispatch.aiBypass ?? false
36464
36505
  );
36465
36506
  }
36466
36507
  return true;
@@ -36518,7 +36559,7 @@ async function runLocalCommand(ctx, input) {
36518
36559
  const commandId = randomCommandId();
36519
36560
  await runAiPrompt(ctx, prompt, commandId, "local");
36520
36561
  }
36521
- async function runAiPrompt(ctx, prompt, commandId, origin, oneShot = false, images, aiConfig, readOnly = false) {
36562
+ async function runAiPrompt(ctx, prompt, commandId, origin, oneShot = false, images, aiConfig, readOnly = false, bypass = false) {
36522
36563
  const config = readProfileConfig(ctx.profileDir);
36523
36564
  const projectTimeoutSec = config.projectAiRunTimeoutSec ?? 0;
36524
36565
  const machineTimeoutSec = config.aiRunTimeoutSec ?? 0;
@@ -36590,7 +36631,7 @@ async function runAiPrompt(ctx, prompt, commandId, origin, oneShot = false, imag
36590
36631
  const guardedPrompt = ctx.restrictToFolder && ctx.physicRoot ? folderScopeGuard(ctx.physicRoot, aiBodyPrompt) : aiBodyPrompt;
36591
36632
  const hint = unified ? { credential: startCred ?? workingCred } : { dir: startDir ?? workingDir };
36592
36633
  const memCfg = resolveMemoryConfig(config);
36593
- const firstAttempt = planAiRun(guardedPrompt, config, hint, /* @__PURE__ */ new Map(), oneShot, aiConfig, readOnly).attempts[0];
36634
+ const firstAttempt = planAiRun(guardedPrompt, config, hint, /* @__PURE__ */ new Map(), oneShot, aiConfig, readOnly, bypass).attempts[0];
36594
36635
  const resumeId = memCfg.enabled && firstAttempt?.key && firstAttempt.cmd === "claude" ? ctx.sessionIdByKey.get(firstAttempt.key) : void 0;
36595
36636
  let effectivePrompt = guardedPrompt;
36596
36637
  let resume = /* @__PURE__ */ new Map();
@@ -36602,7 +36643,7 @@ ${ctx.aiMemory}
36602
36643
 
36603
36644
  ${guardedPrompt}`;
36604
36645
  }
36605
- const plan = planAiRun(effectivePrompt, config, hint, resume, oneShot, aiConfig, readOnly);
36646
+ const plan = planAiRun(effectivePrompt, config, hint, resume, oneShot, aiConfig, readOnly, bypass);
36606
36647
  const markerArgs = plan.attempts[0]?.args ?? [];
36607
36648
  const startStamp = formatTimestampInZone(/* @__PURE__ */ new Date(), ctx.orgTimezone);
36608
36649
  ctx.bus.push({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@4pm/cli",
3
- "version": "1.5.29",
3
+ "version": "1.5.30",
4
4
  "private": false,
5
5
  "description": "4PM CLI — drives Claude/Codex CLIs on AI worker machines (Node + TypeScript)",
6
6
  "license": "LicenseRef-4PM-Source-Available",