duocode 0.1.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/.env.example +36 -0
- package/LICENSE +21 -0
- package/README.md +52 -0
- package/dist/ast/context.d.ts +16 -0
- package/dist/ast/context.js +37 -0
- package/dist/ast/context.js.map +1 -0
- package/dist/ast/diff.d.ts +27 -0
- package/dist/ast/diff.js +44 -0
- package/dist/ast/diff.js.map +1 -0
- package/dist/ast/locks.d.ts +47 -0
- package/dist/ast/locks.js +88 -0
- package/dist/ast/locks.js.map +1 -0
- package/dist/ast/merge.d.ts +22 -0
- package/dist/ast/merge.js +120 -0
- package/dist/ast/merge.js.map +1 -0
- package/dist/ast/ownership.d.ts +31 -0
- package/dist/ast/ownership.js +111 -0
- package/dist/ast/ownership.js.map +1 -0
- package/dist/ast/parser.d.ts +44 -0
- package/dist/ast/parser.js +134 -0
- package/dist/ast/parser.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +423 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/doctor.d.ts +5 -0
- package/dist/commands/doctor.js +63 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/duo.d.ts +9 -0
- package/dist/commands/duo.js +285 -0
- package/dist/commands/duo.js.map +1 -0
- package/dist/commands/github.d.ts +2 -0
- package/dist/commands/github.js +85 -0
- package/dist/commands/github.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +33 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/negotiation.d.ts +2 -0
- package/dist/commands/negotiation.js +160 -0
- package/dist/commands/negotiation.js.map +1 -0
- package/dist/commands/repl_commands.d.ts +26 -0
- package/dist/commands/repl_commands.js +226 -0
- package/dist/commands/repl_commands.js.map +1 -0
- package/dist/commands/shell.d.ts +1 -0
- package/dist/commands/shell.js +110 -0
- package/dist/commands/shell.js.map +1 -0
- package/dist/commands/start.d.ts +2 -0
- package/dist/commands/start.js +231 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/task.d.ts +2 -0
- package/dist/commands/task.js +215 -0
- package/dist/commands/task.js.map +1 -0
- package/dist/config/loader.d.ts +193 -0
- package/dist/config/loader.js +106 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/context/project_context.d.ts +79 -0
- package/dist/context/project_context.js +292 -0
- package/dist/context/project_context.js.map +1 -0
- package/dist/context/token_budget.d.ts +35 -0
- package/dist/context/token_budget.js +81 -0
- package/dist/context/token_budget.js.map +1 -0
- package/dist/db/queries.d.ts +121 -0
- package/dist/db/queries.js +109 -0
- package/dist/db/queries.js.map +1 -0
- package/dist/db/schema.d.ts +110 -0
- package/dist/db/schema.js +346 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/duo/duo_orchestrator.d.ts +50 -0
- package/dist/duo/duo_orchestrator.js +510 -0
- package/dist/duo/duo_orchestrator.js.map +1 -0
- package/dist/duo/duo_session.d.ts +47 -0
- package/dist/duo/duo_session.js +127 -0
- package/dist/duo/duo_session.js.map +1 -0
- package/dist/duo/duo_types.d.ts +168 -0
- package/dist/duo/duo_types.js +53 -0
- package/dist/duo/duo_types.js.map +1 -0
- package/dist/duo/session_store.d.ts +71 -0
- package/dist/duo/session_store.js +177 -0
- package/dist/duo/session_store.js.map +1 -0
- package/dist/git/worktree.d.ts +21 -0
- package/dist/git/worktree.js +86 -0
- package/dist/git/worktree.js.map +1 -0
- package/dist/github/cache.d.ts +23 -0
- package/dist/github/cache.js +67 -0
- package/dist/github/cache.js.map +1 -0
- package/dist/github/issues.d.ts +17 -0
- package/dist/github/issues.js +93 -0
- package/dist/github/issues.js.map +1 -0
- package/dist/github/mcp_client.d.ts +57 -0
- package/dist/github/mcp_client.js +214 -0
- package/dist/github/mcp_client.js.map +1 -0
- package/dist/github/sync.d.ts +11 -0
- package/dist/github/sync.js +65 -0
- package/dist/github/sync.js.map +1 -0
- package/dist/github/webhook.d.ts +25 -0
- package/dist/github/webhook.js +197 -0
- package/dist/github/webhook.js.map +1 -0
- package/dist/negotiation/index.d.ts +1 -0
- package/dist/negotiation/index.js +2 -0
- package/dist/negotiation/index.js.map +1 -0
- package/dist/negotiation/protocol.d.ts +62 -0
- package/dist/negotiation/protocol.js +188 -0
- package/dist/negotiation/protocol.js.map +1 -0
- package/dist/orchestrator/complexity_scorer.d.ts +2 -0
- package/dist/orchestrator/complexity_scorer.js +79 -0
- package/dist/orchestrator/complexity_scorer.js.map +1 -0
- package/dist/orchestrator/dependency_graph.d.ts +7 -0
- package/dist/orchestrator/dependency_graph.js +73 -0
- package/dist/orchestrator/dependency_graph.js.map +1 -0
- package/dist/orchestrator/intent_parser.d.ts +11 -0
- package/dist/orchestrator/intent_parser.js +116 -0
- package/dist/orchestrator/intent_parser.js.map +1 -0
- package/dist/orchestrator/task_runner.d.ts +56 -0
- package/dist/orchestrator/task_runner.js +181 -0
- package/dist/orchestrator/task_runner.js.map +1 -0
- package/dist/orchestrator/types.d.ts +44 -0
- package/dist/orchestrator/types.js +21 -0
- package/dist/orchestrator/types.js.map +1 -0
- package/dist/providers/anthropic.d.ts +12 -0
- package/dist/providers/anthropic.js +258 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/auction.d.ts +42 -0
- package/dist/providers/auction.js +190 -0
- package/dist/providers/auction.js.map +1 -0
- package/dist/providers/base.d.ts +103 -0
- package/dist/providers/base.js +2 -0
- package/dist/providers/base.js.map +1 -0
- package/dist/providers/cost_tracker.d.ts +45 -0
- package/dist/providers/cost_tracker.js +111 -0
- package/dist/providers/cost_tracker.js.map +1 -0
- package/dist/providers/duo_pair_router.d.ts +11 -0
- package/dist/providers/duo_pair_router.js +67 -0
- package/dist/providers/duo_pair_router.js.map +1 -0
- package/dist/providers/factory.d.ts +7 -0
- package/dist/providers/factory.js +130 -0
- package/dist/providers/factory.js.map +1 -0
- package/dist/providers/grading_rubric.d.ts +37 -0
- package/dist/providers/grading_rubric.js +238 -0
- package/dist/providers/grading_rubric.js.map +1 -0
- package/dist/providers/openai.d.ts +12 -0
- package/dist/providers/openai.js +229 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/openrouter.d.ts +14 -0
- package/dist/providers/openrouter.js +178 -0
- package/dist/providers/openrouter.js.map +1 -0
- package/dist/providers/performance_tracker.d.ts +21 -0
- package/dist/providers/performance_tracker.js +63 -0
- package/dist/providers/performance_tracker.js.map +1 -0
- package/dist/providers/registry_loader.d.ts +6 -0
- package/dist/providers/registry_loader.js +54 -0
- package/dist/providers/registry_loader.js.map +1 -0
- package/dist/providers/retry.d.ts +66 -0
- package/dist/providers/retry.js +203 -0
- package/dist/providers/retry.js.map +1 -0
- package/dist/providers/role_scorer.d.ts +16 -0
- package/dist/providers/role_scorer.js +16 -0
- package/dist/providers/role_scorer.js.map +1 -0
- package/dist/providers/router.d.ts +84 -0
- package/dist/providers/router.js +542 -0
- package/dist/providers/router.js.map +1 -0
- package/dist/security/credentials.d.ts +6 -0
- package/dist/security/credentials.js +16 -0
- package/dist/security/credentials.js.map +1 -0
- package/dist/setup/browser.d.ts +1 -0
- package/dist/setup/browser.js +12 -0
- package/dist/setup/browser.js.map +1 -0
- package/dist/setup/global_config.d.ts +14 -0
- package/dist/setup/global_config.js +54 -0
- package/dist/setup/global_config.js.map +1 -0
- package/dist/setup/wizard.d.ts +2 -0
- package/dist/setup/wizard.js +206 -0
- package/dist/setup/wizard.js.map +1 -0
- package/dist/tools/agent_loop.d.ts +38 -0
- package/dist/tools/agent_loop.js +72 -0
- package/dist/tools/agent_loop.js.map +1 -0
- package/dist/tools/approval.d.ts +64 -0
- package/dist/tools/approval.js +172 -0
- package/dist/tools/approval.js.map +1 -0
- package/dist/tools/checkpoint.d.ts +65 -0
- package/dist/tools/checkpoint.js +342 -0
- package/dist/tools/checkpoint.js.map +1 -0
- package/dist/tools/definitions.d.ts +13 -0
- package/dist/tools/definitions.js +103 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/diff_display.d.ts +46 -0
- package/dist/tools/diff_display.js +298 -0
- package/dist/tools/diff_display.js.map +1 -0
- package/dist/tools/executor.d.ts +12 -0
- package/dist/tools/executor.js +340 -0
- package/dist/tools/executor.js.map +1 -0
- package/dist/tools/permissions.d.ts +17 -0
- package/dist/tools/permissions.js +139 -0
- package/dist/tools/permissions.js.map +1 -0
- package/dist/tools/tool_types.d.ts +48 -0
- package/dist/tools/tool_types.js +7 -0
- package/dist/tools/tool_types.js.map +1 -0
- package/dist/ui/banner.d.ts +4 -0
- package/dist/ui/banner.js +104 -0
- package/dist/ui/banner.js.map +1 -0
- package/dist/ui/callbacks.d.ts +30 -0
- package/dist/ui/callbacks.js +132 -0
- package/dist/ui/callbacks.js.map +1 -0
- package/dist/ui/colors.d.ts +14 -0
- package/dist/ui/colors.js +28 -0
- package/dist/ui/colors.js.map +1 -0
- package/dist/ui/dashboard.d.ts +51 -0
- package/dist/ui/dashboard.js +181 -0
- package/dist/ui/dashboard.js.map +1 -0
- package/dist/ui/leaderboard.d.ts +16 -0
- package/dist/ui/leaderboard.js +43 -0
- package/dist/ui/leaderboard.js.map +1 -0
- package/dist/ui/logger.d.ts +28 -0
- package/dist/ui/logger.js +117 -0
- package/dist/ui/logger.js.map +1 -0
- package/dist/ui/progress.d.ts +16 -0
- package/dist/ui/progress.js +62 -0
- package/dist/ui/progress.js.map +1 -0
- package/dist/ui/tokenizer.d.ts +5 -0
- package/dist/ui/tokenizer.js +54 -0
- package/dist/ui/tokenizer.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { R, B, BLU, GRN, DM } from "./colors.js";
|
|
2
|
+
import { listEloRatingsByRole } from "../db/queries.js";
|
|
3
|
+
import { createLogger } from "./logger.js";
|
|
4
|
+
export function aggregateEloByModel(ratings) {
|
|
5
|
+
const modelElos = new Map();
|
|
6
|
+
for (const row of ratings) {
|
|
7
|
+
const existing = modelElos.get(row.model) ?? { totalElo: 0, count: 0, matches: 0 };
|
|
8
|
+
existing.totalElo += row.elo;
|
|
9
|
+
existing.count += 1;
|
|
10
|
+
existing.matches += row.match_count;
|
|
11
|
+
modelElos.set(row.model, existing);
|
|
12
|
+
}
|
|
13
|
+
return [...modelElos.entries()]
|
|
14
|
+
.map(([model, data]) => ({
|
|
15
|
+
model,
|
|
16
|
+
avgElo: data.totalElo / data.count,
|
|
17
|
+
matches: data.matches,
|
|
18
|
+
}))
|
|
19
|
+
.sort((a, b) => b.avgElo - a.avgElo);
|
|
20
|
+
}
|
|
21
|
+
const log = createLogger("leaderboard");
|
|
22
|
+
export function printLeaderboard(db, roles) {
|
|
23
|
+
const targetRoles = roles ?? ["architect", "executor"];
|
|
24
|
+
for (const role of targetRoles) {
|
|
25
|
+
const color = role === "architect" ? BLU : GRN;
|
|
26
|
+
log.raw(`\n${B}${color}${role.toUpperCase()} Leaderboard${R}\n`);
|
|
27
|
+
log.raw(`${DM}${"─".repeat(60)}${R}\n`);
|
|
28
|
+
const ratings = listEloRatingsByRole(db, role);
|
|
29
|
+
if (ratings.length === 0) {
|
|
30
|
+
log.raw(`${DM} No ELO data yet. Run 'duocode duo run' to generate ratings.${R}\n`);
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const sorted = aggregateEloByModel(ratings);
|
|
34
|
+
log.raw(` ${DM}${"Rank".padEnd(6)}${"Model".padEnd(25)}${"ELO".padEnd(10)}${"Matches".padEnd(10)}${R}\n`);
|
|
35
|
+
for (let i = 0; i < sorted.length; i++) {
|
|
36
|
+
const entry = sorted[i];
|
|
37
|
+
const rank = `#${i + 1}`;
|
|
38
|
+
log.raw(` ${color}${rank.padEnd(6)}${R}${entry.model.padEnd(25)}${entry.avgElo.toFixed(0).padEnd(10)}${String(entry.matches).padEnd(10)}\n`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
log.raw("\n");
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=leaderboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"leaderboard.js","sourceRoot":"","sources":["../../src/ui/leaderboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const LOG_LEVELS: readonly ["error", "warn", "info", "debug", "trace"];
|
|
2
|
+
export type LogLevel = (typeof LOG_LEVELS)[number];
|
|
3
|
+
export interface LogEntry {
|
|
4
|
+
timestamp: string;
|
|
5
|
+
level: LogLevel;
|
|
6
|
+
component: string;
|
|
7
|
+
message: string;
|
|
8
|
+
metadata?: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
export interface Logger {
|
|
11
|
+
error(msg: string, meta?: Record<string, unknown>): void;
|
|
12
|
+
warn(msg: string, meta?: Record<string, unknown>): void;
|
|
13
|
+
info(msg: string, meta?: Record<string, unknown>): void;
|
|
14
|
+
debug(msg: string, meta?: Record<string, unknown>): void;
|
|
15
|
+
trace(msg: string, meta?: Record<string, unknown>): void;
|
|
16
|
+
/** Stdout passthrough — no level filtering, no formatting. */
|
|
17
|
+
raw(text: string): void;
|
|
18
|
+
/** Create a child logger with a sub-component prefix. */
|
|
19
|
+
child(sub: string): Logger;
|
|
20
|
+
}
|
|
21
|
+
export interface LoggerConfig {
|
|
22
|
+
level: LogLevel;
|
|
23
|
+
format: "human" | "json" | "auto";
|
|
24
|
+
filePath: string | null;
|
|
25
|
+
}
|
|
26
|
+
export declare function configureLogger(opts: Partial<LoggerConfig>): void;
|
|
27
|
+
export declare function getLoggerConfig(): Readonly<LoggerConfig>;
|
|
28
|
+
export declare function createLogger(component: string): Logger;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured logging framework for DuoCode.
|
|
3
|
+
*
|
|
4
|
+
* - Structured logs (error/warn/info/debug/trace) go to stderr
|
|
5
|
+
* - raw() writes to stdout (banners, tables, prompts, LLM streaming)
|
|
6
|
+
* - File transport writes JSONL via appendFileSync for crash safety
|
|
7
|
+
* - TTY auto-detection on stderr; overridable via DUOCODE_LOG_FORMAT
|
|
8
|
+
*/
|
|
9
|
+
import fs from "node:fs";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
export const LOG_LEVELS = ["error", "warn", "info", "debug", "trace"];
|
|
12
|
+
// ── ANSI helpers (human format only) ──────────────────────────────
|
|
13
|
+
const ANSI_RESET = "\x1b[0m";
|
|
14
|
+
const ANSI_DIM = "\x1b[2m";
|
|
15
|
+
const LEVEL_COLORS = {
|
|
16
|
+
error: "\x1b[91m", // bright red
|
|
17
|
+
warn: "\x1b[93m", // bright yellow
|
|
18
|
+
info: "\x1b[92m", // bright green
|
|
19
|
+
debug: "\x1b[2m", // dim
|
|
20
|
+
trace: "\x1b[2m", // dim
|
|
21
|
+
};
|
|
22
|
+
// ── Global state ──────────────────────────────────────────────────
|
|
23
|
+
const LEVEL_PRIORITY = {
|
|
24
|
+
error: 0,
|
|
25
|
+
warn: 1,
|
|
26
|
+
info: 2,
|
|
27
|
+
debug: 3,
|
|
28
|
+
trace: 4,
|
|
29
|
+
};
|
|
30
|
+
const globalConfig = {
|
|
31
|
+
level: "info",
|
|
32
|
+
format: "auto",
|
|
33
|
+
filePath: null,
|
|
34
|
+
};
|
|
35
|
+
// ── Config API ────────────────────────────────────────────────────
|
|
36
|
+
export function configureLogger(opts) {
|
|
37
|
+
if (opts.level !== undefined)
|
|
38
|
+
globalConfig.level = opts.level;
|
|
39
|
+
if (opts.format !== undefined)
|
|
40
|
+
globalConfig.format = opts.format;
|
|
41
|
+
if (opts.filePath !== undefined)
|
|
42
|
+
globalConfig.filePath = opts.filePath;
|
|
43
|
+
}
|
|
44
|
+
export function getLoggerConfig() {
|
|
45
|
+
return { ...globalConfig };
|
|
46
|
+
}
|
|
47
|
+
// ── Internal helpers ──────────────────────────────────────────────
|
|
48
|
+
function shouldEmit(level) {
|
|
49
|
+
return LEVEL_PRIORITY[level] <= LEVEL_PRIORITY[globalConfig.level];
|
|
50
|
+
}
|
|
51
|
+
function resolveFormat() {
|
|
52
|
+
if (globalConfig.format !== "auto")
|
|
53
|
+
return globalConfig.format;
|
|
54
|
+
return process.stderr.isTTY ? "human" : "json";
|
|
55
|
+
}
|
|
56
|
+
function formatTimestamp(date) {
|
|
57
|
+
return date.toISOString();
|
|
58
|
+
}
|
|
59
|
+
function formatHumanTime(date) {
|
|
60
|
+
const h = String(date.getHours()).padStart(2, "0");
|
|
61
|
+
const m = String(date.getMinutes()).padStart(2, "0");
|
|
62
|
+
const s = String(date.getSeconds()).padStart(2, "0");
|
|
63
|
+
const ms = String(date.getMilliseconds()).padStart(3, "0");
|
|
64
|
+
return `${h}:${m}:${s}.${ms}`;
|
|
65
|
+
}
|
|
66
|
+
function buildEntry(level, component, message, meta) {
|
|
67
|
+
return {
|
|
68
|
+
timestamp: formatTimestamp(new Date()),
|
|
69
|
+
level,
|
|
70
|
+
component,
|
|
71
|
+
message,
|
|
72
|
+
...(meta !== undefined && Object.keys(meta).length > 0 ? { metadata: meta } : {}),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function writeToStderr(entry) {
|
|
76
|
+
const fmt = resolveFormat();
|
|
77
|
+
if (fmt === "json") {
|
|
78
|
+
process.stderr.write(JSON.stringify(entry) + "\n");
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const color = LEVEL_COLORS[entry.level];
|
|
82
|
+
const tag = entry.level.toUpperCase().padEnd(5);
|
|
83
|
+
const time = formatHumanTime(new Date(entry.timestamp));
|
|
84
|
+
let line = `${ANSI_DIM}${time}${ANSI_RESET} ${color}${tag}${ANSI_RESET} ${ANSI_DIM}[${entry.component}]${ANSI_RESET} ${entry.message}`;
|
|
85
|
+
if (entry.metadata && Object.keys(entry.metadata).length > 0) {
|
|
86
|
+
line += ` ${ANSI_DIM}${JSON.stringify(entry.metadata)}${ANSI_RESET}`;
|
|
87
|
+
}
|
|
88
|
+
process.stderr.write(line + "\n");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function writeToFile(entry) {
|
|
92
|
+
if (!globalConfig.filePath)
|
|
93
|
+
return;
|
|
94
|
+
const dir = path.dirname(globalConfig.filePath);
|
|
95
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
96
|
+
fs.appendFileSync(globalConfig.filePath, JSON.stringify(entry) + "\n");
|
|
97
|
+
}
|
|
98
|
+
function emit(level, component, message, meta) {
|
|
99
|
+
if (!shouldEmit(level))
|
|
100
|
+
return;
|
|
101
|
+
const entry = buildEntry(level, component, message, meta);
|
|
102
|
+
writeToStderr(entry);
|
|
103
|
+
writeToFile(entry);
|
|
104
|
+
}
|
|
105
|
+
// ── Factory ───────────────────────────────────────────────────────
|
|
106
|
+
export function createLogger(component) {
|
|
107
|
+
return {
|
|
108
|
+
error: (msg, meta) => emit("error", component, msg, meta),
|
|
109
|
+
warn: (msg, meta) => emit("warn", component, msg, meta),
|
|
110
|
+
info: (msg, meta) => emit("info", component, msg, meta),
|
|
111
|
+
debug: (msg, meta) => emit("debug", component, msg, meta),
|
|
112
|
+
trace: (msg, meta) => emit("trace", component, msg, meta),
|
|
113
|
+
raw: (text) => { process.stdout.write(text); },
|
|
114
|
+
child: (sub) => createLogger(`${component}:${sub}`),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/ui/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress indicators: spinner, phase banners, live counters, elapsed time.
|
|
3
|
+
*/
|
|
4
|
+
export declare class Spinner {
|
|
5
|
+
private intervalId;
|
|
6
|
+
private frameIndex;
|
|
7
|
+
private message;
|
|
8
|
+
constructor(message: string);
|
|
9
|
+
start(): void;
|
|
10
|
+
update(message: string): void;
|
|
11
|
+
stop(finalMessage?: string): void;
|
|
12
|
+
}
|
|
13
|
+
export declare function phaseBanner(phaseNumber: number, totalPhases: number, label: string): string;
|
|
14
|
+
export declare function liveTokenCounter(tokens: number, costUsd: number): string;
|
|
15
|
+
export declare function formatElapsed(ms: number): string;
|
|
16
|
+
export declare function formatSessionCost(costUsd: number): string;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress indicators: spinner, phase banners, live counters, elapsed time.
|
|
3
|
+
*/
|
|
4
|
+
import { DM, R, B } from "./colors.js";
|
|
5
|
+
// ── Spinner ─────────────────────────────────────────────────────
|
|
6
|
+
const SPINNER_FRAMES = ["\u28CB", "\u28D9", "\u28F9", "\u28F8", "\u28FC", "\u28F4", "\u28E6", "\u28E7", "\u28C7", "\u28CF"];
|
|
7
|
+
export class Spinner {
|
|
8
|
+
intervalId = null;
|
|
9
|
+
frameIndex = 0;
|
|
10
|
+
message;
|
|
11
|
+
constructor(message) {
|
|
12
|
+
this.message = message;
|
|
13
|
+
}
|
|
14
|
+
start() {
|
|
15
|
+
if (this.intervalId)
|
|
16
|
+
return;
|
|
17
|
+
this.frameIndex = 0;
|
|
18
|
+
this.intervalId = setInterval(() => {
|
|
19
|
+
const frame = SPINNER_FRAMES[this.frameIndex % SPINNER_FRAMES.length];
|
|
20
|
+
process.stdout.write(`\r\x1b[2K${DM}${frame} ${this.message}${R}`);
|
|
21
|
+
this.frameIndex++;
|
|
22
|
+
}, 80);
|
|
23
|
+
}
|
|
24
|
+
update(message) {
|
|
25
|
+
this.message = message;
|
|
26
|
+
}
|
|
27
|
+
stop(finalMessage) {
|
|
28
|
+
if (this.intervalId) {
|
|
29
|
+
clearInterval(this.intervalId);
|
|
30
|
+
this.intervalId = null;
|
|
31
|
+
}
|
|
32
|
+
process.stdout.write("\r\x1b[2K");
|
|
33
|
+
if (finalMessage) {
|
|
34
|
+
process.stdout.write(finalMessage + "\n");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// ── Phase Banners ───────────────────────────────────────────────
|
|
39
|
+
export function phaseBanner(phaseNumber, totalPhases, label) {
|
|
40
|
+
return `${DM}[${phaseNumber}/${totalPhases}]${R} ${B}${label}${R}`;
|
|
41
|
+
}
|
|
42
|
+
// ── Live Token Counter ──────────────────────────────────────────
|
|
43
|
+
export function liveTokenCounter(tokens, costUsd) {
|
|
44
|
+
return `${DM}tokens: ${tokens.toLocaleString()} | $${costUsd.toFixed(4)}${R}`;
|
|
45
|
+
}
|
|
46
|
+
// ── Elapsed Time ────────────────────────────────────────────────
|
|
47
|
+
export function formatElapsed(ms) {
|
|
48
|
+
if (ms < 1000)
|
|
49
|
+
return `${ms}ms`;
|
|
50
|
+
if (ms < 60000)
|
|
51
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
52
|
+
const mins = Math.floor(ms / 60000);
|
|
53
|
+
const secs = ((ms % 60000) / 1000).toFixed(0);
|
|
54
|
+
return `${mins}m${secs}s`;
|
|
55
|
+
}
|
|
56
|
+
// ── Session Cost Format ─────────────────────────────────────────
|
|
57
|
+
export function formatSessionCost(costUsd) {
|
|
58
|
+
if (costUsd < 0.01)
|
|
59
|
+
return `$${costUsd.toFixed(4)}`;
|
|
60
|
+
return `$${costUsd.toFixed(2)}`;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/ui/progress.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell-style command line tokenizer.
|
|
3
|
+
* Handles single and double quotes, backslash escapes.
|
|
4
|
+
*/
|
|
5
|
+
export function tokenizeCommandLine(input) {
|
|
6
|
+
const tokens = [];
|
|
7
|
+
let current = "";
|
|
8
|
+
let quote = null;
|
|
9
|
+
let escaped = false;
|
|
10
|
+
for (let i = 0; i < input.length; i += 1) {
|
|
11
|
+
const ch = input[i];
|
|
12
|
+
if (escaped) {
|
|
13
|
+
current += ch;
|
|
14
|
+
escaped = false;
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (ch === "\\") {
|
|
18
|
+
escaped = true;
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (quote) {
|
|
22
|
+
if (ch === quote) {
|
|
23
|
+
quote = null;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
current += ch;
|
|
27
|
+
}
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (ch === "\"" || ch === "'") {
|
|
31
|
+
quote = ch;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (/\s/.test(ch)) {
|
|
35
|
+
if (current.length > 0) {
|
|
36
|
+
tokens.push(current);
|
|
37
|
+
current = "";
|
|
38
|
+
}
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
current += ch;
|
|
42
|
+
}
|
|
43
|
+
if (quote) {
|
|
44
|
+
throw new Error("Unclosed quote in command.");
|
|
45
|
+
}
|
|
46
|
+
if (escaped) {
|
|
47
|
+
current += "\\";
|
|
48
|
+
}
|
|
49
|
+
if (current.length > 0) {
|
|
50
|
+
tokens.push(current);
|
|
51
|
+
}
|
|
52
|
+
return tokens;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=tokenizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../../src/ui/tokenizer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,KAAK,GAAsB,IAAI,CAAC;IACpC,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAEpB,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,IAAI,EAAE,CAAC;YACd,OAAO,GAAG,KAAK,CAAC;YAChB,SAAS;QACX,CAAC;QAED,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YAChB,OAAO,GAAG,IAAI,CAAC;YACf,SAAS;QACX,CAAC;QAED,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,EAAE,KAAK,KAAK,EAAE,CAAC;gBACjB,KAAK,GAAG,IAAI,CAAC;YACf,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAI,EAAE,CAAC;YAChB,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YAC9B,KAAK,GAAG,EAAE,CAAC;YACX,SAAS;QACX,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YAClB,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACrB,OAAO,GAAG,EAAE,CAAC;YACf,CAAC;YACD,SAAS;QACX,CAAC;QAED,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;IAED,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,IAAI,IAAI,CAAC;IAClB,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "duocode",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Multi-agent code orchestration CLI with AST ownership, negotiation, provider routing, and GitHub integration",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": ["cli", "coding", "ai", "orchestration", "multi-agent", "duopair"],
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/duocode/duocode.git"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/duocode/duocode#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/duocode/duocode/issues"
|
|
15
|
+
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=20"
|
|
18
|
+
},
|
|
19
|
+
"bin": {
|
|
20
|
+
"duocode": "dist/cli.js"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist/",
|
|
24
|
+
"LICENSE",
|
|
25
|
+
".env.example"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc -p tsconfig.json",
|
|
29
|
+
"dev": "tsx src/cli.ts",
|
|
30
|
+
"start": "node dist/cli.js",
|
|
31
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
32
|
+
"lint": "eslint src/",
|
|
33
|
+
"test": "tsx --test tests/**/*.test.ts",
|
|
34
|
+
"prepublishOnly": "npm run build && npm test"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@anthropic-ai/sdk": "^0.74.0",
|
|
38
|
+
"@types/express": "^5.0.6",
|
|
39
|
+
"better-sqlite3": "^11.7.0",
|
|
40
|
+
"commander": "^13.1.0",
|
|
41
|
+
"express": "^5.2.1",
|
|
42
|
+
"openai": "^6.19.0",
|
|
43
|
+
"yaml": "^2.7.0",
|
|
44
|
+
"zod": "^3.24.1"
|
|
45
|
+
},
|
|
46
|
+
"optionalDependencies": {
|
|
47
|
+
"tree-sitter": "^0.21.1",
|
|
48
|
+
"tree-sitter-go": "^0.21.0",
|
|
49
|
+
"tree-sitter-python": "^0.21.0",
|
|
50
|
+
"tree-sitter-typescript": "^0.23.2"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@eslint/js": "^9.39.2",
|
|
54
|
+
"@types/better-sqlite3": "^7.6.12",
|
|
55
|
+
"@types/node": "^22.13.1",
|
|
56
|
+
"@types/supertest": "^6.0.3",
|
|
57
|
+
"eslint": "^9.39.2",
|
|
58
|
+
"supertest": "^7.2.2",
|
|
59
|
+
"tsx": "^4.19.2",
|
|
60
|
+
"typescript": "5.3.3",
|
|
61
|
+
"typescript-eslint": "^8.55.0"
|
|
62
|
+
}
|
|
63
|
+
}
|