@0dai-dev/cli 4.2.0 → 4.3.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/README.md +30 -5
- package/bin/0dai.js +289 -60
- package/lib/commands/audit.js +13 -0
- package/lib/commands/auth.js +341 -98
- package/lib/commands/boneyard.js +44 -0
- package/lib/commands/ci.js +329 -0
- package/lib/commands/compliance.js +20 -0
- package/lib/commands/doctor.js +20 -1
- package/lib/commands/experience.js +5 -1
- package/lib/commands/feedback.js +92 -5
- package/lib/commands/gh.js +506 -0
- package/lib/commands/graph.js +78 -10
- package/lib/commands/heatmap.js +17 -0
- package/lib/commands/import_claude_code_agents.js +367 -0
- package/lib/commands/init.js +440 -28
- package/lib/commands/loop.js +108 -0
- package/lib/commands/mcp.js +410 -0
- package/lib/commands/models.js +27 -3
- package/lib/commands/paste.js +114 -0
- package/lib/commands/play.js +173 -0
- package/lib/commands/provider.js +69 -0
- package/lib/commands/quota.js +76 -0
- package/lib/commands/receipt.js +53 -0
- package/lib/commands/report.js +29 -2
- package/lib/commands/run.js +44 -4
- package/lib/commands/runner.js +527 -0
- package/lib/commands/session.js +1 -7
- package/lib/commands/standup.js +40 -0
- package/lib/commands/status.js +26 -1
- package/lib/commands/swarm.js +97 -4
- package/lib/commands/tui.js +81 -13
- package/lib/commands/usage.js +87 -0
- package/lib/commands/vault.js +246 -0
- package/lib/onboarding.js +9 -3
- package/lib/shared.js +29 -14
- package/lib/tui/index.mjs +571 -187
- package/lib/utils/auth.js +1 -0
- package/lib/utils/canonical-counts.js +54 -0
- package/lib/utils/diff-preview.js +192 -0
- package/lib/utils/identity.js +76 -18
- package/lib/utils/mcp-auth.js +607 -0
- package/lib/utils/plan.js +37 -2
- package/lib/vault/cipher.js +125 -0
- package/lib/vault/identity.js +122 -0
- package/lib/vault/index.js +184 -0
- package/lib/vault/storage.js +84 -0
- package/lib/wizard.js +19 -12
- package/package.json +2 -2
package/lib/shared.js
CHANGED
|
@@ -60,7 +60,7 @@ const DRIFT_TRACKED_CONFIGS = [
|
|
|
60
60
|
];
|
|
61
61
|
|
|
62
62
|
// --- API ---
|
|
63
|
-
function apiCall(endpoint, data) {
|
|
63
|
+
function apiCall(endpoint, data, options = {}) {
|
|
64
64
|
return new Promise((resolve) => {
|
|
65
65
|
const url = new URL(endpoint, API_URL);
|
|
66
66
|
const mod = url.protocol === "https:" ? https : http;
|
|
@@ -71,11 +71,16 @@ function apiCall(endpoint, data) {
|
|
|
71
71
|
"X-CLI-Version": VERSION,
|
|
72
72
|
"X-Client-Channel": "npm",
|
|
73
73
|
};
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
const accessToken = options && options.accessToken ? String(options.accessToken).trim() : "";
|
|
75
|
+
if (accessToken) {
|
|
76
|
+
headers["Authorization"] = `Bearer ${accessToken}`;
|
|
77
|
+
} else {
|
|
78
|
+
try {
|
|
79
|
+
const auth = JSON.parse(fs.readFileSync(AUTH_FILE, "utf8"));
|
|
80
|
+
const token = auth.api_key || auth.access_token || auth.token;
|
|
81
|
+
if (token) headers["Authorization"] = `Bearer ${token}`;
|
|
82
|
+
} catch {}
|
|
83
|
+
}
|
|
79
84
|
const opts = {
|
|
80
85
|
hostname: url.hostname,
|
|
81
86
|
port: url.port || (url.protocol === "https:" ? 443 : 80),
|
|
@@ -116,12 +121,14 @@ function updateAuthState(patch) {
|
|
|
116
121
|
saveAuthState({ ...current, ...patch });
|
|
117
122
|
}
|
|
118
123
|
|
|
119
|
-
async function fetchAuthStatus() {
|
|
120
|
-
const
|
|
121
|
-
|
|
124
|
+
async function fetchAuthStatus(accessToken = "") {
|
|
125
|
+
const token = String(accessToken || "").trim();
|
|
126
|
+
const status = await apiCall("/v1/auth/status", null, token ? { accessToken: token } : undefined);
|
|
127
|
+
if (status && !status.error && status.email && !token) {
|
|
122
128
|
updateAuthState({
|
|
123
129
|
email: status.email, plan: status.plan || "free",
|
|
124
130
|
name: status.name || "", license: status.license || {},
|
|
131
|
+
plan_expires_at: status.plan_expires_at || "",
|
|
125
132
|
});
|
|
126
133
|
}
|
|
127
134
|
return status;
|
|
@@ -302,6 +309,8 @@ function mergeSettingsJson(existing, incoming) {
|
|
|
302
309
|
function writeFiles(target, files) {
|
|
303
310
|
let created = 0, updated = 0, unchanged = 0, merged = 0, skipped = 0;
|
|
304
311
|
const targetResolved = path.resolve(target);
|
|
312
|
+
let backupDir = null;
|
|
313
|
+
const backupConfigs = new Set(["CLAUDE.md", "AGENTS.md"]);
|
|
305
314
|
for (const [rel, content] of Object.entries(files)) {
|
|
306
315
|
if (typeof rel !== "string" || !rel || path.isAbsolute(rel) || rel.split(/[/\\]/).includes("..")) {
|
|
307
316
|
skipped++; continue;
|
|
@@ -314,11 +323,16 @@ function writeFiles(target, files) {
|
|
|
314
323
|
const existing = fs.readFileSync(p, "utf8");
|
|
315
324
|
if (existing === content) { unchanged++; continue; }
|
|
316
325
|
if (rel.endsWith("settings.json")) { finalContent = mergeSettingsJson(existing, content); merged++; }
|
|
317
|
-
else if (rel
|
|
318
|
-
if (existing.includes("managed: false")) { unchanged++; continue; }
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
326
|
+
else if (backupConfigs.has(rel)) {
|
|
327
|
+
if (rel === "AGENTS.md" && existing.includes("managed: false")) { unchanged++; continue; }
|
|
328
|
+
if (!backupDir) {
|
|
329
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
330
|
+
backupDir = path.join(targetResolved, "ai", ".backups", timestamp);
|
|
331
|
+
fs.mkdirSync(backupDir, { recursive: true });
|
|
332
|
+
}
|
|
333
|
+
const backupPath = path.join(backupDir, rel);
|
|
334
|
+
fs.writeFileSync(backupPath, existing, "utf8");
|
|
335
|
+
log(`backed up existing ${rel} to ${backupPath}`);
|
|
322
336
|
updated++;
|
|
323
337
|
} else { updated++; }
|
|
324
338
|
} else { created++; }
|
|
@@ -337,6 +351,7 @@ function findRepoScript(target, scriptName) {
|
|
|
337
351
|
path.join(target, "scripts", scriptName),
|
|
338
352
|
path.join(process.cwd(), "scripts", scriptName),
|
|
339
353
|
path.join(__dirname, "..", "..", "..", "scripts", scriptName),
|
|
354
|
+
path.join(__dirname, "..", "..", "..", "..", "scripts", scriptName),
|
|
340
355
|
];
|
|
341
356
|
for (const c of candidates) { if (fs.existsSync(c)) return c; }
|
|
342
357
|
return null;
|