ax-agents 0.0.1-alpha.8 → 0.0.1-alpha.9

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/ax.js +61 -36
  2. package/package.json +1 -1
package/ax.js CHANGED
@@ -1852,7 +1852,22 @@ function detectState(screen, config) {
1852
1852
  }
1853
1853
  }
1854
1854
 
1855
- // Thinking - spinners (check last lines only to avoid false positives from timing messages like "✻ Crunched for 32s")
1855
+ // Ready - check BEFORE thinking to avoid false positives from timing messages like "✻ Worked for 45s"
1856
+ // If the prompt symbol is visible, the agent is ready regardless of spinner characters in timing messages
1857
+ if (lastLines.includes(config.promptSymbol)) {
1858
+ // Check if any line has the prompt followed by pasted content indicator
1859
+ // "[Pasted text" indicates user has pasted content and Claude is still processing
1860
+ const linesArray = lastLines.split("\n");
1861
+ const promptWithPaste = linesArray.some(
1862
+ (l) => l.includes(config.promptSymbol) && l.includes("[Pasted text"),
1863
+ );
1864
+ if (!promptWithPaste) {
1865
+ return State.READY;
1866
+ }
1867
+ // If prompt has pasted content, Claude is still processing - not ready yet
1868
+ }
1869
+
1870
+ // Thinking - spinners (check last lines only)
1856
1871
  const spinners = config.spinners || [];
1857
1872
  if (spinners.some((s) => lastLines.includes(s))) {
1858
1873
  return State.THINKING;
@@ -1877,20 +1892,6 @@ function detectState(screen, config) {
1877
1892
  }
1878
1893
  }
1879
1894
 
1880
- // Ready - only if prompt symbol is visible AND not followed by pasted content
1881
- // "[Pasted text" indicates user has pasted content and Claude is still processing
1882
- if (lastLines.includes(config.promptSymbol)) {
1883
- // Check if any line has the prompt followed by pasted content indicator
1884
- const linesArray = lastLines.split("\n");
1885
- const promptWithPaste = linesArray.some(
1886
- (l) => l.includes(config.promptSymbol) && l.includes("[Pasted text"),
1887
- );
1888
- if (!promptWithPaste) {
1889
- return State.READY;
1890
- }
1891
- // If prompt has pasted content, Claude is still processing - not ready yet
1892
- }
1893
-
1894
1895
  return State.STARTING;
1895
1896
  }
1896
1897
 
@@ -4161,20 +4162,43 @@ async function cmdSelect(agent, session, n, { wait = false, timeoutMs } = {}) {
4161
4162
  // =============================================================================
4162
4163
 
4163
4164
  /**
4164
- * @returns {Agent}
4165
+ * Resolve the agent to use based on (in priority order):
4166
+ * 1. Explicit --tool flag
4167
+ * 2. Session name (e.g., "claude-archangel-..." → ClaudeAgent)
4168
+ * 3. CLI invocation name (axclaude, axcodex)
4169
+ * 4. AX_DEFAULT_TOOL environment variable
4170
+ * 5. Default to CodexAgent
4171
+ *
4172
+ * @param {{toolFlag?: string, sessionName?: string | null}} options
4173
+ * @returns {{agent: Agent, error?: string}}
4165
4174
  */
4166
- function getAgentFromInvocation() {
4175
+ function resolveAgent({ toolFlag, sessionName } = {}) {
4176
+ // 1. Explicit --tool flag takes highest priority
4177
+ if (toolFlag) {
4178
+ if (toolFlag === "claude") return { agent: ClaudeAgent };
4179
+ if (toolFlag === "codex") return { agent: CodexAgent };
4180
+ return { agent: CodexAgent, error: `unknown tool '${toolFlag}'` };
4181
+ }
4182
+
4183
+ // 2. Infer from session name (e.g., "claude-archangel-..." or "codex-partner-...")
4184
+ if (sessionName) {
4185
+ const parsed = parseSessionName(sessionName);
4186
+ if (parsed?.tool === "claude") return { agent: ClaudeAgent };
4187
+ if (parsed?.tool === "codex") return { agent: CodexAgent };
4188
+ }
4189
+
4190
+ // 3. CLI invocation name
4167
4191
  const invoked = path.basename(process.argv[1], ".js");
4168
- if (invoked === "axclaude" || invoked === "claude") return ClaudeAgent;
4169
- if (invoked === "axcodex" || invoked === "codex") return CodexAgent;
4192
+ if (invoked === "axclaude" || invoked === "claude") return { agent: ClaudeAgent };
4193
+ if (invoked === "axcodex" || invoked === "codex") return { agent: CodexAgent };
4170
4194
 
4171
- // Default based on AX_DEFAULT_TOOL env var, or codex if not set
4195
+ // 4. AX_DEFAULT_TOOL environment variable
4172
4196
  const defaultTool = process.env.AX_DEFAULT_TOOL;
4173
- if (defaultTool === "claude") return ClaudeAgent;
4174
- if (defaultTool === "codex" || !defaultTool) return CodexAgent;
4197
+ if (defaultTool === "claude") return { agent: ClaudeAgent };
4198
+ if (defaultTool === "codex" || !defaultTool) return { agent: CodexAgent };
4175
4199
 
4176
4200
  console.error(`WARNING: invalid AX_DEFAULT_TOOL="${defaultTool}", using codex`);
4177
- return CodexAgent;
4201
+ return { agent: CodexAgent };
4178
4202
  }
4179
4203
 
4180
4204
  /**
@@ -4278,19 +4302,8 @@ async function main() {
4278
4302
  // Extract flags into local variables for convenience
4279
4303
  const { wait, noWait, yolo, fresh, reasoning, follow, all, orphans, force } = flags;
4280
4304
 
4281
- // Agent selection
4282
- let agent = getAgentFromInvocation();
4283
- if (flags.tool) {
4284
- if (flags.tool === "claude") agent = ClaudeAgent;
4285
- else if (flags.tool === "codex") agent = CodexAgent;
4286
- else {
4287
- console.log(`ERROR: unknown tool '${flags.tool}'`);
4288
- process.exit(1);
4289
- }
4290
- }
4291
-
4292
- // Session resolution
4293
- let session = agent.getDefaultSession();
4305
+ // Session resolution (must happen before agent resolution so we can infer tool from session name)
4306
+ let session = null;
4294
4307
  if (flags.session) {
4295
4308
  if (flags.session === "self") {
4296
4309
  const current = tmuxCurrentSession();
@@ -4305,6 +4318,18 @@ async function main() {
4305
4318
  }
4306
4319
  }
4307
4320
 
4321
+ // Agent resolution (considers --tool flag, session name, invocation, and env vars)
4322
+ const { agent, error: agentError } = resolveAgent({ toolFlag: flags.tool, sessionName: session });
4323
+ if (agentError) {
4324
+ console.log(`ERROR: ${agentError}`);
4325
+ process.exit(1);
4326
+ }
4327
+
4328
+ // If no explicit session, use agent's default
4329
+ if (!session) {
4330
+ session = agent.getDefaultSession();
4331
+ }
4332
+
4308
4333
  // Timeout (convert seconds to milliseconds)
4309
4334
  let timeoutMs = DEFAULT_TIMEOUT_MS;
4310
4335
  if (flags.timeout !== undefined) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ax-agents",
3
- "version": "0.0.1-alpha.8",
3
+ "version": "0.0.1-alpha.9",
4
4
  "description": "A CLI for orchestrating AI coding agents via tmux",
5
5
  "bin": {
6
6
  "ax": "ax.js",