auto-mode 3.1.1 → 3.1.3

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/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { C as pickJudgeLane, E as updateJSONFile, S as CLI_LIMITS, T as resolveXDGDir, _ as readCheckout, a as resolveSessionScopePath, b as loadConfig, c as splitGitCommand, d as loadCheckoutFacts, f as writeActionDiagnostic, g as isUnresolvedWord, h as resolveShellPath, i as classifyAction, l as loadPolicy, m as collectShellCommands, n as readRuntime, o as loadSessionScope, p as toRepositorySlug, s as EMPTY_SESSION_SCOPE, t as parseActionRequest, u as resolveShippedPolicyDir, v as readGitEntry, w as M, x as runCapped, y as DEFAULT_SCOPE_SOURCES } from "./parse-action-request-qyh3MBGg.js";
2
+ import { C as pickJudgeLane, E as updateJSONFile, S as CLI_LIMITS, T as resolveXDGDir, _ as readCheckout, a as resolveSessionScopePath, b as loadConfig, c as splitGitCommand, d as loadCheckoutFacts, f as writeActionDiagnostic, g as isUnresolvedWord, h as resolveShellPath, i as classifyAction, l as loadPolicy, m as collectShellCommands, n as readRuntime, o as loadSessionScope, p as toRepositorySlug, s as EMPTY_SESSION_SCOPE, t as parseActionRequest, u as resolveShippedPolicyDir, v as readGitEntry, w as M, x as runCapped, y as DEFAULT_SCOPE_SOURCES } from "./parse-action-request-Czvdr5DS.js";
3
3
  import { a as literal, d as string, i as discriminatedUnion, r as boolean, s as number, u as strictObject } from "./schemas-B80Yxv6m.js";
4
4
  import { createHash, randomUUID } from "node:crypto";
5
5
  import { chmod, mkdir, open, readFile, realpath, stat } from "node:fs/promises";
package/dist/index.d.ts CHANGED
@@ -148,6 +148,7 @@ interface UserTask {
148
148
  }
149
149
  interface DirectUserMessage extends UserTask {
150
150
  readonly freshness?: 'stale' | undefined;
151
+ readonly position?: 'opening' | undefined;
151
152
  }
152
153
  interface DelegatedTask {
153
154
  readonly text: string;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { b as loadConfig$1, i as classifyAction$1, n as readRuntime, r as readHostEnvironment, t as parseActionRequest } from "./parse-action-request-qyh3MBGg.js";
1
+ import { b as loadConfig$1, i as classifyAction$1, n as readRuntime, r as readHostEnvironment, t as parseActionRequest } from "./parse-action-request-Czvdr5DS.js";
2
2
  //#region src/index.ts
3
3
  function classifyAction(request, config, options = {}) {
4
4
  return classifyAction$1(request, config, {
@@ -3575,7 +3575,7 @@ function buildJudgedVerdict(rule, basis, reply, options) {
3575
3575
  };
3576
3576
  if (reply.kind === "overturn") {
3577
3577
  const clearsHardRule = reply.basis === "misread" && options.misreadClears === true;
3578
- return rule.tier === "hard" && !clearsHardRule || reply.basis === "misread" && options.overturns === "consent" ? {
3578
+ return rule.tier === "hard" && !clearsHardRule || reply.basis === "misread" && options.overturns === "consent" || reply.basis === "consent" && !options.hasUserMessage ? {
3579
3579
  verdict: template,
3580
3580
  status: "held",
3581
3581
  overturnBasis: reply.basis
@@ -3833,6 +3833,7 @@ async function classifyWithJudge(payload, evidence, judge, options) {
3833
3833
  let failure = null;
3834
3834
  let answered = null;
3835
3835
  let replies = evidence.map(() => null);
3836
+ const directMessage = findCurrentDirectUserMessage(payload.decisionContext?.lastDirectUserMessage);
3836
3837
  try {
3837
3838
  failure = "credential";
3838
3839
  const needsKey = pickJudgeLane(judge).credential === "api-key";
@@ -3840,7 +3841,6 @@ async function classifyWithJudge(payload, evidence, judge, options) {
3840
3841
  if (needsKey && apiKey === null) throw new Error("no API key for the judge");
3841
3842
  failure = "policy";
3842
3843
  const system = await loadPolicy({ rulesPath: options.rulesPath }, "judge.md");
3843
- const directMessage = findCurrentDirectUserMessage(payload.decisionContext?.lastDirectUserMessage);
3844
3844
  const user = buildJudgeMessage({
3845
3845
  denies: evidence.map((entry) => ({
3846
3846
  rule: entry.rule,
@@ -3881,7 +3881,8 @@ async function classifyWithJudge(payload, evidence, judge, options) {
3881
3881
  const verdict = buildJudgedVerdict(entry.rule, entry.basis, reply, {
3882
3882
  overturns,
3883
3883
  heldReason: entry.containment?.reason,
3884
- misreadClears: entry.misreadClears
3884
+ misreadClears: entry.misreadClears,
3885
+ hasUserMessage: directMessage !== null
3885
3886
  });
3886
3887
  return {
3887
3888
  ...verdict,
@@ -5927,6 +5928,28 @@ async function loadTaskScope(request, sources, host, stderr) {
5927
5928
  });
5928
5929
  }
5929
5930
  //#endregion
5931
+ //#region src/scope/probe-launcher-spawner.ts
5932
+ async function probeLauncherSpawner(location, readTextFile) {
5933
+ const load = await loadScopeFile(location, readTextFile);
5934
+ return load.kind === "malformed" || load.kind === "scope" && load.scope.replyChannels.length > 0;
5935
+ }
5936
+ //#endregion
5937
+ //#region src/scope/resolve-opening-prompt.ts
5938
+ async function resolveOpeningPrompt(request, runtime) {
5939
+ const context = request.decisionContext;
5940
+ const message = context?.lastDirectUserMessage;
5941
+ if (context === void 0 || message?.position !== "opening") return request;
5942
+ const { position: _, ...unmarked } = message;
5943
+ const isSpawned = await probeLauncherSpawner(runtime.host.env["AUTO_MODE_SCOPE_FILE"], runtime.readTextFile);
5944
+ return {
5945
+ ...request,
5946
+ decisionContext: {
5947
+ ...context,
5948
+ lastDirectUserMessage: isSpawned ? null : unmarked
5949
+ }
5950
+ };
5951
+ }
5952
+ //#endregion
5930
5953
  //#region src/classify-action.ts
5931
5954
  async function classifyAction(request, config, options) {
5932
5955
  const stderr = options.stderr;
@@ -5936,7 +5959,8 @@ async function classifyAction(request, config, options) {
5936
5959
  invocationID,
5937
5960
  status: "started"
5938
5961
  }, host, stderr);
5939
- const outcome = options.budget === true ? await classifyWithBudget(request, config, options) : await classifyStages(request, config, options);
5962
+ const resolved = await resolveOpeningPrompt(request, options.runtime);
5963
+ const outcome = options.budget === true ? await classifyWithBudget(resolved, config, options) : await classifyStages(resolved, config, options);
5940
5964
  if (options.actionLog === true) await writeActionDiagnostic(request, {
5941
5965
  invocationID,
5942
5966
  status: outcome.status,
@@ -6294,7 +6318,8 @@ const userTaskSchema = strictObject({
6294
6318
  });
6295
6319
  const directUserMessageSchema = strictObject({
6296
6320
  ...userTaskSchema.shape,
6297
- freshness: literal("stale").optional()
6321
+ freshness: literal("stale").optional(),
6322
+ position: literal("opening").optional()
6298
6323
  });
6299
6324
  const delegatedTaskSchema = strictObject({
6300
6325
  text: string(),
@@ -9,6 +9,7 @@ export interface UserTask {
9
9
 
10
10
  export interface DirectUserMessage extends UserTask {
11
11
  readonly freshness?: 'stale' | undefined;
12
+ readonly position?: 'opening' | undefined;
12
13
  }
13
14
 
14
15
  interface DelegatedTask {
@@ -17,6 +17,11 @@ export function buildPromptContext(
17
17
  originalUserTask: null,
18
18
  lastDirectUserMessage: null,
19
19
  canCaptureOriginal: input.source === 'startup' || input.source === 'clear',
20
+
21
+ // A launcher can pass the opening prompt on the command line, which
22
+ // Claude Code reports with the origin of a typed prompt. A clear happens
23
+ // only at the prompt of a running session.
24
+ awaitsOpeningPrompt: input.source !== 'clear',
20
25
  };
21
26
  }
22
27
 
@@ -27,21 +32,29 @@ export function buildPromptContext(
27
32
  originalUserTask: previous?.originalUserTask ?? null,
28
33
  lastDirectUserMessage: buildStaleMessage(previous?.lastDirectUserMessage ?? null),
29
34
  canCaptureOriginal: previous?.canCaptureOriginal ?? false,
35
+ awaitsOpeningPrompt: previous?.awaitsOpeningPrompt ?? true,
30
36
  };
31
37
  }
32
38
 
33
39
  const message: UserTask = { text: input.text, origin };
40
+ const isOpeningPrompt = previous?.awaitsOpeningPrompt ?? true;
34
41
 
35
42
  return {
36
43
  originalUserTask:
37
44
  previous?.originalUserTask ?? (previous?.canCaptureOriginal === true ? message : null),
38
- lastDirectUserMessage: message,
45
+ lastDirectUserMessage: isOpeningPrompt ? { ...message, position: 'opening' } : message,
39
46
  canCaptureOriginal: previous?.canCaptureOriginal ?? false,
47
+ awaitsOpeningPrompt: false,
40
48
  };
41
49
  }
42
50
 
43
51
  function buildStaleMessage(message: DirectUserMessage | null): DirectUserMessage | null {
44
52
  return message === null
45
53
  ? null
46
- : { text: message.text, origin: message.origin, freshness: 'stale' };
54
+ : {
55
+ text: message.text,
56
+ origin: message.origin,
57
+ freshness: 'stale',
58
+ ...(message.position === undefined ? {} : { position: message.position }),
59
+ };
47
60
  }
@@ -51,6 +51,7 @@ export interface PromptContext {
51
51
  readonly originalUserTask: UserTask | null;
52
52
  readonly lastDirectUserMessage: DirectUserMessage | null;
53
53
  readonly canCaptureOriginal: boolean;
54
+ readonly awaitsOpeningPrompt: boolean;
54
55
  }
55
56
 
56
57
  interface PromptInput {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auto-mode",
3
- "version": "3.1.1",
3
+ "version": "3.1.3",
4
4
  "description": "A permission classifier library and Claude Code mod, so agents that are not Claude can run unattended",
5
5
  "keywords": [
6
6
  "agent",
@@ -70,6 +70,8 @@
70
70
  "files:branch": "bun scripts/read-branch-files.ts",
71
71
  "lint:files": "oxlint --no-error-on-unmatched-pattern",
72
72
  "test:related": "bun scripts/run-related-tests.ts",
73
+ "check:publish": "bun scripts/run-publish-check.ts",
74
+ "setup:ci-tools": "bun scripts/run-ci-tools-install.ts",
73
75
  "check:commits": "bun scripts/run-commits-check.ts",
74
76
  "check:local-paths": "bun scripts/run-local-paths-check.ts",
75
77
  "check:test-timeouts": "bun scripts/run-test-timeouts-check.ts",
@@ -86,7 +88,7 @@
86
88
  "@types/node": "26.6.5",
87
89
  "@zgeoff/bun-test-extended": "0.2.1",
88
90
  "@zgeoff/format-codemod": "0.3.3",
89
- "@zgeoff/oxlint-config": "0.7.0",
91
+ "@zgeoff/oxlint-config": "0.7.1",
90
92
  "@zgeoff/skill-gate": "0.2.9",
91
93
  "gunshi": "1.0.0-rc.1",
92
94
  "knip": "6.42.0",