@0dai-dev/cli 3.2.2 → 3.2.4
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/bin/0dai.js +89 -21
- package/package.json +1 -1
package/bin/0dai.js
CHANGED
|
@@ -1599,31 +1599,57 @@ async function cmdAuthStatus() {
|
|
|
1599
1599
|
}
|
|
1600
1600
|
|
|
1601
1601
|
async function cmdFeedbackPush(target) {
|
|
1602
|
-
const
|
|
1603
|
-
const
|
|
1602
|
+
const fbDir = path.join(target, "ai", "feedback");
|
|
1603
|
+
const items = [];
|
|
1604
|
+
|
|
1605
|
+
// Collect from report JSON files
|
|
1604
1606
|
try {
|
|
1605
|
-
for (const f of fs.readdirSync(
|
|
1607
|
+
for (const f of fs.readdirSync(fbDir)) {
|
|
1606
1608
|
if (f.endsWith("-report.json") || (f.endsWith(".json") && f.match(/^\d{8}/))) {
|
|
1607
1609
|
try {
|
|
1608
|
-
const d = JSON.parse(fs.readFileSync(path.join(
|
|
1609
|
-
if (d.project || d.verdict)
|
|
1610
|
+
const d = JSON.parse(fs.readFileSync(path.join(fbDir, f), "utf8"));
|
|
1611
|
+
if (d.project || d.verdict) items.push({ type: "report", data: d, file: f });
|
|
1610
1612
|
} catch {}
|
|
1611
1613
|
}
|
|
1612
1614
|
}
|
|
1613
1615
|
} catch {}
|
|
1614
1616
|
|
|
1615
|
-
|
|
1617
|
+
// Collect from operational.jsonl (feedback log entries)
|
|
1618
|
+
const jsonlPath = path.join(fbDir, "operational.jsonl");
|
|
1619
|
+
try {
|
|
1620
|
+
if (fs.existsSync(jsonlPath)) {
|
|
1621
|
+
const lines = fs.readFileSync(jsonlPath, "utf8").trim().split("\n").filter(Boolean);
|
|
1622
|
+
for (const line of lines) {
|
|
1623
|
+
try { items.push({ type: "log", data: JSON.parse(line) }); } catch {}
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
} catch {}
|
|
1616
1627
|
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
log(`
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1628
|
+
if (!items.length) {
|
|
1629
|
+
log("no feedback found");
|
|
1630
|
+
console.log(` ${D}Log feedback first: 0dai feedback log --type suggestion --detail '...'${R}`);
|
|
1631
|
+
return;
|
|
1632
|
+
}
|
|
1633
|
+
|
|
1634
|
+
// Push all items
|
|
1635
|
+
const report = {
|
|
1636
|
+
project: path.basename(target),
|
|
1637
|
+
entries: items.map(i => i.data),
|
|
1638
|
+
count: items.length,
|
|
1639
|
+
submitted_at: new Date().toISOString(),
|
|
1640
|
+
};
|
|
1641
|
+
log(`pushing ${items.length} feedback item(s)...`);
|
|
1642
|
+
const result = await apiCall("/v1/feedback", { report });
|
|
1643
|
+
if (result.received) {
|
|
1644
|
+
log(`received${result.issue ? `: ${result.issue}` : ""}`);
|
|
1645
|
+
if (result.bonus) log(`${T}bonus:${R} ${result.bonus}`);
|
|
1646
|
+
// Archive pushed entries
|
|
1647
|
+
if (fs.existsSync(jsonlPath)) {
|
|
1648
|
+
const archivePath = path.join(fbDir, `pushed-${Date.now()}.jsonl`);
|
|
1649
|
+
fs.renameSync(jsonlPath, archivePath);
|
|
1626
1650
|
}
|
|
1651
|
+
} else {
|
|
1652
|
+
log(`error: ${result.error || "unknown"}`);
|
|
1627
1653
|
}
|
|
1628
1654
|
}
|
|
1629
1655
|
|
|
@@ -2056,20 +2082,62 @@ async function main() {
|
|
|
2056
2082
|
try {
|
|
2057
2083
|
const SessionManager = require("../lib/session-manager");
|
|
2058
2084
|
const sm = new SessionManager();
|
|
2059
|
-
if (sub === "launch" || !sub) {
|
|
2060
|
-
const
|
|
2061
|
-
const
|
|
2085
|
+
if (sub === "launch" || !sub || sub.startsWith("--")) {
|
|
2086
|
+
const toolIdx = args.indexOf("--tool");
|
|
2087
|
+
const tool = toolIdx >= 0 && args[toolIdx + 1] ? args[toolIdx + 1] : "codex";
|
|
2088
|
+
const TOOL_CMDS = {
|
|
2089
|
+
codex: { bin: "codex", args: [] },
|
|
2090
|
+
claude: { bin: "claude", args: [] },
|
|
2091
|
+
gemini: { bin: "gemini", args: [] },
|
|
2092
|
+
opencode: { bin: "opencode", args: [] },
|
|
2093
|
+
aider: { bin: "aider", args: [] },
|
|
2094
|
+
};
|
|
2095
|
+
const toolConfig = TOOL_CMDS[tool];
|
|
2096
|
+
if (!toolConfig) {
|
|
2097
|
+
log(`unknown tool: ${tool}. Available: ${Object.keys(TOOL_CMDS).join(", ")}`);
|
|
2098
|
+
break;
|
|
2099
|
+
}
|
|
2100
|
+
// Pass initial prompt if provided after --
|
|
2101
|
+
const dashIdx = args.indexOf("--");
|
|
2102
|
+
const prompt = dashIdx >= 0 ? args.slice(dashIdx + 1).join(" ") : "";
|
|
2103
|
+
const spawnArgs = [...toolConfig.args];
|
|
2104
|
+
if (prompt) spawnArgs.push(prompt);
|
|
2105
|
+
const id = sm.spawn(toolConfig.bin, spawnArgs, target);
|
|
2062
2106
|
log(`session ${id.slice(0, 8)} started (${tool})`);
|
|
2107
|
+
console.log(` ${D}Ctrl+C to exit, session keeps running in background${R}`);
|
|
2108
|
+
console.log(` ${D}Re-attach: 0dai terminal attach ${id.slice(0, 8)}${R}`);
|
|
2063
2109
|
sm.attach(id);
|
|
2064
2110
|
} else if (sub === "list") {
|
|
2065
2111
|
const sessions = sm.list();
|
|
2066
2112
|
if (!sessions.length) { log("no active sessions"); break; }
|
|
2067
|
-
for (const s of sessions)
|
|
2113
|
+
for (const s of sessions) {
|
|
2114
|
+
const elapsed = Math.round((Date.now() - new Date(s.createdAt).getTime()) / 1000);
|
|
2115
|
+
console.log(` ${s.id.slice(0, 8)} [${s.tool}] ${s.status} ${elapsed}s ${s.attached ? "(attached)" : ""}`);
|
|
2116
|
+
}
|
|
2117
|
+
} else if (sub === "attach") {
|
|
2118
|
+
const prefix = args[1] || "";
|
|
2119
|
+
if (!prefix) { log("usage: 0dai terminal attach <session-id-prefix>"); break; }
|
|
2120
|
+
const sessions = sm.list();
|
|
2121
|
+
const match = sessions.find(s => s.id.startsWith(prefix));
|
|
2122
|
+
if (!match) { log(`no running session matching '${prefix}'`); break; }
|
|
2123
|
+
log(`re-attaching to ${match.id.slice(0, 8)} (${match.tool})`);
|
|
2124
|
+
sm.attach(match.id);
|
|
2125
|
+
} else if (sub === "kill") {
|
|
2126
|
+
const prefix = args[1] || "";
|
|
2127
|
+
if (!prefix) { log("usage: 0dai terminal kill <session-id-prefix>"); break; }
|
|
2128
|
+
const all = Array.from(sm.sessions || []);
|
|
2129
|
+
// Kill by prefix match
|
|
2130
|
+
let found = false;
|
|
2131
|
+
for (const [id] of all) {
|
|
2132
|
+
if (id.startsWith(prefix)) { sm.kill(id); log(`killed ${id.slice(0, 8)}`); found = true; }
|
|
2133
|
+
}
|
|
2134
|
+
if (!found) log(`no session matching '${prefix}'`);
|
|
2068
2135
|
} else {
|
|
2069
|
-
console.log("Usage: 0dai terminal [launch|list] [--tool codex|claude|gemini]");
|
|
2136
|
+
console.log("Usage: 0dai terminal [launch|list|attach|kill] [--tool codex|claude|gemini|opencode|aider]");
|
|
2137
|
+
console.log(" 0dai terminal --tool opencode -- 'fix the auth bug'");
|
|
2070
2138
|
}
|
|
2071
2139
|
} catch (e) {
|
|
2072
|
-
if (e.code === "MODULE_NOT_FOUND") log("install node-pty first:
|
|
2140
|
+
if (e.code === "MODULE_NOT_FOUND") log("install node-pty first: npm i -g node-pty");
|
|
2073
2141
|
else log(`error: ${e.message}`);
|
|
2074
2142
|
}
|
|
2075
2143
|
break;
|