muonroi-cli 1.4.1 → 1.6.0

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 (194) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +122 -122
  3. package/dist/packages/agent-harness-core/src/predicate.d.ts +1 -1
  4. package/dist/src/agent-harness/__tests__/mock-model.spec.js +48 -1
  5. package/dist/src/agent-harness/mock-model.d.ts +11 -0
  6. package/dist/src/agent-harness/mock-model.js +21 -0
  7. package/dist/src/cli/cost-forensics.js +12 -12
  8. package/dist/src/council/__tests__/clarification-prompt.test.js +51 -0
  9. package/dist/src/council/__tests__/clarifier-ready-gate.test.js +32 -0
  10. package/dist/src/council/__tests__/decisions-lock.test.js +17 -1
  11. package/dist/src/council/__tests__/oauth-reachable.test.d.ts +1 -0
  12. package/dist/src/council/__tests__/oauth-reachable.test.js +31 -0
  13. package/dist/src/council/__tests__/parse-outcome-fallback.test.js +11 -0
  14. package/dist/src/council/clarifier.js +9 -1
  15. package/dist/src/council/debate.js +5 -1
  16. package/dist/src/council/decisions-lock.js +3 -3
  17. package/dist/src/council/index.js +12 -5
  18. package/dist/src/council/leader.d.ts +0 -17
  19. package/dist/src/council/leader.js +22 -15
  20. package/dist/src/council/planner.js +1 -1
  21. package/dist/src/council/prompts.js +63 -57
  22. package/dist/src/council/types.d.ts +7 -0
  23. package/dist/src/ee/__tests__/ee-onboarding.test.d.ts +1 -0
  24. package/dist/src/ee/__tests__/ee-onboarding.test.js +32 -0
  25. package/dist/src/ee/artifact-cache.d.ts +56 -0
  26. package/dist/src/ee/artifact-cache.js +155 -0
  27. package/dist/src/ee/artifact-cache.test.d.ts +1 -0
  28. package/dist/src/ee/artifact-cache.test.js +69 -0
  29. package/dist/src/ee/auth.d.ts +9 -0
  30. package/dist/src/ee/auth.js +19 -0
  31. package/dist/src/ee/ee-onboarding.d.ts +5 -0
  32. package/dist/src/ee/ee-onboarding.js +76 -0
  33. package/dist/src/ee/search.js +7 -5
  34. package/dist/src/ee/search.test.d.ts +1 -0
  35. package/dist/src/ee/search.test.js +23 -0
  36. package/dist/src/generated/version.d.ts +1 -1
  37. package/dist/src/generated/version.js +1 -1
  38. package/dist/src/headless/output.js +6 -4
  39. package/dist/src/headless/output.test.js +4 -3
  40. package/dist/src/index.js +20 -1
  41. package/dist/src/mcp/__tests__/auto-setup.test.js +74 -0
  42. package/dist/src/mcp/__tests__/client-pool.spec.d.ts +1 -0
  43. package/dist/src/mcp/__tests__/client-pool.spec.js +98 -0
  44. package/dist/src/mcp/__tests__/parallel-build.spec.d.ts +1 -0
  45. package/dist/src/mcp/__tests__/parallel-build.spec.js +67 -0
  46. package/dist/src/mcp/__tests__/smart-filter.test.js +56 -0
  47. package/dist/src/mcp/auto-setup.js +56 -2
  48. package/dist/src/mcp/client-pool.d.ts +46 -0
  49. package/dist/src/mcp/client-pool.js +212 -0
  50. package/dist/src/mcp/oauth-callback.js +2 -2
  51. package/dist/src/mcp/parse-headers.test.js +14 -14
  52. package/dist/src/mcp/runtime.d.ts +28 -0
  53. package/dist/src/mcp/runtime.js +117 -51
  54. package/dist/src/mcp/self-verify-runner.d.ts +14 -0
  55. package/dist/src/mcp/self-verify-runner.js +38 -0
  56. package/dist/src/mcp/setup-guide-text.d.ts +9 -0
  57. package/dist/src/mcp/setup-guide-text.js +84 -0
  58. package/dist/src/mcp/smart-filter.js +49 -0
  59. package/dist/src/mcp/smoke.test.js +43 -43
  60. package/dist/src/mcp/tools-server.d.ts +7 -0
  61. package/dist/src/mcp/tools-server.js +19 -22
  62. package/dist/src/models/catalog.json +349 -349
  63. package/dist/src/ops/__tests__/doctor-ee-health.test.js +21 -0
  64. package/dist/src/ops/doctor.d.ts +3 -2
  65. package/dist/src/ops/doctor.js +47 -11
  66. package/dist/src/ops/doctor.test.js +4 -3
  67. package/dist/src/orchestrator/__tests__/mcp-capability-block.test.d.ts +1 -0
  68. package/dist/src/orchestrator/__tests__/mcp-capability-block.test.js +39 -0
  69. package/dist/src/orchestrator/__tests__/project-stack.test.d.ts +1 -0
  70. package/dist/src/orchestrator/__tests__/project-stack.test.js +65 -0
  71. package/dist/src/orchestrator/batch-turn-runner.js +7 -11
  72. package/dist/src/orchestrator/compaction.d.ts +2 -0
  73. package/dist/src/orchestrator/compaction.js +14 -1
  74. package/dist/src/orchestrator/compaction.test.js +25 -1
  75. package/dist/src/orchestrator/message-processor.js +72 -32
  76. package/dist/src/orchestrator/orchestrator.js +26 -0
  77. package/dist/src/orchestrator/prompts.d.ts +51 -0
  78. package/dist/src/orchestrator/prompts.js +257 -134
  79. package/dist/src/orchestrator/scope-ceiling.js +6 -1
  80. package/dist/src/orchestrator/scope-reminder.d.ts +12 -0
  81. package/dist/src/orchestrator/scope-reminder.js +16 -0
  82. package/dist/src/orchestrator/scope-reminder.test.js +22 -1
  83. package/dist/src/orchestrator/stream-runner.js +23 -15
  84. package/dist/src/orchestrator/subagent-compactor.d.ts +14 -5
  85. package/dist/src/orchestrator/subagent-compactor.js +30 -8
  86. package/dist/src/orchestrator/subagent-compactor.spec.js +18 -0
  87. package/dist/src/orchestrator/text-tool-call-detector.test.js +13 -13
  88. package/dist/src/pil/__tests__/clarity-gate.test.js +24 -215
  89. package/dist/src/pil/__tests__/config.test.js +1 -17
  90. package/dist/src/pil/__tests__/discovery.test.js +144 -11
  91. package/dist/src/pil/__tests__/layer1-intent-trace.test.js +7 -2
  92. package/dist/src/pil/__tests__/layer1-intent.test.js +3 -0
  93. package/dist/src/pil/__tests__/layer16-clarity.test.js +32 -116
  94. package/dist/src/pil/__tests__/layer4-gsd.test.js +37 -0
  95. package/dist/src/pil/__tests__/layer6-output.test.js +158 -18
  96. package/dist/src/pil/__tests__/llm-classify.test.js +49 -2
  97. package/dist/src/pil/__tests__/surface-compaction-artifacts.test.d.ts +1 -0
  98. package/dist/src/pil/__tests__/surface-compaction-artifacts.test.js +112 -0
  99. package/dist/src/pil/agent-operating-contract.d.ts +1 -1
  100. package/dist/src/pil/agent-operating-contract.js +2 -0
  101. package/dist/src/pil/agent-operating-contract.test.js +7 -2
  102. package/dist/src/pil/cheap-model-playbook.js +35 -35
  103. package/dist/src/pil/cheap-model-workbooks.js +16 -13
  104. package/dist/src/pil/clarity-gate.d.ts +21 -19
  105. package/dist/src/pil/clarity-gate.js +26 -153
  106. package/dist/src/pil/config.d.ts +9 -1
  107. package/dist/src/pil/config.js +15 -4
  108. package/dist/src/pil/discovery.js +211 -136
  109. package/dist/src/pil/layer1-intent.d.ts +12 -0
  110. package/dist/src/pil/layer1-intent.js +283 -38
  111. package/dist/src/pil/layer1-intent.test.js +210 -4
  112. package/dist/src/pil/layer16-clarity.d.ts +25 -11
  113. package/dist/src/pil/layer16-clarity.js +19 -306
  114. package/dist/src/pil/layer3-ee-injection.d.ts +19 -0
  115. package/dist/src/pil/layer3-ee-injection.js +96 -4
  116. package/dist/src/pil/layer4-gsd.js +18 -6
  117. package/dist/src/pil/layer6-output.d.ts +2 -0
  118. package/dist/src/pil/layer6-output.js +151 -25
  119. package/dist/src/pil/llm-classify.d.ts +26 -0
  120. package/dist/src/pil/llm-classify.js +34 -5
  121. package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
  122. package/dist/src/pil/native-capabilities-workbook.js +82 -76
  123. package/dist/src/pil/pipeline.js +15 -9
  124. package/dist/src/pil/schema.d.ts +8 -0
  125. package/dist/src/pil/schema.js +12 -1
  126. package/dist/src/pil/task-tier-map.js +4 -0
  127. package/dist/src/pil/types.d.ts +11 -1
  128. package/dist/src/product-loop/done-gate.js +3 -3
  129. package/dist/src/product-loop/loop-driver.js +18 -18
  130. package/dist/src/product-loop/progress-snapshot.js +4 -4
  131. package/dist/src/providers/auth/gemini-oauth.js +6 -15
  132. package/dist/src/providers/auth/grok-oauth.js +6 -15
  133. package/dist/src/providers/auth/openai-oauth.js +6 -15
  134. package/dist/src/providers/mcp-vision-bridge.js +48 -48
  135. package/dist/src/reporter/index.js +1 -1
  136. package/dist/src/scaffold/bb-ecosystem-apply.js +47 -47
  137. package/dist/src/scaffold/bb-quality-gate.js +5 -5
  138. package/dist/src/scaffold/continuation-prompt.js +60 -60
  139. package/dist/src/scaffold/init-new.js +453 -453
  140. package/dist/src/self-qa/__tests__/scenario-planner.test.js +3 -3
  141. package/dist/src/self-qa/agentic-loop.js +24 -19
  142. package/dist/src/self-qa/spec-emitter.js +26 -23
  143. package/dist/src/storage/__tests__/migrations.test.js +2 -2
  144. package/dist/src/storage/interaction-log.js +5 -5
  145. package/dist/src/storage/migrations.js +122 -122
  146. package/dist/src/storage/sessions.js +42 -42
  147. package/dist/src/storage/transcript.js +91 -84
  148. package/dist/src/storage/usage.js +14 -14
  149. package/dist/src/storage/workspaces.js +12 -12
  150. package/dist/src/tools/__tests__/native-tools.test.d.ts +1 -0
  151. package/dist/src/tools/__tests__/native-tools.test.js +53 -0
  152. package/dist/src/tools/git-safety.d.ts +61 -0
  153. package/dist/src/tools/git-safety.js +141 -0
  154. package/dist/src/tools/git-safety.test.d.ts +1 -0
  155. package/dist/src/tools/git-safety.test.js +111 -0
  156. package/dist/src/tools/native-tools.d.ts +31 -0
  157. package/dist/src/tools/native-tools.js +273 -0
  158. package/dist/src/tools/registry-ee-query.test.js +18 -1
  159. package/dist/src/tools/registry-git-safety.test.d.ts +7 -0
  160. package/dist/src/tools/registry-git-safety.test.js +92 -0
  161. package/dist/src/tools/registry.js +52 -6
  162. package/dist/src/ui/__tests__/markdown-render.test.d.ts +1 -0
  163. package/dist/src/ui/__tests__/markdown-render.test.js +48 -0
  164. package/dist/src/ui/app.js +0 -0
  165. package/dist/src/ui/components/message-view.js +4 -1
  166. package/dist/src/ui/components/structured-response-view.js +7 -3
  167. package/dist/src/ui/components/tool-group.js +7 -1
  168. package/dist/src/ui/markdown-render.d.ts +41 -0
  169. package/dist/src/ui/markdown-render.js +223 -0
  170. package/dist/src/ui/markdown.d.ts +10 -0
  171. package/dist/src/ui/markdown.js +12 -35
  172. package/dist/src/ui/slash/council-inspect.js +4 -4
  173. package/dist/src/ui/slash/export.js +4 -4
  174. package/dist/src/ui/utils/text.d.ts +8 -0
  175. package/dist/src/ui/utils/text.js +16 -0
  176. package/dist/src/ui/utils/text.test.d.ts +1 -0
  177. package/dist/src/ui/utils/text.test.js +23 -0
  178. package/dist/src/usage/ledger.js +48 -15
  179. package/dist/src/utils/__tests__/footprint-gitignore.test.d.ts +1 -0
  180. package/dist/src/utils/__tests__/footprint-gitignore.test.js +50 -0
  181. package/dist/src/utils/clipboard-image.js +23 -23
  182. package/dist/src/utils/open-url.d.ts +56 -0
  183. package/dist/src/utils/open-url.js +58 -0
  184. package/dist/src/utils/open-url.test.d.ts +1 -0
  185. package/dist/src/utils/open-url.test.js +86 -0
  186. package/dist/src/utils/settings.d.ts +12 -0
  187. package/dist/src/utils/settings.js +48 -0
  188. package/dist/src/utils/side-question.js +2 -2
  189. package/dist/src/utils/skills.js +3 -3
  190. package/dist/src/verify/__tests__/coverage-parsers.test.js +30 -30
  191. package/dist/src/verify/environment.js +2 -1
  192. package/package.json +1 -1
  193. package/dist/src/pil/layer16-clarity.test.js +0 -31
  194. /package/dist/src/{pil/layer16-clarity.test.d.ts → council/__tests__/clarification-prompt.test.d.ts} +0 -0
@@ -1,22 +1,24 @@
1
- import type { TaskType } from "./types.js";
2
- export interface L1Signal {
3
- confidence: number;
4
- taskType: TaskType | null;
5
- complexity: "low" | "medium" | "high";
6
- }
7
- export declare function isDirectImperative(raw: string): boolean;
8
- export declare function canInferOutcome(taskType: TaskType | null, raw: string): boolean;
9
1
  /**
10
- * PIL-L6 fix — operational-domain scope (CI, deploy, build, lint) implies
11
- * scope is the project's pipeline/infra, not a specific file. "fix ci fail"
12
- * doesn't have a file path but the scope is unambiguous: it's the .github/
13
- * workflows + whatever those workflows run. Treat as scoped for auto-pass.
2
+ * src/pil/clarity-gate.ts
3
+ *
4
+ * Phase 2 (2026-06-16): the regex/keyword ASK gate (`shouldAutoPass`,
5
+ * `canInferOutcome`, and the per-modality scope detectors) was removed. The
6
+ * configured chat model is now the sole decider of whether a turn needs
7
+ * clarification — see `proposeModelGaps` in `discovery.ts`. Keyword heuristics
8
+ * deciding what/whether to ask were "bad bad bad UX" (miss billions of cases)
9
+ * per the user directive; there is no regex fallback by design.
10
+ *
11
+ * Two helpers survive because they are NOT ask-gating:
12
+ * - `detectNoClarifySignal` — honours an explicit USER instruction ("don't
13
+ * ask" / "đừng hỏi"). That is user consent, not classification.
14
+ * - `hasOperationalScope` — used only by `getAutofilledOutcome` to pick a
15
+ * better outcome LABEL for CI/build/deploy debug turns (output polish, not
16
+ * a decision about whether to interview).
17
+ */
18
+ /**
19
+ * Operational-domain detector (CI / deploy / build / lint). Used by
20
+ * `getAutofilledOutcome` to refine the resolved outcome label for pipeline
21
+ * debug turns; it no longer gates any askcard.
14
22
  */
15
23
  export declare function hasOperationalScope(raw: string): boolean;
16
- export declare function countFileReferences(raw: string): number;
17
- export declare function hasExplicitScope(raw: string): boolean;
18
- export declare function hasImageScope(raw: string): boolean;
19
- export declare function hasExternalInfoScope(raw: string): boolean;
20
- export declare function hasWholeRepoScope(raw: string): boolean;
21
- export declare function hasSelfContainedComputationScope(raw: string): boolean;
22
- export declare function shouldAutoPass(l1: L1Signal, raw: string): boolean;
24
+ export declare function detectNoClarifySignal(raw: string): boolean;
@@ -1,162 +1,35 @@
1
- import { getAutoPassThreshold } from "./config.js";
2
1
  /**
3
- * A direct imperative command — "run the tests", "echo ok", "show the config",
4
- * "list the ports" — has a self-evident outcome (the command executes / the
5
- * thing is shown), so it should NOT trigger an outcome-clarification askcard.
6
- * Requires an executable verb at the very start followed by a concrete object
7
- * (a bare "run" with no object stays ambiguous → false).
8
- */
9
- const DIRECT_IMPERATIVE_RE = /^\s*(run|execute|show|list|print|echo)\b\s+\S/i;
10
- export function isDirectImperative(raw) {
11
- return DIRECT_IMPERATIVE_RE.test(raw);
12
- }
13
- export function canInferOutcome(taskType, raw) {
14
- if (!taskType)
15
- return false;
16
- // PIL clarity over-trigger fix: a "general" prompt normally can't infer its
17
- // outcome, but a direct imperative command is the exception — its outcome is
18
- // obvious, so asking "what's the expected outcome?" is pure noise.
19
- if (taskType === "general")
20
- return isDirectImperative(raw);
21
- const hasErrorRef = /error|exception|stack|TypeError|Cannot|failed|crash|fail(?:s|ed|ing)?|broken|red/i.test(raw);
22
- const hasFileLineRef = /\.\w+:\d+/.test(raw);
23
- const hasTargetState = /should|must|expect|return|produce|output|become/i.test(raw);
24
- const hasAddPattern = /\b(add|create|implement|write|generate)\b.*\b(to|in|for|into)\b/i.test(raw);
25
- // PIL-L6 fix — explicit goal phrase in the prompt is itself an outcome
26
- // ("goal sẽ là ci green", "want: tests passing", "expect: 0 errors").
27
- // Without this, debug prompts that name the desired end-state still
28
- // tripped the interview because none of the verb-noun patterns matched.
29
- const hasExplicitGoal = /\b(goal|target|expect|want|mong muốn|mong muon|kết quả|ket qua)\b[:\s]/i.test(raw);
30
- return hasErrorRef || hasFileLineRef || hasTargetState || hasAddPattern || hasExplicitGoal;
31
- }
32
- /**
33
- * PIL-L6 fix — operational-domain scope (CI, deploy, build, lint) implies
34
- * scope is the project's pipeline/infra, not a specific file. "fix ci fail"
35
- * doesn't have a file path but the scope is unambiguous: it's the .github/
36
- * workflows + whatever those workflows run. Treat as scoped for auto-pass.
37
- */
38
- export function hasOperationalScope(raw) {
39
- return /\b(ci|cd|build|deploy(?:ment)?|action(?:s)?|workflow|pipeline|lint|tests?|coverage|gh\s+(check|run|workflow))\b/i.test(raw);
40
- }
41
- export function countFileReferences(raw) {
42
- return (raw.match(/[\w-]+\.\w{1,5}/g) ?? []).filter((m) => /\.(ts|tsx|js|jsx|py|rs|go|java|cs|rb|vue|svelte|css|scss|json|yaml|yml|toml|md)$/i.test(m)).length;
43
- }
44
- export function hasExplicitScope(raw) {
45
- return /\b(src\/|lib\/|app\/|pages\/|components\/|modules\/|packages\/)\S+/.test(raw);
46
- }
47
- /**
48
- * An image-analysis prompt is scoped to the IMAGE, not the codebase. "analyze
49
- * diagram.png", "take a screenshot and describe it" name their target directly,
50
- * so the "Which part of the codebase should this target?" askcard is
51
- * nonsensical for them — exactly like operational (CI/build) prompts are scoped
52
- * to the pipeline (see hasOperationalScope). Detect a concrete image signal: an
53
- * image file extension, a data:image URI, or an unambiguous image noun.
2
+ * src/pil/clarity-gate.ts
54
3
  *
55
- * Deliberately NARROW: a false positive here SUPPRESSES a legitimate clarifying
56
- * question (quality risk), so overloaded words are excluded
57
- * - "logo" / "icon" / "diagram" / "chart" / "mockup" appear in real codebase
58
- * tasks ("add a logo to the header"),
59
- * - bare "image" collides with container/Docker usage ("rebuild the image"),
60
- * - "picture" collides with the "bigger picture" idiom,
61
- * - Vietnamese substrings (ảnh/hình) collide with frequent non-image words
62
- * ("ảnh hưởng", "màn hình", "hình thức").
63
- * Only a file extension, data:image URI, "screenshot", or "photo" qualify.
64
- */
65
- const IMAGE_SCOPE_RE = /\.(png|jpe?g|gif|webp|svg|bmp|tiff?|heic|avif|ico)\b|data:image\/|\bscreen-?shots?\b|\bphotos?\b/i;
66
- export function hasImageScope(raw) {
67
- return IMAGE_SCOPE_RE.test(raw);
68
- }
69
- /**
70
- * A web-search / external-information prompt ("search the web for X", "google
71
- * the error", a bare URL, "latest news on Y") is scoped to the WEB, not the
72
- * codebase, so the "Which part of the codebase should this target?" askcard is
73
- * nonsensical for it — symmetric to hasOperationalScope / hasImageScope. (Live:
74
- * "search the web for the latest vitest release notes" → taskType=analyze fired
75
- * the scope askcard and recorded a wrong scope of "src/mcp".)
4
+ * Phase 2 (2026-06-16): the regex/keyword ASK gate (`shouldAutoPass`,
5
+ * `canInferOutcome`, and the per-modality scope detectors) was removed. The
6
+ * configured chat model is now the sole decider of whether a turn needs
7
+ * clarification see `proposeModelGaps` in `discovery.ts`. Keyword heuristics
8
+ * deciding what/whether to ask were "bad bad bad UX" (miss billions of cases)
9
+ * per the user directive; there is no regex fallback by design.
76
10
  *
77
- * Deliberately NARROW only UNAMBIGUOUSLY-external intent. It must not reuse
78
- * the broad hasDocsSignal vocabulary (library/api/install/package), because
79
- * those words routinely describe real codebase tasks ("add the zod library to
80
- * the auth module") that genuinely need the scope askcard. In particular a bare
81
- * "search" is excluded so "search the codebase" / "implement the search
82
- * feature" still get scoped.
11
+ * Two helpers survive because they are NOT ask-gating:
12
+ * - `detectNoClarifySignal` honours an explicit USER instruction ("don't
13
+ * ask" / "đừng hỏi"). That is user consent, not classification.
14
+ * - `hasOperationalScope` used only by `getAutofilledOutcome` to pick a
15
+ * better outcome LABEL for CI/build/deploy debug turns (output polish, not
16
+ * a decision about whether to interview).
83
17
  */
84
- const EXTERNAL_INFO_SCOPE_RE = /https?:\/\/\S+|\bsearch\s+(the\s+)?(web|internet|online)\b|\bweb\s*search\b|\bon\s+the\s+(web|internet)\b|\bgoogle\b|\b(news|weather|headlines)\b/i;
85
- export function hasExternalInfoScope(raw) {
86
- return EXTERNAL_INFO_SCOPE_RE.test(raw);
87
- }
88
18
  /**
89
- * A whole-repo / whole-project prompt ("đánh giá repo này", "review the entire
90
- * codebase", "audit the whole project") is ALREADY scoped — to everything — so
91
- * the "Which part of the codebase should this target?" askcard is nonsensical
92
- * (and worse, it recommends a single bounded context like "src/cli" as the
93
- * default, which is wrong for a repo-wide eval). Symmetric to the other scope
94
- * predicates. Live: gemini-2.5-flash classified "đánh giá repo …" as analyze and
95
- * got the scope askcard whose recommended option was a narrow subdir.
96
- *
97
- * Deliberately NARROW — it must NOT fire on a narrow task that merely mentions a
98
- * repo/project ("add X to this repo", "fix the bug in the project"), or those
99
- * would wrongly skip a legitimate scope question. So it requires EITHER an
100
- * explicit wholeness qualifier (whole/entire/all/toàn bộ/cả) on a repo/project/
101
- * codebase noun, OR an evaluation/overview verb (review/audit/evaluate/assess/
102
- * analyze/overview · đánh giá/phân tích/tổng quan/kiểm tra) applied to that noun.
19
+ * Operational-domain detector (CI / deploy / build / lint). Used by
20
+ * `getAutofilledOutcome` to refine the resolved outcome label for pipeline
21
+ * debug turns; it no longer gates any askcard.
103
22
  */
104
- const WHOLE_REPO_SCOPE_RE =
105
- // NOTE: leading anchors on Vietnamese-initial alternatives use (?:^|\s) not
106
- // \b — JS \b is ASCII-only and never matches before a non-ASCII letter like
107
- // "đ", so "\bđánh" would silently fail to match "đánh giá repo".
108
- /\b(whole|entire|overall|all\s+of\s+the|across\s+the)\s+(repo(?:sitory)?|code-?base|project)\b|(?:^|\s)(toàn\s*bộ|toan\s*bo|cả|ca)\s+(repo|dự\s*án|du\s*an|m[ãa]\s*ngu[ồo]n|code-?base|project)\b|\b(review|audit|evaluate|assess|analy[sz]e|summari[sz]e|overview\s+of|summary\s+of)\s+(?:\S+\s+){0,2}?(repo(?:sitory)?|code-?base|project)\b|(?:^|\s)(đánh\s*giá|danh\s*gia|phân\s*tích|phan\s*tich|tổng\s*quan|tong\s*quan|kiểm\s*tra|kiem\s*tra|tóm\s*tắt|tom\s*tat)\s+(?:\S+\s+){0,2}?(toàn|toan|repo|dự\s*án|du\s*an|m[ãa]\s*ngu[ồo]n|code-?base|project)\b/i;
109
- export function hasWholeRepoScope(raw) {
110
- return WHOLE_REPO_SCOPE_RE.test(raw);
111
- }
112
- /**
113
- * A self-contained computation / reasoning prompt supplies its operand data
114
- * INLINE ("Compute f([3,1,2]) …", "what is the median of [10, 4, 7]?") — the
115
- * task's target is the data in the prompt, not the codebase, so the "Which part
116
- * of the codebase should this target?" askcard is nonsensical for it. Symmetric
117
- * to hasOperationalScope / hasImageScope / hasExternalInfoScope / hasWholeRepoScope.
118
- *
119
- * Live: "Compute f([3,1,2]) where f sorts the list ascending then returns the
120
- * sum of the first two elements." classified taskType=analyze — the regex
121
- * classifier matched the bare word "list" (regex:read, conf 0.80, which also
122
- * skips the brain) — and fired BOTH the pil-interview scope askcard (auto
123
- * "Entire project") and the pil-acceptance card on a pure math problem.
124
- *
125
- * Deliberately NARROW — a false positive here SUPPRESSES a legitimate scope
126
- * question (quality risk), so it requires BOTH:
127
- * 1. an inline DATA literal — a bracketed comma-list of >=2 numeric or quoted
128
- * string values (`[3, 1, 2]`, `["a", "b"]`). A bracketed list of bare
129
- * identifiers (`[auth.ts, session.ts]`) is NOT data — those are file/symbol
130
- * references and stay codebase-scoped; the regex only accepts numbers and
131
- * quoted strings, so it never matches them. Single-element `[0]` (array
132
- * indexing) is excluded by the >=2-element requirement.
133
- * 2. computation framing — a compute/evaluate/sort/sum/statistic verb or a
134
- * "what is …" / "given the array …" question frame.
135
- * The AND keeps real codebase tasks that merely embed a literal (e.g. "set the
136
- * default retry delays to [100, 200, 400] in the config") correctly scoped.
137
- */
138
- const INLINE_DATA_LITERAL_RE = /\[\s*(?:-?\d+(?:\.\d+)?|"[^"]*"|'[^']*')(?:\s*,\s*(?:-?\d+(?:\.\d+)?|"[^"]*"|'[^']*'))+\s*\]/;
139
- const COMPUTE_FRAMING_RE = /\b(comput(?:e|ing)|calculat(?:e|ing|ion)|evaluat(?:e|ing)|solve|sort(?:s|ed|ing)?|sum|median|mean|average|max(?:imum)?|min(?:imum)?|largest|smallest|reverse[ds]?|result\s+of|what(?:'?s|\s+is|\s+are)|given\s+(?:the\s+)?(?:array|list|sequence|set|matrix|string|numbers?))\b/i;
140
- export function hasSelfContainedComputationScope(raw) {
141
- return INLINE_DATA_LITERAL_RE.test(raw) && COMPUTE_FRAMING_RE.test(raw);
23
+ export function hasOperationalScope(raw) {
24
+ return /\b(ci|cd|build|deploy(?:ment)?|action(?:s)?|workflow|pipeline|lint|tests?|coverage|gh\s+(check|run|workflow))\b/i.test(raw);
142
25
  }
143
- export function shouldAutoPass(l1, raw) {
144
- if (l1.confidence < getAutoPassThreshold())
145
- return false;
146
- if (!canInferOutcome(l1.taskType, raw))
147
- return false;
148
- // PIL-L6 fix — debug prompts about CI/build/deploy don't need a file path
149
- // because their scope is the pipeline itself. Operational scope counts.
150
- if (countFileReferences(raw) === 0 &&
151
- !hasExplicitScope(raw) &&
152
- !hasOperationalScope(raw) &&
153
- !hasImageScope(raw) &&
154
- !hasExternalInfoScope(raw) &&
155
- !hasWholeRepoScope(raw) &&
156
- !hasSelfContainedComputationScope(raw))
157
- return false;
158
- if (l1.complexity === "high")
159
- return false;
160
- return true;
26
+ // The user explicitly told the agent NOT to clarify ("don't ask", "trả lời
27
+ // thẳng"). When present, discovery skips ALL interview + acceptance cards. Narrow
28
+ // on purpose: the idiom "don't ask me why" (seeking an explanation, not a
29
+ // directive to skip questions) is excluded via a negative lookahead. EN + VI
30
+ // (with diacritics + bare-ASCII transliterations).
31
+ const NO_CLARIFY_RE = /\b(?:don'?t|do not)\s+ask(?!\s+me\s+(?:why|how|what))\b|\bno\s+(?:questions?|clarif(?:ication|ying)|interview)\b|\bwithout\s+asking\b|\bjust\s+answer\b|\banswer\s+(?:me\s+)?directly\b|\bstop\s+asking\b|đừng\s+hỏi|không\s+(?:cần\s+)?hỏi|khỏi\s+hỏi|trả\s+lời\s+(?:thẳng|luôn|liền|ngay|trực\s*tiếp)|\bdung\s+hoi\b|\bkhong\s+(?:can\s+)?hoi\b|\btra\s+loi\s+(?:thang|luon|lien|ngay)\b/i;
32
+ export function detectNoClarifySignal(raw) {
33
+ return !!raw && NO_CLARIFY_RE.test(raw);
161
34
  }
162
35
  //# sourceMappingURL=clarity-gate.js.map
@@ -5,6 +5,14 @@
5
5
  * Default OFF during rollout; flip to ON after dual-run validation.
6
6
  */
7
7
  export declare function isUnifiedPilEnabled(): boolean;
8
+ /**
9
+ * MUONROI_LLM_FIRST_CLASSIFY: model-first Layer-1 classification. When enabled
10
+ * (default), the configured model classifies taskType/intentKind/style at the
11
+ * top of the turn and the brittle keyword-regex cascade becomes the OFFLINE
12
+ * fallback (used only when the model call fails / is not wired). Set to "0" to
13
+ * revert to the regex-first cascade. Requires opts.llmFallback to be wired
14
+ * (the orchestrator does this on the main path); without it, the cascade runs.
15
+ */
16
+ export declare function isLlmFirstClassifyEnabled(): boolean;
8
17
  export declare function isDiscoveryEnabled(): boolean;
9
- export declare function getAutoPassThreshold(): number;
10
18
  export declare function getMaxInterviewQuestions(): number;
@@ -11,13 +11,24 @@ export function isUnifiedPilEnabled() {
11
11
  return true;
12
12
  return false;
13
13
  }
14
+ /**
15
+ * MUONROI_LLM_FIRST_CLASSIFY: model-first Layer-1 classification. When enabled
16
+ * (default), the configured model classifies taskType/intentKind/style at the
17
+ * top of the turn and the brittle keyword-regex cascade becomes the OFFLINE
18
+ * fallback (used only when the model call fails / is not wired). Set to "0" to
19
+ * revert to the regex-first cascade. Requires opts.llmFallback to be wired
20
+ * (the orchestrator does this on the main path); without it, the cascade runs.
21
+ */
22
+ export function isLlmFirstClassifyEnabled() {
23
+ return process.env.MUONROI_LLM_FIRST_CLASSIFY !== "0";
24
+ }
14
25
  export function isDiscoveryEnabled() {
15
26
  return process.env.MUONROI_PIL_DISCOVERY !== "0";
16
27
  }
17
- export function getAutoPassThreshold() {
18
- const v = Number(process.env.MUONROI_PIL_AUTOPASS_THRESHOLD);
19
- return Number.isFinite(v) && v >= 0.5 && v <= 1.0 ? v : 0.85;
20
- }
28
+ // Phase 2 (2026-06-16): getAutoPassThreshold() was removed with the regex
29
+ // auto-pass gate (shouldAutoPass). The model now decides whether a turn needs
30
+ // clarification, so there is no confidence threshold to tune. The
31
+ // MUONROI_PIL_AUTOPASS_THRESHOLD env var is therefore inert.
21
32
  export function getMaxInterviewQuestions() {
22
33
  const v = Number(process.env.MUONROI_PIL_MAX_QUESTIONS);
23
34
  return Number.isFinite(v) && v >= 1 && v <= 5 ? v : 3;