@praneeth_54/agentdoctor 3.0.2 → 3.0.3
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/CHANGELOG.md +33 -2
- package/README.md +5 -4
- package/dist/agent/chat/deterministic.d.ts +2 -0
- package/dist/agent/chat/deterministic.js +91 -3
- package/dist/agent/chat/response.js +25 -4
- package/dist/agent/chat/service.d.ts +1 -0
- package/dist/agent/chat/service.js +28 -10
- package/dist/agent/chat/types.d.ts +3 -0
- package/dist/agent/context/brain-evidence.d.ts +26 -0
- package/dist/agent/context/brain-evidence.js +296 -0
- package/dist/agent/context/retrieve.d.ts +7 -1
- package/dist/agent/context/retrieve.js +204 -63
- package/dist/agent/progress.d.ts +10 -0
- package/dist/agent/progress.js +4 -0
- package/dist/cli/ask-progress.d.ts +17 -0
- package/dist/cli/ask-progress.js +85 -0
- package/dist/cli/commands/chat.d.ts +6 -0
- package/dist/cli/commands/chat.js +16 -0
- package/dist/cli/program.js +2 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/core/understanding/brain/storage/store.js +0 -1
- package/package.json +1 -1
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { colors, symbolFail, symbolOk } from "../utils/colors.js";
|
|
2
|
+
const STAGE_LABELS = {
|
|
3
|
+
understand: "Understanding question",
|
|
4
|
+
search: "Searching project knowledge",
|
|
5
|
+
retrieve: "Retrieving relevant evidence",
|
|
6
|
+
verify: "Verifying evidence",
|
|
7
|
+
prepare: "Preparing answer",
|
|
8
|
+
};
|
|
9
|
+
const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
10
|
+
/**
|
|
11
|
+
* Human-readable ask progress. Stages must be driven by real operations.
|
|
12
|
+
* Animation uses setInterval only for frame updates while work is in flight —
|
|
13
|
+
* never to invent delay.
|
|
14
|
+
*/
|
|
15
|
+
export function createAskProgress(options = {}) {
|
|
16
|
+
const enabled = options.enabled !== false;
|
|
17
|
+
const stream = options.stream ?? process.stderr;
|
|
18
|
+
const tty = options.isTTY ??
|
|
19
|
+
Boolean(stream && typeof stream === "object" && "isTTY" in stream && stream.isTTY);
|
|
20
|
+
let frame = 0;
|
|
21
|
+
let timer;
|
|
22
|
+
let activeLabel;
|
|
23
|
+
let stopped = false;
|
|
24
|
+
const clearLine = () => {
|
|
25
|
+
if (!tty || !enabled)
|
|
26
|
+
return;
|
|
27
|
+
stream.write("\r\x1b[K");
|
|
28
|
+
};
|
|
29
|
+
const stopSpin = () => {
|
|
30
|
+
if (timer) {
|
|
31
|
+
clearInterval(timer);
|
|
32
|
+
timer = undefined;
|
|
33
|
+
}
|
|
34
|
+
clearLine();
|
|
35
|
+
};
|
|
36
|
+
const renderSpin = () => {
|
|
37
|
+
if (!tty || !enabled || !activeLabel || stopped)
|
|
38
|
+
return;
|
|
39
|
+
const glyph = SPINNER_FRAMES[frame % SPINNER_FRAMES.length];
|
|
40
|
+
frame += 1;
|
|
41
|
+
stream.write(`\r${colors.cyan(glyph)} ${activeLabel}...`);
|
|
42
|
+
};
|
|
43
|
+
const writeDone = (ok, label, detail) => {
|
|
44
|
+
if (!enabled || stopped)
|
|
45
|
+
return;
|
|
46
|
+
const mark = ok ? symbolOk() : symbolFail();
|
|
47
|
+
const suffix = detail ? colors.dim(` — ${detail}`) : "";
|
|
48
|
+
stream.write(`${mark} ${label}${suffix}\n`);
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
stage(id, state, detail) {
|
|
52
|
+
if (!enabled || stopped)
|
|
53
|
+
return;
|
|
54
|
+
const label = STAGE_LABELS[id];
|
|
55
|
+
if (state === "start") {
|
|
56
|
+
stopSpin();
|
|
57
|
+
activeLabel = label;
|
|
58
|
+
if (tty) {
|
|
59
|
+
frame = 0;
|
|
60
|
+
renderSpin();
|
|
61
|
+
timer = setInterval(renderSpin, 80);
|
|
62
|
+
timer.unref?.();
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
stream.write(`${label}...\n`);
|
|
66
|
+
}
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
stopSpin();
|
|
70
|
+
activeLabel = undefined;
|
|
71
|
+
writeDone(state === "ok", state === "ok" && id === "prepare" ? "Answer ready" : label, detail);
|
|
72
|
+
},
|
|
73
|
+
stop() {
|
|
74
|
+
stopSpin();
|
|
75
|
+
activeLabel = undefined;
|
|
76
|
+
stopped = true;
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export function silentAskProgress() {
|
|
81
|
+
return {
|
|
82
|
+
stage() { },
|
|
83
|
+
stop() { },
|
|
84
|
+
};
|
|
85
|
+
}
|
|
@@ -5,6 +5,12 @@ export declare function runAskCommand(options: {
|
|
|
5
5
|
json?: boolean;
|
|
6
6
|
/** Test-only: force mock provider */
|
|
7
7
|
useMock?: boolean;
|
|
8
|
+
/** Test override: force progress enabled/disabled */
|
|
9
|
+
progressEnabled?: boolean;
|
|
10
|
+
/** Test override: progress stream */
|
|
11
|
+
progressStream?: NodeJS.WritableStream;
|
|
12
|
+
/** Test override: treat progress stream as TTY */
|
|
13
|
+
progressIsTTY?: boolean;
|
|
8
14
|
}): Promise<ExitCode>;
|
|
9
15
|
export declare function runChatCommand(options: {
|
|
10
16
|
root?: string;
|
|
@@ -5,6 +5,7 @@ import { MockModelProvider, createModelProvider, loadAiConfig } from "../../ai/i
|
|
|
5
5
|
import { EXIT_CODES } from "../../types/index.js";
|
|
6
6
|
import { resolveCliProjectRoot } from "../safe-root.js";
|
|
7
7
|
import { colors } from "../../utils/colors.js";
|
|
8
|
+
import { createAskProgress } from "../ask-progress.js";
|
|
8
9
|
function printBanner(options) {
|
|
9
10
|
const lines = [
|
|
10
11
|
"",
|
|
@@ -58,13 +59,21 @@ export async function runAskCommand(options) {
|
|
|
58
59
|
}
|
|
59
60
|
const root = gated.root;
|
|
60
61
|
const provider = options.useMock ? new MockModelProvider() : createModelProvider(loadAiConfig());
|
|
62
|
+
const progressEnabled = options.progressEnabled ?? !options.json;
|
|
63
|
+
const progress = createAskProgress({
|
|
64
|
+
enabled: progressEnabled,
|
|
65
|
+
...(options.progressStream ? { stream: options.progressStream } : {}),
|
|
66
|
+
...(options.progressIsTTY !== undefined ? { isTTY: options.progressIsTTY } : {}),
|
|
67
|
+
});
|
|
61
68
|
const chat = new ChatService({
|
|
62
69
|
root,
|
|
63
70
|
provider,
|
|
64
71
|
persistAudit: !options.useMock,
|
|
72
|
+
progress,
|
|
65
73
|
});
|
|
66
74
|
try {
|
|
67
75
|
const response = await chat.ask(options.question);
|
|
76
|
+
progress.stop();
|
|
68
77
|
if (options.json) {
|
|
69
78
|
process.stdout.write(`${JSON.stringify(response, null, 2)}\n`);
|
|
70
79
|
}
|
|
@@ -78,7 +87,14 @@ export async function runAskCommand(options) {
|
|
|
78
87
|
}
|
|
79
88
|
return EXIT_CODES.SUCCESS;
|
|
80
89
|
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
progress.stop();
|
|
92
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
93
|
+
console.error(`AgentDoctor error:\n${message}`);
|
|
94
|
+
return EXIT_CODES.INTERNAL_ERROR;
|
|
95
|
+
}
|
|
81
96
|
finally {
|
|
97
|
+
progress.stop();
|
|
82
98
|
await chat.end();
|
|
83
99
|
}
|
|
84
100
|
}
|
package/dist/cli/program.js
CHANGED
|
@@ -1255,7 +1255,8 @@ export function createProgram() {
|
|
|
1255
1255
|
.argument("<question>", "Question about the project")
|
|
1256
1256
|
.argument("[path]", "Repository path (default: current directory)")
|
|
1257
1257
|
.option("--json", "Emit JSON response", false)
|
|
1258
|
-
.action(async (question, pathArg,
|
|
1258
|
+
.action(async (question, pathArg, _options, command) => {
|
|
1259
|
+
const options = command.optsWithGlobals();
|
|
1259
1260
|
process.exitCode = await runAskCommand({
|
|
1260
1261
|
question,
|
|
1261
1262
|
root: resolveTargetArgument(pathArg),
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentId } from "./types/index.js";
|
|
2
|
-
export declare const PACKAGE_VERSION = "3.0.
|
|
2
|
+
export declare const PACKAGE_VERSION = "3.0.3";
|
|
3
3
|
export declare const DEFAULT_MAX_FILE_SIZE_BYTES: number;
|
|
4
4
|
/** Directories skipped during normal discovery (unless a rule needs them later). */
|
|
5
5
|
export declare const DEFAULT_IGNORE_DIRECTORIES: Set<string>;
|
package/dist/constants.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const PACKAGE_VERSION = "3.0.
|
|
1
|
+
export const PACKAGE_VERSION = "3.0.3";
|
|
2
2
|
export const DEFAULT_MAX_FILE_SIZE_BYTES = 2 * 1024 * 1024; // 2 MiB
|
|
3
3
|
/** Directories skipped during normal discovery (unless a rule needs them later). */
|
|
4
4
|
export const DEFAULT_IGNORE_DIRECTORIES = new Set([
|
|
@@ -128,7 +128,6 @@ export class LocalBrainStore {
|
|
|
128
128
|
await fs.mkdir(path.join(this.root, "deltas"), { recursive: true });
|
|
129
129
|
}
|
|
130
130
|
async readMeta() {
|
|
131
|
-
await this.ensureRoot();
|
|
132
131
|
try {
|
|
133
132
|
const raw = await fs.readFile(this.metaPath(), "utf8");
|
|
134
133
|
const parsed = JSON.parse(raw);
|
package/package.json
CHANGED