atris 3.37.0 → 3.37.1

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/commands/task.js CHANGED
@@ -5533,7 +5533,11 @@ function cmdReviews(args) {
5533
5533
  }
5534
5534
  approvalItems.forEach((item, index) => {
5535
5535
  if (index > 0) console.log('');
5536
- console.log(`${index + 1}. ${gateForHuman(item.title, { title: item.title }).text}`);
5536
+ const ref = item.display_id || taskRef(item.id);
5537
+ const badge = item.evidence?.any_forced
5538
+ ? ' [evidence:forced]'
5539
+ : item.evidence?.all_passing ? ' [evidence:passing]' : '';
5540
+ console.log(`${index + 1}. ${gateForHuman(item.title, { title: item.title }).text} (${ref})${badge}`);
5537
5541
  if (item.landing) {
5538
5542
  taskReviewLandingLines(item).forEach(line => console.log(line));
5539
5543
  if (verbose && item.result?.saved) console.log(` saved: ${item.result.saved}`);
@@ -17,16 +17,25 @@ const DECISION_PHRASE_RE = /\b(?:should|whether|decide|deciding)\b/i;
17
17
  const ARGUE_BOTH_RE = /\bargue\b|\bboth sides\b|\bsteelman\b/i;
18
18
  const CODE_EDIT_RE = /\b(?:fix(?:es|ed|ing)?|refactor(?:s|ed|ing)?|renam(?:e|es|ed|ing)|debug(?:s|ged|ging)?)\b/i;
19
19
  const CODE_DIAGNOSIS_RE = /\bwhy\b|\bwrong\b|\bfail(?:s|ed|ing)?\b|\bresolv(?:e|es|ed|ing)?\b|\bbroken\b|\bnot work/i;
20
- const CODE_CONTEXT_RE = /```|(?:^|\n)\s*(?:traceback\b|(?:[a-z]+)?(?:error|exception):|at\s+\S+\s+\()/im;
20
+ const CODE_CONTEXT_RE = /```|\bregexp?\b|(?:^|\n)\s*(?:traceback\b|(?:[a-z]+)?(?:error|exception):|at\s+\S+\s+\()/im;
21
21
  const ERROR_EXPLAIN_RE = /\bexplain (?:this|the) error\b|\bwhat does (?:this|the) error mean\b/i;
22
22
  // Yes/no capability checks are lookups even without a lookup keyword.
23
23
  const YESNO_LOOKUP_RE = /^(?:does|is|are|can|do)\b/i;
24
+ // Tiny how-do-i asks are muscle-memory lookups; longer ones are advice.
25
+ const HOWTO_LOOKUP_RE = /^how (?:do|does|did) (?:i|we|you)\b/i;
26
+ const HOWTO_LOOKUP_MAX_CHARS = 40;
24
27
  const YESNO_LOOKUP_MAX_CHARS = 80;
25
28
  // Troubleshooting language means advice, not recall: keep it out of fast.
26
29
  const TROUBLE_RE = /\bfail(?:s|ed|ing)?\b|\bcrash(?:es|ed|ing)?\b|\bbroken\b|\bnot working\b/i;
27
- const WEIGHING_WORD_RE = /\b(?:consider|weigh|rank|estimate)\b/i;
30
+ const WEIGHING_WORD_RE = /\b(?:consider|weigh|rank|estimate|think (?:about|through))\b/i;
28
31
  const WEIGHING_FACTOR_MIN_COMMAS = 2;
29
32
  const TRANSFORM_START_RE = /^(?:convert|summarize|translate)\b/i;
33
+ // Reshaping pasted content is editing work, not analysis; question marks
34
+ // inside the paste do not make it a multi-question ask.
35
+ const TRANSFORM_INTENT_RE = /^(?:turn|clean up|rewrite|reword|compress|tighten|polish)\b/i;
36
+ // Possessives point at workspace context the model must gather first.
37
+ const OWN_CONTEXT_RE = /\b(?:our|my)\b/i;
38
+ const SPANISH_LOOKUP_RE = /^(?:que|qu\u00e9|cual|cu\u00e1l|quien|qui\u00e9n|cuando|cu\u00e1ndo|donde|d\u00f3nde|como|c\u00f3mo)\b/i;
30
39
  const GREETING_RE = /^(?:hey|hi|hello|yo|thanks|thank you|ok|okay|cool|nice|got it|great|perfect|yep|no worries)\b/i;
31
40
 
32
41
  function threshold(value, fallback) {
@@ -44,6 +53,9 @@ function pickLane(message, opts = {}) {
44
53
  if (text.length > longInputMinChars) {
45
54
  return { lane: 'max', reason: 'max fits this long input.' };
46
55
  }
56
+ if (TRANSFORM_INTENT_RE.test(text) && !HEAVY_REASONING_RE.test(text)) {
57
+ return { lane: 'pro', reason: 'pro fits reshaping the content you pasted.' };
58
+ }
47
59
  if (questionCount > 1) {
48
60
  return { lane: 'max', reason: 'max fits a request with multiple questions.' };
49
61
  }
@@ -64,7 +76,12 @@ function pickLane(message, opts = {}) {
64
76
  if (ERROR_EXPLAIN_RE.test(text) && !hasCodeContext) {
65
77
  return { lane: 'fast', reason: 'fast fits a plain error explanation.' };
66
78
  }
67
- if (TRANSFORM_START_RE.test(text) && text.length <= shortLookupMaxChars) {
79
+ if (SPANISH_LOOKUP_RE.test(text) && text.length <= shortLookupMaxChars
80
+ && !JUDGMENT_WORD_RE.test(text) && !TROUBLE_RE.test(text)) {
81
+ return { lane: 'fast', reason: 'fast fits this short lookup.' };
82
+ }
83
+ if (TRANSFORM_START_RE.test(text) && text.length <= shortLookupMaxChars
84
+ && !OWN_CONTEXT_RE.test(text)) {
68
85
  return { lane: 'fast', reason: 'fast fits this small transform.' };
69
86
  }
70
87
  if (GREETING_RE.test(text) && text.length <= GREETING_MAX_CHARS) {
@@ -73,6 +90,12 @@ function pickLane(message, opts = {}) {
73
90
  if (text.length > 0 && text.length <= TINY_MESSAGE_MAX_CHARS && !CODE_EDIT_RE.test(text)) {
74
91
  return { lane: 'fast', reason: 'fast fits this tiny message.' };
75
92
  }
93
+ if (text.length <= HOWTO_LOOKUP_MAX_CHARS
94
+ && HOWTO_LOOKUP_RE.test(text)
95
+ && !JUDGMENT_WORD_RE.test(text)
96
+ && !TROUBLE_RE.test(text)) {
97
+ return { lane: 'fast', reason: 'fast fits this quick how-to.' };
98
+ }
76
99
  if (text.length <= YESNO_LOOKUP_MAX_CHARS
77
100
  && YESNO_LOOKUP_RE.test(text)
78
101
  && !JUDGMENT_WORD_RE.test(text)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atris",
3
- "version": "3.37.0",
3
+ "version": "3.37.1",
4
4
  "description": "you say what you want in plain words. atris builds it, checks it, and shows you proof.",
5
5
  "main": "bin/atris.js",
6
6
  "bin": {