@dosu/cli 0.67.2 → 0.68.1
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 +6 -4
- package/bin/dosu.js +136 -46
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -190,10 +190,12 @@ unanchored and reach topics immediately. Neither setup nor `enable` replaces a s
|
|
|
190
190
|
already have; they print the one-liner to add to your own script instead.
|
|
191
191
|
|
|
192
192
|
`incognito on` is a saved per-agent setting: none of that agent's sessions are studied until you
|
|
193
|
-
turn it off.
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
193
|
+
turn it off. Turning it off resumes studying only new sessions going forward; sessions that
|
|
194
|
+
finished while incognito was on stay unstudied permanently, even if a later sync picks them up.
|
|
195
|
+
To keep a single chat out instead, type `/dosu-incognito` in it; setup installs that command with
|
|
196
|
+
the hook. It marks the session's transcript so studying skips it (the whole session, and for the
|
|
197
|
+
rest of it — start a new session to turn Dosu back on) and tells the model not to use Dosu
|
|
198
|
+
tools. See [docs/studying.md](docs/studying.md).
|
|
197
199
|
|
|
198
200
|
### Telemetry and privacy
|
|
199
201
|
|
package/bin/dosu.js
CHANGED
|
@@ -1128,7 +1128,7 @@ function isNpxInvocation(channel = INSTALL_CHANNEL, env = process.env) {
|
|
|
1128
1128
|
function getVersionString() {
|
|
1129
1129
|
return `v${VERSION}`;
|
|
1130
1130
|
}
|
|
1131
|
-
var VERSION = "0.
|
|
1131
|
+
var VERSION = "0.68.1", INSTALL_CHANNEL = "npm";
|
|
1132
1132
|
|
|
1133
1133
|
// src/debug/logger.ts
|
|
1134
1134
|
import {
|
|
@@ -2113,6 +2113,10 @@ function syncStatePath(configDir = getConfigDir()) {
|
|
|
2113
2113
|
function stringsOf(values) {
|
|
2114
2114
|
return values.filter((v) => typeof v === "string");
|
|
2115
2115
|
}
|
|
2116
|
+
function incognitoPeriodsOf(values) {
|
|
2117
|
+
const optionalString = (v) => v === undefined || typeof v === "string";
|
|
2118
|
+
return values.filter((v) => typeof v === "object" && v !== null && typeof v.agent === "string" && optionalString(v.from) && optionalString(v.to)).map(({ agent, from, to }) => ({ agent, ...from ? { from } : {}, ...to ? { to } : {} }));
|
|
2119
|
+
}
|
|
2116
2120
|
function loadSyncState(configDir = getConfigDir()) {
|
|
2117
2121
|
const empty = {
|
|
2118
2122
|
schema_version: STATE_SCHEMA_VERSION,
|
|
@@ -2149,6 +2153,7 @@ function loadSyncState(configDir = getConfigDir()) {
|
|
|
2149
2153
|
...run ? { run } : {},
|
|
2150
2154
|
...raw.paused === true ? { paused: true } : {},
|
|
2151
2155
|
...Array.isArray(raw.incognito_agents) ? { incognito_agents: stringsOf(raw.incognito_agents) } : {},
|
|
2156
|
+
...Array.isArray(raw.incognito_periods) ? { incognito_periods: incognitoPeriodsOf(raw.incognito_periods) } : {},
|
|
2152
2157
|
...Array.isArray(raw.repo_filter) ? { repo_filter: stringsOf(raw.repo_filter) } : {},
|
|
2153
2158
|
...Array.isArray(raw.project_filter) ? { project_filter: stringsOf(raw.project_filter) } : {}
|
|
2154
2159
|
};
|
|
@@ -2167,7 +2172,18 @@ function setSyncPaused(paused, configDir = getConfigDir()) {
|
|
|
2167
2172
|
function setAgentsIncognito(agentIds, incognito, configDir = getConfigDir()) {
|
|
2168
2173
|
const state = loadSyncState(configDir);
|
|
2169
2174
|
const current = new Set(state.incognito_agents ?? []);
|
|
2175
|
+
const periods = state.incognito_periods ?? [];
|
|
2176
|
+
const at = new Date().toISOString();
|
|
2170
2177
|
for (const id of agentIds) {
|
|
2178
|
+
if (incognito && !current.has(id))
|
|
2179
|
+
periods.push({ agent: id, from: at });
|
|
2180
|
+
if (!incognito && current.has(id)) {
|
|
2181
|
+
const open = periods.find((p) => p.agent === id && !p.to);
|
|
2182
|
+
if (open)
|
|
2183
|
+
open.to = at;
|
|
2184
|
+
else
|
|
2185
|
+
periods.push({ agent: id, to: at });
|
|
2186
|
+
}
|
|
2171
2187
|
if (incognito)
|
|
2172
2188
|
current.add(id);
|
|
2173
2189
|
else
|
|
@@ -2177,8 +2193,16 @@ function setAgentsIncognito(agentIds, incognito, configDir = getConfigDir()) {
|
|
|
2177
2193
|
state.incognito_agents = [...current].sort();
|
|
2178
2194
|
else
|
|
2179
2195
|
delete state.incognito_agents;
|
|
2196
|
+
if (periods.length > 0)
|
|
2197
|
+
state.incognito_periods = periods;
|
|
2180
2198
|
saveSyncState(state, configDir);
|
|
2181
2199
|
}
|
|
2200
|
+
function isAgentIncognito(state, session) {
|
|
2201
|
+
if (state.incognito_agents?.includes(session.harness))
|
|
2202
|
+
return true;
|
|
2203
|
+
const updated = Date.parse(session.updated);
|
|
2204
|
+
return (state.incognito_periods ?? []).some((p) => p.agent === session.harness && p.to !== undefined && (p.from === undefined || Date.parse(p.from) <= updated) && updated <= Date.parse(p.to));
|
|
2205
|
+
}
|
|
2182
2206
|
function resetSyncState(configDir = getConfigDir()) {
|
|
2183
2207
|
const previous = loadSyncState(configDir);
|
|
2184
2208
|
const fresh = {
|
|
@@ -2188,7 +2212,8 @@ function resetSyncState(configDir = getConfigDir()) {
|
|
|
2188
2212
|
...previous.repo_filter ? { repo_filter: previous.repo_filter } : {},
|
|
2189
2213
|
...previous.project_filter ? { project_filter: previous.project_filter } : {},
|
|
2190
2214
|
...previous.paused ? { paused: true } : {},
|
|
2191
|
-
...previous.incognito_agents ? { incognito_agents: previous.incognito_agents } : {}
|
|
2215
|
+
...previous.incognito_agents ? { incognito_agents: previous.incognito_agents } : {},
|
|
2216
|
+
...previous.incognito_periods ? { incognito_periods: previous.incognito_periods } : {}
|
|
2192
2217
|
};
|
|
2193
2218
|
saveSyncState(fresh, configDir);
|
|
2194
2219
|
}
|
|
@@ -13985,8 +14010,7 @@ function listSessionBacklog() {
|
|
|
13985
14010
|
const sessions = filterSessionsByRepo(scanned, filter, resolver.resolveRepo);
|
|
13986
14011
|
resolver.flush();
|
|
13987
14012
|
const gate = gateSessions(sessions, state.watermark);
|
|
13988
|
-
const
|
|
13989
|
-
const { kept, skipped } = partitionIncognitoSessions(gate.ready, (session) => incognitoAgents.has(session.harness) || isIncognitoSession(session));
|
|
14013
|
+
const { kept, skipped } = partitionIncognitoSessions(gate.ready, (session) => isAgentIncognito(state, session) || isIncognitoSession(session));
|
|
13990
14014
|
return { queued: kept.reverse(), open: gate.open.reverse(), incognito: skipped.reverse() };
|
|
13991
14015
|
} catch {
|
|
13992
14016
|
return { queued: [], open: [], incognito: [] };
|
|
@@ -14125,8 +14149,7 @@ async function runKnowledgeSync(options = {}) {
|
|
|
14125
14149
|
}
|
|
14126
14150
|
const worthStudying = deps.worthStudying ?? isWorthStudying;
|
|
14127
14151
|
const isIncognitoChat = deps.isIncognito ?? isIncognitoSession;
|
|
14128
|
-
const
|
|
14129
|
-
const isIncognito = (session) => incognitoAgents.has(session.harness) || isIncognitoChat(session);
|
|
14152
|
+
const isIncognito = (session) => isAgentIncognito(state, session) || isIncognitoChat(session);
|
|
14130
14153
|
const studiedSnapshot = lastStudiedSnapshot(state.mined_sessions);
|
|
14131
14154
|
const examined = [];
|
|
14132
14155
|
const batch = [];
|
|
@@ -14333,7 +14356,7 @@ var init_conflicts = __esm(() => {
|
|
|
14333
14356
|
});
|
|
14334
14357
|
|
|
14335
14358
|
// src/telemetry/debug-id.ts
|
|
14336
|
-
var BUNDLE_DEBUG_ID_PLACEHOLDER = "
|
|
14359
|
+
var BUNDLE_DEBUG_ID_PLACEHOLDER = "6315379c-189a-f368-6475-6e2164756e21";
|
|
14337
14360
|
|
|
14338
14361
|
// src/telemetry/telemetry.ts
|
|
14339
14362
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
@@ -62521,10 +62544,13 @@ function hasShape(expected, actual) {
|
|
|
62521
62544
|
}
|
|
62522
62545
|
return expected === actual;
|
|
62523
62546
|
}
|
|
62547
|
+
function isUserChoiceKey(key) {
|
|
62548
|
+
return USER_CHOICE_KEYS.has(key);
|
|
62549
|
+
}
|
|
62524
62550
|
function withoutUserChoices(entry) {
|
|
62525
62551
|
if (typeof entry !== "object" || entry === null || Array.isArray(entry))
|
|
62526
62552
|
return entry;
|
|
62527
|
-
return Object.fromEntries(Object.entries(entry).filter(([key]) => !
|
|
62553
|
+
return Object.fromEntries(Object.entries(entry).filter(([key]) => !isUserChoiceKey(key)));
|
|
62528
62554
|
}
|
|
62529
62555
|
function entryHasShape(expected, actual) {
|
|
62530
62556
|
return hasShape(withoutUserChoices(expected), withoutUserChoices(actual));
|
|
@@ -62723,7 +62749,7 @@ var init_cline_cli = __esm(() => {
|
|
|
62723
62749
|
import { existsSync as existsSync22, readFileSync as readFileSync22 } from "node:fs";
|
|
62724
62750
|
import { dirname as dirname11, join as join29 } from "node:path";
|
|
62725
62751
|
function codexHome3() {
|
|
62726
|
-
return process.env.CODEX_HOME
|
|
62752
|
+
return process.env.CODEX_HOME || expandHome("~/.codex");
|
|
62727
62753
|
}
|
|
62728
62754
|
function getConfigPath2(global2) {
|
|
62729
62755
|
if (global2)
|
|
@@ -62745,66 +62771,130 @@ function tomlValue(value) {
|
|
|
62745
62771
|
return Array.isArray(value) ? `[${value.map(tomlString).join(", ")}]` : tomlString(value);
|
|
62746
62772
|
}
|
|
62747
62773
|
function dosuEntry(url, apiKey, npx, path) {
|
|
62748
|
-
return npxRemoteEntry(url, apiKey, npx, path);
|
|
62774
|
+
return { ...npxRemoteEntry(url, apiKey, npx, path), omit_tools_from: ["deferred"] };
|
|
62775
|
+
}
|
|
62776
|
+
function isUserKey(key) {
|
|
62777
|
+
return isUserChoiceKey(key) || key === "tools" || key.startsWith("tools.");
|
|
62778
|
+
}
|
|
62779
|
+
function isUserTable(name) {
|
|
62780
|
+
return name === `${DOSU_TABLE}.tools` || name.startsWith(`${DOSU_TABLE}.tools.`);
|
|
62749
62781
|
}
|
|
62750
|
-
function renderDosuEntry(entry) {
|
|
62751
|
-
const tables = [[
|
|
62782
|
+
function renderDosuEntry(entry, kept) {
|
|
62783
|
+
const tables = [[DOSU_TABLE, []]];
|
|
62752
62784
|
for (const [key, value] of Object.entries(entry)) {
|
|
62753
|
-
if (typeof value === "string" || Array.isArray(value))
|
|
62754
|
-
tables[0][1]
|
|
62755
|
-
else
|
|
62756
|
-
|
|
62785
|
+
if (typeof value === "string" || Array.isArray(value)) {
|
|
62786
|
+
tables[0][1].push(`${key} = ${tomlValue(value)}`);
|
|
62787
|
+
} else {
|
|
62788
|
+
const lines = Object.entries(value).map(([k, v]) => `${k} = ${tomlValue(v)}`);
|
|
62789
|
+
tables.push([`${DOSU_TABLE}.${key}`, lines]);
|
|
62790
|
+
}
|
|
62757
62791
|
}
|
|
62758
|
-
|
|
62759
|
-
|
|
62760
|
-
return `
|
|
62792
|
+
tables[0][1].push(...kept.root);
|
|
62793
|
+
return tables.map(([name, lines]) => `
|
|
62761
62794
|
[${name}]
|
|
62762
62795
|
${lines.join(`
|
|
62763
62796
|
`)}
|
|
62764
|
-
|
|
62765
|
-
|
|
62766
|
-
|
|
62767
|
-
|
|
62768
|
-
|
|
62797
|
+
`).join("") + kept.tables.map((table) => `
|
|
62798
|
+
${table}
|
|
62799
|
+
`).join("");
|
|
62800
|
+
}
|
|
62801
|
+
function openBrackets(text) {
|
|
62802
|
+
let depth = 0;
|
|
62803
|
+
let quote = null;
|
|
62804
|
+
for (let i = 0;i < text.length; i++) {
|
|
62805
|
+
const c = text[i];
|
|
62806
|
+
if (quote) {
|
|
62807
|
+
if (c === "\\" && quote === '"')
|
|
62808
|
+
i++;
|
|
62809
|
+
else if (c === quote)
|
|
62810
|
+
quote = null;
|
|
62811
|
+
} else if (c === '"' || c === "'")
|
|
62812
|
+
quote = c;
|
|
62813
|
+
else if (c === "#")
|
|
62814
|
+
break;
|
|
62815
|
+
else if (c === "[" || c === "{")
|
|
62816
|
+
depth++;
|
|
62817
|
+
else if (c === "]" || c === "}")
|
|
62818
|
+
depth--;
|
|
62819
|
+
}
|
|
62820
|
+
return depth;
|
|
62769
62821
|
}
|
|
62770
|
-
function
|
|
62771
|
-
|
|
62822
|
+
function dosuTables(content) {
|
|
62823
|
+
const tables = [];
|
|
62772
62824
|
let table;
|
|
62825
|
+
let open;
|
|
62826
|
+
let depth = 0;
|
|
62773
62827
|
for (const line of content.split(`
|
|
62774
62828
|
`)) {
|
|
62775
62829
|
const name = sectionName(line);
|
|
62776
62830
|
if (name !== null) {
|
|
62777
|
-
|
|
62778
|
-
|
|
62779
|
-
|
|
62780
|
-
|
|
62781
|
-
if (name === "mcp_servers.dosu") {
|
|
62782
|
-
table = entry;
|
|
62783
|
-
} else {
|
|
62784
|
-
table = {};
|
|
62785
|
-
entry[name.slice("mcp_servers.dosu.".length)] = table;
|
|
62786
|
-
}
|
|
62831
|
+
open = undefined;
|
|
62832
|
+
table = isDosuSection(name) ? { name, header: line.trim(), statements: [] } : undefined;
|
|
62833
|
+
if (table)
|
|
62834
|
+
tables.push(table);
|
|
62787
62835
|
continue;
|
|
62788
62836
|
}
|
|
62837
|
+
if (open && depth > 0) {
|
|
62838
|
+
open.value += `
|
|
62839
|
+
${line}`;
|
|
62840
|
+
open.text += `
|
|
62841
|
+
${line}`;
|
|
62842
|
+
depth += openBrackets(line);
|
|
62843
|
+
continue;
|
|
62844
|
+
}
|
|
62845
|
+
open = undefined;
|
|
62789
62846
|
const text = line.trim();
|
|
62790
62847
|
if (!table || !text || text.startsWith("#"))
|
|
62791
62848
|
continue;
|
|
62792
62849
|
const eq = text.indexOf("=");
|
|
62793
62850
|
const key = eq === -1 ? text : text.slice(0, eq).trim();
|
|
62794
|
-
const
|
|
62795
|
-
|
|
62796
|
-
|
|
62797
|
-
|
|
62798
|
-
|
|
62851
|
+
const value = eq === -1 ? "" : text.slice(eq + 1).trim();
|
|
62852
|
+
open = { key, value, text: line };
|
|
62853
|
+
table.statements.push(open);
|
|
62854
|
+
depth = openBrackets(value);
|
|
62855
|
+
}
|
|
62856
|
+
return tables;
|
|
62857
|
+
}
|
|
62858
|
+
function readDosuEntry(content) {
|
|
62859
|
+
let entry;
|
|
62860
|
+
for (const { name, statements } of dosuTables(content)) {
|
|
62861
|
+
entry ??= {};
|
|
62862
|
+
if (isUserTable(name))
|
|
62863
|
+
continue;
|
|
62864
|
+
const isRoot = name === DOSU_TABLE;
|
|
62865
|
+
const table = isRoot ? entry : {};
|
|
62866
|
+
if (!isRoot)
|
|
62867
|
+
entry[name.slice(DOSU_TABLE.length + 1)] = table;
|
|
62868
|
+
for (const { key, value } of statements) {
|
|
62869
|
+
if (isRoot && isUserKey(key))
|
|
62870
|
+
continue;
|
|
62871
|
+
try {
|
|
62872
|
+
table[key] = JSON.parse(value);
|
|
62873
|
+
} catch {
|
|
62874
|
+
table[key] = value;
|
|
62875
|
+
}
|
|
62799
62876
|
}
|
|
62800
62877
|
}
|
|
62801
62878
|
return entry;
|
|
62802
62879
|
}
|
|
62880
|
+
function userSettings(content) {
|
|
62881
|
+
const kept = { root: [], tables: [] };
|
|
62882
|
+
for (const { name, header, statements } of dosuTables(content)) {
|
|
62883
|
+
if (name === DOSU_TABLE) {
|
|
62884
|
+
kept.root.push(...statements.filter(({ key }) => isUserKey(key)).map(({ text }) => text));
|
|
62885
|
+
} else if (isUserTable(name)) {
|
|
62886
|
+
kept.tables.push([header, ...statements.map(({ text }) => text)].join(`
|
|
62887
|
+
`));
|
|
62888
|
+
}
|
|
62889
|
+
}
|
|
62890
|
+
return kept;
|
|
62891
|
+
}
|
|
62803
62892
|
function installDosuToTOML(path, cfg) {
|
|
62804
|
-
const
|
|
62893
|
+
const existing = readTOML(path);
|
|
62894
|
+
const content = removeDosuFromTOML(existing);
|
|
62805
62895
|
const npx = findNpx();
|
|
62806
62896
|
const entry = dosuEntry(mcpEndpoint(cfg), cfg.active_account?.target?.api_key, npx, npxPathEnv(npx));
|
|
62807
|
-
writeTOML(path, content + renderDosuEntry(entry));
|
|
62897
|
+
writeTOML(path, content + renderDosuEntry(entry, userSettings(existing)));
|
|
62808
62898
|
}
|
|
62809
62899
|
function sectionName(line) {
|
|
62810
62900
|
const header = line.trim();
|
|
@@ -62812,7 +62902,7 @@ function sectionName(line) {
|
|
|
62812
62902
|
return match ? match[1].trim() : null;
|
|
62813
62903
|
}
|
|
62814
62904
|
function isDosuSection(name) {
|
|
62815
|
-
return name ===
|
|
62905
|
+
return name === DOSU_TABLE || name.startsWith(`${DOSU_TABLE}.`);
|
|
62816
62906
|
}
|
|
62817
62907
|
function removeDosuFromTOML(content) {
|
|
62818
62908
|
const result = [];
|
|
@@ -62870,7 +62960,7 @@ function pruneLegacyRemoteEntry(path) {
|
|
|
62870
62960
|
return;
|
|
62871
62961
|
writeTOML(path, removeDosuFromTOML(content));
|
|
62872
62962
|
}
|
|
62873
|
-
var REMOTE_HTTP_KEY, CodexProvider = () => ({
|
|
62963
|
+
var DOSU_TABLE = "mcp_servers.dosu", REMOTE_HTTP_KEY, CodexProvider = () => ({
|
|
62874
62964
|
name: () => "Codex (CLI + Desktop)",
|
|
62875
62965
|
id: () => "codex",
|
|
62876
62966
|
supportsLocal: () => true,
|
|
@@ -69217,4 +69307,4 @@ main().catch((err) => {
|
|
|
69217
69307
|
process.exit(1);
|
|
69218
69308
|
});
|
|
69219
69309
|
|
|
69220
|
-
//# debugId=
|
|
69310
|
+
//# debugId=6315379c-189a-f368-6475-6e2164756e21
|