atris 3.30.7 → 3.30.8

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 +44 -20
  2. package/package.json +1 -1
package/ax CHANGED
@@ -598,7 +598,15 @@ function connectorWriteIntent(message) {
598
598
  }
599
599
 
600
600
  function workspaceIntent(message) {
601
- return /\b(files?|folders?|repo|workspace|project|directory|tree|read|open|inspect|search|grep|find|locate|where|edit|write|change|modify|patch|fix|test|tests?|build|src|source|code|diff|git|backend|frontend|atris task|atris xp|xp game|career xp|agentxp|todo|map)\b/i.test(message || '');
601
+ return Boolean(workspaceIntentReason(message));
602
+ }
603
+
604
+ function workspaceIntentReason(message) {
605
+ const text = String(message || '');
606
+ if (/\b(files?|folders?|repo|workspace|project|directory|tree|src|source|code|diff|git|backend|frontend|atris task|atris xp|xp game|career xp|agentxp|todo|map|tests?)\b/i.test(text)) return 'prompt mentions workspace, file, code, or repo terms';
607
+ if (/(^|\s|["'`])(?:\.{0,2}\/)?[\w.-]+\/[\w./-]+|[\w.-]+\.(?:js|jsx|ts|tsx|mjs|cjs|json|md|py|rb|go|rs|java|css|scss|html|yml|yaml|toml|env|txt)\b/i.test(text)) return 'prompt names a file path or filename';
608
+ if (/\b(read|open|inspect|search|grep|find|locate|where|edit|write|change|modify|patch|fix|test|build|refactor)\b.*\b(this|file|folder|repo|workspace|project|directory|module|component|package|readme|source|code|branch|suite|build|bug)\b/i.test(text)) return 'prompt asks to operate on workspace material';
609
+ return '';
602
610
  }
603
611
 
604
612
  function githubWorkspaceIntent(message) {
@@ -608,12 +616,17 @@ function githubWorkspaceIntent(message) {
608
616
  }
609
617
 
610
618
  function resolveRoute(message, options = {}) {
611
- if (options.route === 'local' || options.forceLocal) return 'local';
612
- if (options.route === 'cloud' || options.forceCloud) return 'cloud';
613
- if (githubWorkspaceIntent(message)) return 'local';
614
- if (mentionsConnector(message) && !workspaceIntent(message)) return 'cloud';
615
- if (workspaceIntent(message)) return 'local';
616
- return 'cloud';
619
+ return routeDecision(message, options).route;
620
+ }
621
+
622
+ function routeDecision(message, options = {}) {
623
+ if (options.route === 'local' || options.forceLocal) return { route: 'local', reason: 'explicit --local' };
624
+ if (options.route === 'cloud' || options.forceCloud) return { route: 'cloud', reason: 'explicit --cloud' };
625
+ if (githubWorkspaceIntent(message)) return { route: 'local', reason: 'prompt asks for GitHub repo mutation' };
626
+ const reason = workspaceIntentReason(message);
627
+ if (mentionsConnector(message) && !reason) return { route: 'cloud', reason: 'connector request uses hosted Atris' };
628
+ if (reason) return { route: 'local', reason };
629
+ return { route: 'cloud', reason: 'default hosted chat' };
617
630
  }
618
631
 
619
632
  function shouldPreflightRuntime(route, options = {}, mode = 'fast') {
@@ -1978,7 +1991,7 @@ async function chat(options = {}) {
1978
1991
  if (logger) output.write(`${formatAuxRow('log', formatPathSubject(logger.path, output), output)}\n\n`);
1979
1992
 
1980
1993
  const runtimePreflight = { localReady: false };
1981
- const ensureRuntimeReady = async (routeForTurn = 'local') => {
1994
+ const ensureRuntimeReady = async (routeForTurn = 'local', decision = {}) => {
1982
1995
  if (!shouldPreflightRuntime(routeForTurn, options, mode)) {
1983
1996
  return true;
1984
1997
  }
@@ -1992,7 +2005,7 @@ async function chat(options = {}) {
1992
2005
  return true;
1993
2006
  }
1994
2007
  output.write(`${formatRuntimeHealth(health, output)}\n\n`);
1995
- output.write(`${formatBackendHint()}\n`);
2008
+ output.write(`${formatBackendHint({ routeReason: decision.reason, explicitLocal: decision.reason === 'explicit --local' })}\n`);
1996
2009
  output.write(`${formatDoneLine(Date.now() - startedAt)}\n\n`);
1997
2010
  return false;
1998
2011
  };
@@ -2078,8 +2091,11 @@ async function chat(options = {}) {
2078
2091
  }
2079
2092
 
2080
2093
  const pendingTaskPreview = latestPendingTaskPreview(history);
2081
- const route = pendingTaskPreview ? 'cloud' : resolveRoute(trimmed, { route: options.route });
2082
- if (!(await ensureRuntimeReady(route))) return false;
2094
+ const decision = pendingTaskPreview
2095
+ ? { route: 'cloud', reason: 'pending approval stays on hosted Atris' }
2096
+ : routeDecision(trimmed, { route: options.route });
2097
+ const route = decision.route;
2098
+ if (!(await ensureRuntimeReady(route, decision))) return false;
2083
2099
  const turnFunction = options.turnFunction || turnFunctionForMode(mode);
2084
2100
  const result = await turnFunction(trimmed, { mode, cwd, history, output, route, business: options.business, verify: options.verify, conversationId });
2085
2101
  if (result.output && !result.output.endsWith('\n')) output.write('\n');
@@ -2137,17 +2153,21 @@ async function chat(options = {}) {
2137
2153
  if (logger) logger.close(0);
2138
2154
  }
2139
2155
 
2140
- function printBackendHint() {
2156
+ function printBackendHint(options = {}) {
2141
2157
  console.log('');
2142
- console.log(formatBackendHint());
2158
+ console.log(formatBackendHint(options));
2143
2159
  }
2144
2160
 
2145
- function backendStartCommand() {
2146
- return 'Run without --local for hosted chat, or set AX_BACKEND_URL to your AtrisOS backend.';
2161
+ function backendStartCommand(options = {}) {
2162
+ if (options.explicitLocal) return 'Start your AtrisOS backend, or retry with --cloud for hosted chat.';
2163
+ return 'Start your AtrisOS backend for local workspace, or retry with --cloud for hosted cloud scratch.';
2147
2164
  }
2148
2165
 
2149
- function formatBackendHint() {
2150
- return `Local workspace mode needs a running AtrisOS backend:\n${backendStartCommand()}`;
2166
+ function formatBackendHint(options = {}) {
2167
+ const lines = ['This requires local workspace mode, but no AtrisOS backend is running.'];
2168
+ if (options.routeReason && !options.explicitLocal) lines.push(`Routed local because ${options.routeReason}.`);
2169
+ lines.push(backendStartCommand(options));
2170
+ return lines.join('\n');
2151
2171
  }
2152
2172
 
2153
2173
  function bufferedOutput() {
@@ -2286,7 +2306,8 @@ async function runSelfTest(options = {}) {
2286
2306
  const text = chunks.join('');
2287
2307
  assertSelfTest(healthCalls === 1, 'offline preflight repeated unexpectedly');
2288
2308
  assertSelfTest(/backend\s+offline/.test(text), 'offline backend status missing');
2289
- assertSelfTest(/Local workspace mode needs a running AtrisOS backend:/.test(text), 'local backend hint missing');
2309
+ assertSelfTest(/This requires local workspace mode, but no AtrisOS backend is running\./.test(text), 'local backend hint missing');
2310
+ assertSelfTest(/retry with --cloud for hosted chat/.test(text), 'cloud retry hint missing');
2290
2311
  assertSelfTest(!/\/Users\/keshavrao/.test(text), 'local backend hint leaked a developer path');
2291
2312
  assertSelfTest(!/secret-token/.test(text), 'offline preflight leaked error detail');
2292
2313
  }, results, output);
@@ -3011,8 +3032,11 @@ async function main() {
3011
3032
  console.log(formatDoneLine(result.durationMs, creditsFromState(result)));
3012
3033
  } catch (error) {
3013
3034
  console.error(`x ${error.message}`);
3014
- const shouldShowBackendHint = forceLocal || (prompt && route !== 'cloud' && resolveRoute(prompt, { route: route === 'auto' ? undefined : route }) === 'local');
3015
- if (shouldShowBackendHint) printBackendHint();
3035
+ const decision = prompt
3036
+ ? routeDecision(prompt, { route: route === 'auto' ? undefined : route })
3037
+ : { route: forceLocal ? 'local' : 'cloud', reason: forceLocal ? 'explicit --local' : 'default hosted chat' };
3038
+ const shouldShowBackendHint = decision.route === 'local';
3039
+ if (shouldShowBackendHint) printBackendHint({ routeReason: decision.reason, explicitLocal: forceLocal || decision.reason === 'explicit --local' });
3016
3040
  process.exit(1);
3017
3041
  }
3018
3042
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atris",
3
- "version": "3.30.7",
3
+ "version": "3.30.8",
4
4
  "main": "bin/atris.js",
5
5
  "bin": {
6
6
  "atris": "bin/atris.js",