muonroi-cli 1.4.1 → 1.5.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.
- package/LICENSE +21 -21
- package/README.md +122 -122
- package/dist/packages/agent-harness-core/src/predicate.d.ts +1 -1
- package/dist/src/agent-harness/__tests__/mock-model.spec.js +48 -1
- package/dist/src/agent-harness/mock-model.d.ts +11 -0
- package/dist/src/agent-harness/mock-model.js +21 -0
- package/dist/src/cli/cost-forensics.js +12 -12
- package/dist/src/council/__tests__/clarification-prompt.test.js +51 -0
- package/dist/src/council/__tests__/clarifier-ready-gate.test.js +32 -0
- package/dist/src/council/__tests__/decisions-lock.test.js +17 -1
- package/dist/src/council/__tests__/oauth-reachable.test.d.ts +1 -0
- package/dist/src/council/__tests__/oauth-reachable.test.js +31 -0
- package/dist/src/council/__tests__/parse-outcome-fallback.test.js +11 -0
- package/dist/src/council/clarifier.js +9 -1
- package/dist/src/council/debate.js +5 -1
- package/dist/src/council/decisions-lock.js +3 -3
- package/dist/src/council/index.js +12 -5
- package/dist/src/council/leader.d.ts +0 -17
- package/dist/src/council/leader.js +22 -15
- package/dist/src/council/planner.js +1 -1
- package/dist/src/council/prompts.js +63 -57
- package/dist/src/council/types.d.ts +7 -0
- package/dist/src/ee/__tests__/ee-onboarding.test.d.ts +1 -0
- package/dist/src/ee/__tests__/ee-onboarding.test.js +32 -0
- package/dist/src/ee/auth.d.ts +9 -0
- package/dist/src/ee/auth.js +19 -0
- package/dist/src/ee/ee-onboarding.d.ts +5 -0
- package/dist/src/ee/ee-onboarding.js +76 -0
- package/dist/src/generated/version.d.ts +1 -1
- package/dist/src/generated/version.js +1 -1
- package/dist/src/headless/output.js +6 -4
- package/dist/src/headless/output.test.js +4 -3
- package/dist/src/index.js +20 -1
- package/dist/src/mcp/__tests__/auto-setup.test.js +74 -0
- package/dist/src/mcp/__tests__/client-pool.spec.d.ts +1 -0
- package/dist/src/mcp/__tests__/client-pool.spec.js +98 -0
- package/dist/src/mcp/__tests__/parallel-build.spec.d.ts +1 -0
- package/dist/src/mcp/__tests__/parallel-build.spec.js +67 -0
- package/dist/src/mcp/__tests__/smart-filter.test.js +56 -0
- package/dist/src/mcp/auto-setup.js +56 -2
- package/dist/src/mcp/client-pool.d.ts +46 -0
- package/dist/src/mcp/client-pool.js +212 -0
- package/dist/src/mcp/oauth-callback.js +2 -2
- package/dist/src/mcp/parse-headers.test.js +14 -14
- package/dist/src/mcp/runtime.d.ts +28 -0
- package/dist/src/mcp/runtime.js +117 -51
- package/dist/src/mcp/self-verify-runner.d.ts +14 -0
- package/dist/src/mcp/self-verify-runner.js +38 -0
- package/dist/src/mcp/setup-guide-text.d.ts +9 -0
- package/dist/src/mcp/setup-guide-text.js +84 -0
- package/dist/src/mcp/smart-filter.js +49 -0
- package/dist/src/mcp/smoke.test.js +43 -43
- package/dist/src/mcp/tools-server.d.ts +7 -0
- package/dist/src/mcp/tools-server.js +19 -22
- package/dist/src/models/catalog.json +349 -349
- package/dist/src/ops/__tests__/doctor-ee-health.test.js +21 -0
- package/dist/src/ops/doctor.d.ts +3 -2
- package/dist/src/ops/doctor.js +47 -11
- package/dist/src/ops/doctor.test.js +4 -3
- package/dist/src/orchestrator/__tests__/mcp-capability-block.test.d.ts +1 -0
- package/dist/src/orchestrator/__tests__/mcp-capability-block.test.js +39 -0
- package/dist/src/orchestrator/__tests__/project-stack.test.d.ts +1 -0
- package/dist/src/orchestrator/__tests__/project-stack.test.js +65 -0
- package/dist/src/orchestrator/batch-turn-runner.js +7 -11
- package/dist/src/orchestrator/message-processor.js +57 -27
- package/dist/src/orchestrator/orchestrator.js +26 -0
- package/dist/src/orchestrator/prompts.d.ts +51 -0
- package/dist/src/orchestrator/prompts.js +257 -134
- package/dist/src/orchestrator/scope-ceiling.js +6 -1
- package/dist/src/orchestrator/stream-runner.js +20 -15
- package/dist/src/orchestrator/text-tool-call-detector.test.js +13 -13
- package/dist/src/pil/__tests__/clarity-gate.test.js +24 -215
- package/dist/src/pil/__tests__/config.test.js +1 -17
- package/dist/src/pil/__tests__/discovery.test.js +144 -11
- package/dist/src/pil/__tests__/layer1-intent-trace.test.js +7 -2
- package/dist/src/pil/__tests__/layer1-intent.test.js +3 -0
- package/dist/src/pil/__tests__/layer16-clarity.test.js +32 -116
- package/dist/src/pil/__tests__/layer4-gsd.test.js +37 -0
- package/dist/src/pil/__tests__/layer6-output.test.js +137 -18
- package/dist/src/pil/__tests__/llm-classify.test.js +49 -2
- package/dist/src/pil/agent-operating-contract.d.ts +1 -1
- package/dist/src/pil/agent-operating-contract.js +2 -0
- package/dist/src/pil/agent-operating-contract.test.js +7 -2
- package/dist/src/pil/cheap-model-playbook.js +35 -35
- package/dist/src/pil/cheap-model-workbooks.js +16 -13
- package/dist/src/pil/clarity-gate.d.ts +21 -19
- package/dist/src/pil/clarity-gate.js +26 -153
- package/dist/src/pil/config.d.ts +9 -1
- package/dist/src/pil/config.js +15 -4
- package/dist/src/pil/discovery.js +211 -136
- package/dist/src/pil/layer1-intent.d.ts +12 -0
- package/dist/src/pil/layer1-intent.js +283 -38
- package/dist/src/pil/layer1-intent.test.js +210 -4
- package/dist/src/pil/layer16-clarity.d.ts +25 -11
- package/dist/src/pil/layer16-clarity.js +19 -306
- package/dist/src/pil/layer4-gsd.js +18 -6
- package/dist/src/pil/layer6-output.d.ts +2 -0
- package/dist/src/pil/layer6-output.js +137 -22
- package/dist/src/pil/llm-classify.d.ts +26 -0
- package/dist/src/pil/llm-classify.js +34 -5
- package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
- package/dist/src/pil/native-capabilities-workbook.js +82 -76
- package/dist/src/pil/schema.d.ts +8 -0
- package/dist/src/pil/schema.js +12 -1
- package/dist/src/pil/task-tier-map.js +4 -0
- package/dist/src/pil/types.d.ts +11 -1
- package/dist/src/product-loop/done-gate.js +3 -3
- package/dist/src/product-loop/loop-driver.js +18 -18
- package/dist/src/product-loop/progress-snapshot.js +4 -4
- package/dist/src/providers/auth/gemini-oauth.js +6 -15
- package/dist/src/providers/auth/grok-oauth.js +6 -15
- package/dist/src/providers/auth/openai-oauth.js +6 -15
- package/dist/src/providers/mcp-vision-bridge.js +48 -48
- package/dist/src/reporter/index.js +1 -1
- package/dist/src/scaffold/bb-ecosystem-apply.js +47 -47
- package/dist/src/scaffold/bb-quality-gate.js +5 -5
- package/dist/src/scaffold/continuation-prompt.js +60 -60
- package/dist/src/scaffold/init-new.js +453 -453
- package/dist/src/self-qa/__tests__/scenario-planner.test.js +3 -3
- package/dist/src/self-qa/agentic-loop.js +24 -19
- package/dist/src/self-qa/spec-emitter.js +26 -23
- package/dist/src/storage/__tests__/migrations.test.js +2 -2
- package/dist/src/storage/interaction-log.js +5 -5
- package/dist/src/storage/migrations.js +122 -122
- package/dist/src/storage/sessions.js +42 -42
- package/dist/src/storage/transcript.js +91 -84
- package/dist/src/storage/usage.js +14 -14
- package/dist/src/storage/workspaces.js +12 -12
- package/dist/src/tools/__tests__/native-tools.test.d.ts +1 -0
- package/dist/src/tools/__tests__/native-tools.test.js +53 -0
- package/dist/src/tools/git-safety.d.ts +61 -0
- package/dist/src/tools/git-safety.js +141 -0
- package/dist/src/tools/git-safety.test.d.ts +1 -0
- package/dist/src/tools/git-safety.test.js +111 -0
- package/dist/src/tools/native-tools.d.ts +31 -0
- package/dist/src/tools/native-tools.js +273 -0
- package/dist/src/tools/registry-git-safety.test.d.ts +7 -0
- package/dist/src/tools/registry-git-safety.test.js +92 -0
- package/dist/src/tools/registry.js +39 -4
- package/dist/src/ui/__tests__/markdown-render.test.d.ts +1 -0
- package/dist/src/ui/__tests__/markdown-render.test.js +48 -0
- package/dist/src/ui/app.js +0 -0
- package/dist/src/ui/components/message-view.js +4 -1
- package/dist/src/ui/components/structured-response-view.js +7 -3
- package/dist/src/ui/components/tool-group.js +7 -1
- package/dist/src/ui/markdown-render.d.ts +41 -0
- package/dist/src/ui/markdown-render.js +223 -0
- package/dist/src/ui/markdown.d.ts +10 -0
- package/dist/src/ui/markdown.js +12 -35
- package/dist/src/ui/slash/council-inspect.js +4 -4
- package/dist/src/ui/slash/export.js +4 -4
- package/dist/src/ui/utils/text.d.ts +8 -0
- package/dist/src/ui/utils/text.js +16 -0
- package/dist/src/ui/utils/text.test.d.ts +1 -0
- package/dist/src/ui/utils/text.test.js +23 -0
- package/dist/src/usage/ledger.js +48 -15
- package/dist/src/utils/__tests__/footprint-gitignore.test.d.ts +1 -0
- package/dist/src/utils/__tests__/footprint-gitignore.test.js +50 -0
- package/dist/src/utils/clipboard-image.js +23 -23
- package/dist/src/utils/open-url.d.ts +56 -0
- package/dist/src/utils/open-url.js +58 -0
- package/dist/src/utils/open-url.test.d.ts +1 -0
- package/dist/src/utils/open-url.test.js +86 -0
- package/dist/src/utils/settings.d.ts +12 -0
- package/dist/src/utils/settings.js +48 -0
- package/dist/src/utils/side-question.js +2 -2
- package/dist/src/utils/skills.js +3 -3
- package/dist/src/verify/__tests__/coverage-parsers.test.js +30 -30
- package/dist/src/verify/environment.js +2 -1
- package/package.json +1 -1
- package/dist/src/pil/layer16-clarity.test.js +0 -31
- /package/dist/src/{pil/layer16-clarity.test.d.ts → council/__tests__/clarification-prompt.test.d.ts} +0 -0
|
@@ -23,19 +23,19 @@
|
|
|
23
23
|
* Universal anti-ramble convergence block — applies to every task type.
|
|
24
24
|
* Kept tight; the per-task addendum below specialises it.
|
|
25
25
|
*/
|
|
26
|
-
export const CHEAP_MODEL_CONVERGENCE = `[CONVERGENCE — minimise tool calls; the system prompt + tools are re-sent every call, so each extra step is expensive]
|
|
27
|
-
|
|
28
|
-
- Plan the FEWEST reads you need, then read the specific file/section directly.
|
|
29
|
-
Do NOT broad-grep, re-read a file you already read, or explore "just in case".
|
|
30
|
-
- The moment you have enough to act, STOP investigating and make the change.
|
|
31
|
-
- Make the SMALLEST correct change for the request; do not widen scope.
|
|
32
|
-
- Finish the action before you answer — never stop mid-step (e.g. "I'm verifying…").
|
|
33
|
-
When done, state completion in ONE line (what changed + that it's verified);
|
|
34
|
-
no recap, no next-steps padding.
|
|
35
|
-
- GROUND every claim in what you actually read or ran THIS turn: cite real
|
|
36
|
-
file:line, and never invent counts, line numbers, names, or bugs. If a number
|
|
37
|
-
(test/file count) is not verified by a command you ran, run the check or mark
|
|
38
|
-
it "unverified" — do NOT guess a value or assert a finding you did not observe.
|
|
26
|
+
export const CHEAP_MODEL_CONVERGENCE = `[CONVERGENCE — minimise tool calls; the system prompt + tools are re-sent every call, so each extra step is expensive]
|
|
27
|
+
|
|
28
|
+
- Plan the FEWEST reads you need, then read the specific file/section directly.
|
|
29
|
+
Do NOT broad-grep, re-read a file you already read, or explore "just in case".
|
|
30
|
+
- The moment you have enough to act, STOP investigating and make the change.
|
|
31
|
+
- Make the SMALLEST correct change for the request; do not widen scope.
|
|
32
|
+
- Finish the action before you answer — never stop mid-step (e.g. "I'm verifying…").
|
|
33
|
+
When done, state completion in ONE line (what changed + that it's verified);
|
|
34
|
+
no recap, no next-steps padding.
|
|
35
|
+
- GROUND every claim in what you actually read or ran THIS turn: cite real
|
|
36
|
+
file:line, and never invent counts, line numbers, names, or bugs. If a number
|
|
37
|
+
(test/file count) is not verified by a command you ran, run the check or mark
|
|
38
|
+
it "unverified" — do NOT guess a value or assert a finding you did not observe.
|
|
39
39
|
- ANTI-MÙ: After compaction note or pre-warn, emit PRESERVE_FULL_CONTEXT (full) or KEEP_TOOL_IDS: id1,id2 to protect high-value (auto for read_file/grep on src/PLAN/error). Use the ee_query tool with "tool-artifact id=XXX" for on-demand full re-hydrate. Recall checkpoints. `;
|
|
40
40
|
/**
|
|
41
41
|
* Per-task-type addenda. Each is 1–2 tight lines targeting that type's most
|
|
@@ -47,6 +47,9 @@ const TASK_WORKBOOKS = {
|
|
|
47
47
|
"Never mask a failure to make it pass (no continue-on-error, swallowed catch, skipped test, `|| true`).",
|
|
48
48
|
generate: "GENERATE: confirm the target file + the surrounding pattern, write the new code to match it, then stop. " +
|
|
49
49
|
"Do not scaffold extras or restructure unrelated code.",
|
|
50
|
+
build: "BUILD: scaffold the MINIMUM runnable project/feature that satisfies the request, matching the chosen stack's " +
|
|
51
|
+
"conventions. Wire it end-to-end and verify it builds/runs before stopping. Do NOT add speculative features, " +
|
|
52
|
+
"extra files, or config the request did not ask for.",
|
|
50
53
|
refactor: "REFACTOR: change only what was named (rename/extract/move). Preserve behaviour; add nothing new.",
|
|
51
54
|
analyze: "ANALYZE: answer from what you have already read — do not read the whole codebase. Bullet findings, no narrative. " +
|
|
52
55
|
"For a repo/code review, base findings on the ACTUAL code you inspect (file sizes, structure, key modules), not just AGENTS.md/CLAUDE.md docs.",
|
|
@@ -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
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
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
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
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
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
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
|
-
|
|
105
|
-
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
package/dist/src/pil/config.d.ts
CHANGED
|
@@ -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;
|
package/dist/src/pil/config.js
CHANGED
|
@@ -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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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;
|