@dosu/cli 0.56.1 → 0.57.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/README.md +3 -2
- package/bin/dosu.js +370 -189
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -96,15 +96,16 @@ Or right-click the binary, select "Open", and click "Open" in the dialog.
|
|
|
96
96
|
| `dosu login` | Authenticate with Dosu via browser OAuth |
|
|
97
97
|
| `dosu logout` | Clear saved credentials |
|
|
98
98
|
| `dosu status [--json]` | Show current authentication and MCP status |
|
|
99
|
-
| `dosu upgrade` | Update Dosu through the package manager that installed it |
|
|
99
|
+
| `dosu upgrade` | Update Dosu through the package manager that installed it, then re-run `dosu setup` on the new version |
|
|
100
100
|
| `dosu mcp list` | List supported AI tools |
|
|
101
101
|
| `dosu mcp add <tool>` | Add the Dosu MCP server to a specific tool |
|
|
102
|
+
| `dosu mcp refresh` | Rewrite the Dosu MCP entry in every already-configured tool from the current setup |
|
|
102
103
|
| `dosu logs` | View or manage debug logs (`--tail`, `--clear`) |
|
|
103
104
|
| `dosu telemetry` | Manage usage analytics and error diagnostics (`status`, `enable`, `disable`, `reset`) |
|
|
104
105
|
|
|
105
106
|
`dosu mcp add` takes `-g, --global` to install for all projects instead of project-local, and `--show-secret` to print the full manual config.
|
|
106
107
|
|
|
107
|
-
`dosu upgrade` delegates to npm, pnpm, Yarn Classic, or Homebrew only after confirming which manager owns the current installation. Temporary package-runner invocations stay ephemeral, ambiguous or local installs are left unchanged, and standalone binaries receive the latest safe manual download path.
|
|
108
|
+
`dosu upgrade` delegates to npm, pnpm, Yarn Classic, or Homebrew only after confirming which manager owns the current installation. Temporary package-runner invocations stay ephemeral, ambiguous or local installs are left unchanged, and standalone binaries receive the latest safe manual download path. After a successful update it re-invokes the new version to run `dosu setup`, so every configured tool gets the current MCP entry, hooks, status line, rules, and skill; without a TTY it runs the non-interactive `dosu mcp refresh` instead. Upgrades done outside `dosu upgrade` (npm, brew, `npx @dosu/cli@latest`) get a safety net: when the new version changed the shape of the MCP entry, the first command on it silently rewrites configured tools' MCP entries and prompts you to run `dosu setup` for the rest.
|
|
108
109
|
|
|
109
110
|
### Platform commands
|
|
110
111
|
|
package/bin/dosu.js
CHANGED
|
@@ -636,7 +636,18 @@ function numberValue(value) {
|
|
|
636
636
|
var init_config_v1_migration = () => {};
|
|
637
637
|
|
|
638
638
|
// src/config/config.ts
|
|
639
|
-
import {
|
|
639
|
+
import {
|
|
640
|
+
closeSync,
|
|
641
|
+
constants,
|
|
642
|
+
existsSync as existsSync2,
|
|
643
|
+
fstatSync,
|
|
644
|
+
mkdirSync,
|
|
645
|
+
openSync,
|
|
646
|
+
readFileSync,
|
|
647
|
+
readSync,
|
|
648
|
+
renameSync,
|
|
649
|
+
writeFileSync
|
|
650
|
+
} from "node:fs";
|
|
640
651
|
import { homedir as homedir2 } from "node:os";
|
|
641
652
|
import { join as join2 } from "node:path";
|
|
642
653
|
function getConfigUserID(cfg) {
|
|
@@ -701,6 +712,26 @@ function loadConfig() {
|
|
|
701
712
|
} catch {}
|
|
702
713
|
return parsed;
|
|
703
714
|
}
|
|
715
|
+
function loadConfigNonBlocking() {
|
|
716
|
+
let fd;
|
|
717
|
+
try {
|
|
718
|
+
fd = openSync(getConfigPath(), constants.O_RDONLY | constants.O_NONBLOCK);
|
|
719
|
+
const file = fstatSync(fd);
|
|
720
|
+
if (!file.isFile() || file.size > MAX_BACKGROUND_CONFIG_BYTES)
|
|
721
|
+
return;
|
|
722
|
+
const content = Buffer.alloc(MAX_BACKGROUND_CONFIG_BYTES);
|
|
723
|
+
const bytesRead = readSync(fd, content, 0, content.byteLength, 0);
|
|
724
|
+
return parseConfig(JSON.parse(content.subarray(0, bytesRead).toString("utf8")));
|
|
725
|
+
} catch {
|
|
726
|
+
return;
|
|
727
|
+
} finally {
|
|
728
|
+
if (fd !== undefined) {
|
|
729
|
+
try {
|
|
730
|
+
closeSync(fd);
|
|
731
|
+
} catch {}
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
}
|
|
704
735
|
function parseConfig(raw) {
|
|
705
736
|
if (isConfigV2(raw))
|
|
706
737
|
return normalizeV2(raw);
|
|
@@ -796,8 +827,10 @@ function stringValue2(value) {
|
|
|
796
827
|
function numberValue2(value) {
|
|
797
828
|
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
798
829
|
}
|
|
830
|
+
var MAX_BACKGROUND_CONFIG_BYTES;
|
|
799
831
|
var init_config = __esm(() => {
|
|
800
832
|
init_config_v1_migration();
|
|
833
|
+
MAX_BACKGROUND_CONFIG_BYTES = 64 * 1024;
|
|
801
834
|
});
|
|
802
835
|
|
|
803
836
|
// src/mcp/config-helpers.ts
|
|
@@ -1050,7 +1083,7 @@ function isNpxInvocation(channel = INSTALL_CHANNEL, env = process.env) {
|
|
|
1050
1083
|
function getVersionString() {
|
|
1051
1084
|
return `v${VERSION}`;
|
|
1052
1085
|
}
|
|
1053
|
-
var VERSION = "0.
|
|
1086
|
+
var VERSION = "0.57.0", INSTALL_CHANNEL = "npm";
|
|
1054
1087
|
|
|
1055
1088
|
// src/debug/logger.ts
|
|
1056
1089
|
import {
|
|
@@ -1829,21 +1862,21 @@ var init_read = __esm(() => {
|
|
|
1829
1862
|
});
|
|
1830
1863
|
|
|
1831
1864
|
// src/sync/incognito.ts
|
|
1832
|
-
import { closeSync, fstatSync, openSync, readSync } from "node:fs";
|
|
1865
|
+
import { closeSync as closeSync2, fstatSync as fstatSync2, openSync as openSync2, readSync as readSync2 } from "node:fs";
|
|
1833
1866
|
function textHasIncognitoMarker(text) {
|
|
1834
1867
|
return text.includes(INCOGNITO_MARKER) || text.includes(COMMAND_NAME_MARKER);
|
|
1835
1868
|
}
|
|
1836
1869
|
function transcriptHasIncognitoMarker(path, maxBytes = MAX_SCAN_BYTES) {
|
|
1837
1870
|
let fd;
|
|
1838
1871
|
try {
|
|
1839
|
-
fd =
|
|
1840
|
-
const size = Math.min(
|
|
1872
|
+
fd = openSync2(path, "r");
|
|
1873
|
+
const size = Math.min(fstatSync2(fd).size, maxBytes);
|
|
1841
1874
|
if (size === 0)
|
|
1842
1875
|
return false;
|
|
1843
1876
|
const buffer = Buffer.allocUnsafe(size);
|
|
1844
1877
|
let offset = 0;
|
|
1845
1878
|
while (offset < size) {
|
|
1846
|
-
const read =
|
|
1879
|
+
const read = readSync2(fd, buffer, offset, size - offset, offset);
|
|
1847
1880
|
if (read === 0)
|
|
1848
1881
|
break;
|
|
1849
1882
|
offset += read;
|
|
@@ -1854,7 +1887,7 @@ function transcriptHasIncognitoMarker(path, maxBytes = MAX_SCAN_BYTES) {
|
|
|
1854
1887
|
} finally {
|
|
1855
1888
|
if (fd !== undefined) {
|
|
1856
1889
|
try {
|
|
1857
|
-
|
|
1890
|
+
closeSync2(fd);
|
|
1858
1891
|
} catch {}
|
|
1859
1892
|
}
|
|
1860
1893
|
}
|
|
@@ -4205,11 +4238,11 @@ var init_session_errors = __esm(() => {
|
|
|
4205
4238
|
// src/config/config-lock.ts
|
|
4206
4239
|
import { randomUUID } from "node:crypto";
|
|
4207
4240
|
import {
|
|
4208
|
-
closeSync as
|
|
4241
|
+
closeSync as closeSync3,
|
|
4209
4242
|
existsSync as existsSync8,
|
|
4210
4243
|
linkSync,
|
|
4211
4244
|
mkdirSync as mkdirSync5,
|
|
4212
|
-
openSync as
|
|
4245
|
+
openSync as openSync3,
|
|
4213
4246
|
readFileSync as readFileSync7,
|
|
4214
4247
|
statSync as statSync3,
|
|
4215
4248
|
unlinkSync,
|
|
@@ -4262,12 +4295,12 @@ async function acquireConfigRefreshLock(options) {
|
|
|
4262
4295
|
}
|
|
4263
4296
|
}
|
|
4264
4297
|
function createLockFile(lockPath, metadata) {
|
|
4265
|
-
const fd =
|
|
4298
|
+
const fd = openSync3(lockPath, "wx", 384);
|
|
4266
4299
|
try {
|
|
4267
4300
|
writeFileSync4(fd, JSON.stringify(metadata));
|
|
4268
4301
|
} catch (cause) {
|
|
4269
4302
|
try {
|
|
4270
|
-
|
|
4303
|
+
closeSync3(fd);
|
|
4271
4304
|
} catch {}
|
|
4272
4305
|
try {
|
|
4273
4306
|
unlinkSync(lockPath);
|
|
@@ -4275,7 +4308,7 @@ function createLockFile(lockPath, metadata) {
|
|
|
4275
4308
|
throw cause;
|
|
4276
4309
|
}
|
|
4277
4310
|
try {
|
|
4278
|
-
|
|
4311
|
+
closeSync3(fd);
|
|
4279
4312
|
} catch (cause) {
|
|
4280
4313
|
try {
|
|
4281
4314
|
unlinkSync(lockPath);
|
|
@@ -11821,12 +11854,12 @@ var init_integrations = __esm(() => {
|
|
|
11821
11854
|
|
|
11822
11855
|
// src/sessions/project-dir.ts
|
|
11823
11856
|
import {
|
|
11824
|
-
closeSync as
|
|
11857
|
+
closeSync as closeSync4,
|
|
11825
11858
|
existsSync as existsSync11,
|
|
11826
11859
|
mkdirSync as mkdirSync7,
|
|
11827
|
-
openSync as
|
|
11860
|
+
openSync as openSync4,
|
|
11828
11861
|
readFileSync as readFileSync11,
|
|
11829
|
-
readSync as
|
|
11862
|
+
readSync as readSync3,
|
|
11830
11863
|
renameSync as renameSync3,
|
|
11831
11864
|
statSync as statSync4,
|
|
11832
11865
|
writeFileSync as writeFileSync7
|
|
@@ -11859,18 +11892,18 @@ function saveCacheFile(configDir, entries) {
|
|
|
11859
11892
|
function readHead(path, bytes = HEAD_BYTES) {
|
|
11860
11893
|
let fd;
|
|
11861
11894
|
try {
|
|
11862
|
-
fd =
|
|
11895
|
+
fd = openSync4(path, "r");
|
|
11863
11896
|
} catch {
|
|
11864
11897
|
return null;
|
|
11865
11898
|
}
|
|
11866
11899
|
try {
|
|
11867
11900
|
const buf = Buffer.alloc(bytes);
|
|
11868
|
-
const read =
|
|
11901
|
+
const read = readSync3(fd, buf, 0, bytes, 0);
|
|
11869
11902
|
return buf.subarray(0, read).toString("utf-8");
|
|
11870
11903
|
} catch {
|
|
11871
11904
|
return null;
|
|
11872
11905
|
} finally {
|
|
11873
|
-
|
|
11906
|
+
closeSync4(fd);
|
|
11874
11907
|
}
|
|
11875
11908
|
}
|
|
11876
11909
|
function cwdFromJsonlHead(text) {
|
|
@@ -13680,7 +13713,7 @@ var init_sync = __esm(() => {
|
|
|
13680
13713
|
});
|
|
13681
13714
|
|
|
13682
13715
|
// src/telemetry/debug-id.ts
|
|
13683
|
-
var BUNDLE_DEBUG_ID_PLACEHOLDER = "
|
|
13716
|
+
var BUNDLE_DEBUG_ID_PLACEHOLDER = "6712b11a-8117-30cb-6475-6e2164756e21";
|
|
13684
13717
|
|
|
13685
13718
|
// src/telemetry/telemetry.ts
|
|
13686
13719
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
@@ -15205,7 +15238,7 @@ var init_env = __esm(() => {
|
|
|
15205
15238
|
});
|
|
15206
15239
|
|
|
15207
15240
|
// src/learner/executable.ts
|
|
15208
|
-
import { accessSync, constants, existsSync as existsSync16 } from "node:fs";
|
|
15241
|
+
import { accessSync, constants as constants2, existsSync as existsSync16 } from "node:fs";
|
|
15209
15242
|
import { createRequire as createRequire3 } from "node:module";
|
|
15210
15243
|
import { homedir as homedir6 } from "node:os";
|
|
15211
15244
|
import { delimiter as delimiter2, dirname as dirname6, join as join16 } from "node:path";
|
|
@@ -15224,7 +15257,7 @@ function sdkNativeBinaryExists() {
|
|
|
15224
15257
|
}
|
|
15225
15258
|
function isExecutable(path) {
|
|
15226
15259
|
try {
|
|
15227
|
-
accessSync(path,
|
|
15260
|
+
accessSync(path, constants2.X_OK);
|
|
15228
15261
|
return true;
|
|
15229
15262
|
} catch {
|
|
15230
15263
|
return false;
|
|
@@ -60724,6 +60757,10 @@ function runUpgrade(channel = INSTALL_CHANNEL, options = {}) {
|
|
|
60724
60757
|
}
|
|
60725
60758
|
manager = owningPackageManager(options.entrypoint ?? process.argv[1], platform, options.comSpec, env, cwd);
|
|
60726
60759
|
if (!manager) {
|
|
60760
|
+
if (env.DOSU_DEV === "true") {
|
|
60761
|
+
console.log("DOSU_DEV=true and this copy is not a global package: skipping the package install.");
|
|
60762
|
+
return 0;
|
|
60763
|
+
}
|
|
60727
60764
|
printNonGlobalPackageGuidance();
|
|
60728
60765
|
return 1;
|
|
60729
60766
|
}
|
|
@@ -60756,6 +60793,41 @@ Could not update Dosu automatically.`);
|
|
|
60756
60793
|
console.log('Run "dosu --version" to verify.');
|
|
60757
60794
|
return 0;
|
|
60758
60795
|
}
|
|
60796
|
+
function postUpgradeArgs(interactive) {
|
|
60797
|
+
return interactive ? ["setup"] : ["mcp", "refresh"];
|
|
60798
|
+
}
|
|
60799
|
+
function newBinaryInvocation(channel, args, entrypoint = process.argv[1], execPath = process.execPath) {
|
|
60800
|
+
if (channel === "npm") {
|
|
60801
|
+
return entrypoint ? { command: execPath, args: [entrypoint, ...args] } : null;
|
|
60802
|
+
}
|
|
60803
|
+
if (channel === "homebrew") {
|
|
60804
|
+
return { command: "dosu", args };
|
|
60805
|
+
}
|
|
60806
|
+
return null;
|
|
60807
|
+
}
|
|
60808
|
+
function isInteractiveTerminal() {
|
|
60809
|
+
return process.stdin.isTTY === true && process.stdout.isTTY === true;
|
|
60810
|
+
}
|
|
60811
|
+
function setupAgentsWithNewBinary(channel, options) {
|
|
60812
|
+
const interactive = options.interactive ?? isInteractiveTerminal();
|
|
60813
|
+
const invocation = newBinaryInvocation(channel, postUpgradeArgs(interactive), options.entrypoint ?? process.argv[1]);
|
|
60814
|
+
if (!invocation) {
|
|
60815
|
+
console.error(SETUP_FALLBACK);
|
|
60816
|
+
return;
|
|
60817
|
+
}
|
|
60818
|
+
console.log(interactive ? `
|
|
60819
|
+
Running setup with the new version to update your AI agents...
|
|
60820
|
+
` : `
|
|
60821
|
+
Refreshing agent MCP configs with the new version...`);
|
|
60822
|
+
const result = spawnSync(invocation.command, invocation.args, {
|
|
60823
|
+
cwd: options.cwd ?? homedir9(),
|
|
60824
|
+
shell: false,
|
|
60825
|
+
stdio: "inherit"
|
|
60826
|
+
});
|
|
60827
|
+
if (result.error || result.status !== 0) {
|
|
60828
|
+
console.error(SETUP_FALLBACK);
|
|
60829
|
+
}
|
|
60830
|
+
}
|
|
60759
60831
|
async function completeUpgrade(channel = INSTALL_CHANNEL, options = {}) {
|
|
60760
60832
|
const status = runUpgrade(channel, options);
|
|
60761
60833
|
if (status !== 0)
|
|
@@ -60771,16 +60843,17 @@ async function completeUpgrade(channel = INSTALL_CHANNEL, options = {}) {
|
|
|
60771
60843
|
} catch {
|
|
60772
60844
|
console.error('Skills could not be refreshed. Run "dosu skill update" to retry.');
|
|
60773
60845
|
}
|
|
60846
|
+
setupAgentsWithNewBinary(channel, options);
|
|
60774
60847
|
return 0;
|
|
60775
60848
|
}
|
|
60776
60849
|
function upgradeCommand() {
|
|
60777
|
-
return new Command("upgrade").description("Update Dosu to the latest version
|
|
60850
|
+
return new Command("upgrade").description("Update Dosu to the latest version, then re-run setup to update your AI agents").action(async () => {
|
|
60778
60851
|
const status = await completeUpgrade();
|
|
60779
60852
|
if (status !== 0)
|
|
60780
60853
|
process.exitCode = status;
|
|
60781
60854
|
});
|
|
60782
60855
|
}
|
|
60783
|
-
var import_picocolors31, PACKAGE_NAME = "@dosu/cli", LATEST_PACKAGE, BREW_MANUAL_COMMAND = "brew upgrade dosu-ai/dosu/dosu", NPX_COMMAND = "npx -y @dosu/cli@latest", PROBE_TIMEOUT_MS = 5000, RELEASES_URL = "https://github.com/dosu-ai/dosu-cli/releases/latest", PACKAGE_MANAGERS;
|
|
60856
|
+
var import_picocolors31, PACKAGE_NAME = "@dosu/cli", LATEST_PACKAGE, BREW_MANUAL_COMMAND = "brew upgrade dosu-ai/dosu/dosu", NPX_COMMAND = "npx -y @dosu/cli@latest", PROBE_TIMEOUT_MS = 5000, RELEASES_URL = "https://github.com/dosu-ai/dosu-cli/releases/latest", PACKAGE_MANAGERS, SETUP_FALLBACK = 'Run "dosu setup" to finish updating your AI agents.';
|
|
60784
60857
|
var init_upgrade = __esm(() => {
|
|
60785
60858
|
init_commander();
|
|
60786
60859
|
init_skill();
|
|
@@ -60806,7 +60879,7 @@ var init_upgrade = __esm(() => {
|
|
|
60806
60879
|
});
|
|
60807
60880
|
|
|
60808
60881
|
// src/debug/follow.ts
|
|
60809
|
-
import { closeSync as
|
|
60882
|
+
import { closeSync as closeSync6, openSync as openSync6, readSync as readSync5, statSync as statSync8 } from "node:fs";
|
|
60810
60883
|
function createLogFollower(path, emit) {
|
|
60811
60884
|
const sizeOf = () => {
|
|
60812
60885
|
try {
|
|
@@ -60824,15 +60897,15 @@ function createLogFollower(path, emit) {
|
|
|
60824
60897
|
if (size === offset)
|
|
60825
60898
|
return;
|
|
60826
60899
|
try {
|
|
60827
|
-
const fd =
|
|
60900
|
+
const fd = openSync6(path, "r");
|
|
60828
60901
|
try {
|
|
60829
60902
|
const buf = Buffer.alloc(size - offset);
|
|
60830
|
-
const read =
|
|
60903
|
+
const read = readSync5(fd, buf, 0, buf.length, offset);
|
|
60831
60904
|
offset += read;
|
|
60832
60905
|
if (read > 0)
|
|
60833
60906
|
emit(buf.toString("utf-8", 0, read));
|
|
60834
60907
|
} finally {
|
|
60835
|
-
|
|
60908
|
+
closeSync6(fd);
|
|
60836
60909
|
}
|
|
60837
60910
|
} catch {}
|
|
60838
60911
|
}
|
|
@@ -61510,6 +61583,36 @@ var init_providers = __esm(() => {
|
|
|
61510
61583
|
init_zed();
|
|
61511
61584
|
});
|
|
61512
61585
|
|
|
61586
|
+
// src/mcp/refresh.ts
|
|
61587
|
+
function configuredProviders() {
|
|
61588
|
+
return allSetupProviders().filter((provider) => {
|
|
61589
|
+
try {
|
|
61590
|
+
return provider.isInstalled() && provider.isConfigured();
|
|
61591
|
+
} catch {
|
|
61592
|
+
return false;
|
|
61593
|
+
}
|
|
61594
|
+
});
|
|
61595
|
+
}
|
|
61596
|
+
function refreshConfiguredProviders(cfg) {
|
|
61597
|
+
const result = { updated: [], failed: [] };
|
|
61598
|
+
for (const provider of configuredProviders()) {
|
|
61599
|
+
try {
|
|
61600
|
+
provider.install(cfg, true);
|
|
61601
|
+
logger.info("mcp", `Refreshed ${provider.name()} MCP entry`);
|
|
61602
|
+
result.updated.push(provider);
|
|
61603
|
+
} catch (err) {
|
|
61604
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
61605
|
+
logger.error("mcp", `Refresh failed for ${provider.name()}: ${error.message}`);
|
|
61606
|
+
result.failed.push({ provider, error });
|
|
61607
|
+
}
|
|
61608
|
+
}
|
|
61609
|
+
return result;
|
|
61610
|
+
}
|
|
61611
|
+
var init_refresh = __esm(() => {
|
|
61612
|
+
init_logger();
|
|
61613
|
+
init_providers();
|
|
61614
|
+
});
|
|
61615
|
+
|
|
61513
61616
|
// src/version/update-check.ts
|
|
61514
61617
|
import { existsSync as existsSync23, mkdirSync as mkdirSync13, readFileSync as readFileSync22, writeFileSync as writeFileSync14 } from "node:fs";
|
|
61515
61618
|
import { join as join39 } from "node:path";
|
|
@@ -61665,15 +61768,98 @@ var init_update_check = __esm(() => {
|
|
|
61665
61768
|
SEMVER_PATTERN = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
61666
61769
|
});
|
|
61667
61770
|
|
|
61771
|
+
// src/version/mcp-refresh-check.ts
|
|
61772
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync14, readFileSync as readFileSync23, writeFileSync as writeFileSync15 } from "node:fs";
|
|
61773
|
+
import { join as join40 } from "node:path";
|
|
61774
|
+
function needsMcpRefresh(previous, current) {
|
|
61775
|
+
if (previous === null)
|
|
61776
|
+
return true;
|
|
61777
|
+
if (previous === current)
|
|
61778
|
+
return false;
|
|
61779
|
+
const [older, newer] = isNewerVersion(current, previous) ? [previous, current] : [current, previous];
|
|
61780
|
+
return MCP_FORMAT_CHANGES.some((change) => isNewerVersion(change, older) && !isNewerVersion(change, newer));
|
|
61781
|
+
}
|
|
61782
|
+
function getCachePath4() {
|
|
61783
|
+
return join40(getConfigDir(), CACHE_FILENAME5);
|
|
61784
|
+
}
|
|
61785
|
+
function readMcpRefreshCache() {
|
|
61786
|
+
try {
|
|
61787
|
+
const path = getCachePath4();
|
|
61788
|
+
if (!existsSync24(path))
|
|
61789
|
+
return null;
|
|
61790
|
+
const data = JSON.parse(readFileSync23(path, "utf-8"));
|
|
61791
|
+
if (typeof data?.version === "string")
|
|
61792
|
+
return { version: data.version };
|
|
61793
|
+
return null;
|
|
61794
|
+
} catch {
|
|
61795
|
+
return null;
|
|
61796
|
+
}
|
|
61797
|
+
}
|
|
61798
|
+
function writeMcpRefreshCache(cache) {
|
|
61799
|
+
try {
|
|
61800
|
+
const dir = getConfigDir();
|
|
61801
|
+
if (!existsSync24(dir)) {
|
|
61802
|
+
mkdirSync14(dir, { recursive: true, mode: 448 });
|
|
61803
|
+
}
|
|
61804
|
+
writeFileSync15(getCachePath4(), JSON.stringify(cache), { mode: 384 });
|
|
61805
|
+
} catch {}
|
|
61806
|
+
}
|
|
61807
|
+
function canRefreshMcp(cfg) {
|
|
61808
|
+
const target = cfg.active_account?.target;
|
|
61809
|
+
if (!target?.api_key)
|
|
61810
|
+
return false;
|
|
61811
|
+
return cfg.mode === MODE_OSS || Boolean(target.deployment_id);
|
|
61812
|
+
}
|
|
61813
|
+
function displayNotice3(names) {
|
|
61814
|
+
console.error(`
|
|
61815
|
+
${import_picocolors33.default.green(`✓ Dosu ${VERSION}: refreshed MCP config for ${names.join(", ")}`)}
|
|
61816
|
+
` + `${import_picocolors33.default.dim(` Run ${import_picocolors33.default.cyan('"dosu setup"')} to also update skills, hooks, and rules, then restart your AI agents.`)}
|
|
61817
|
+
`);
|
|
61818
|
+
}
|
|
61819
|
+
function checkForMcpRefresh(options = {}) {
|
|
61820
|
+
const notify = options.notify ?? true;
|
|
61821
|
+
try {
|
|
61822
|
+
const previous = readMcpRefreshCache()?.version ?? null;
|
|
61823
|
+
if (previous === VERSION)
|
|
61824
|
+
return;
|
|
61825
|
+
if (!needsMcpRefresh(previous, VERSION)) {
|
|
61826
|
+
writeMcpRefreshCache({ version: VERSION });
|
|
61827
|
+
return;
|
|
61828
|
+
}
|
|
61829
|
+
const cfg = loadConfigNonBlocking();
|
|
61830
|
+
if (!cfg || !canRefreshMcp(cfg)) {
|
|
61831
|
+
logger.debug("mcp-refresh", "Skipping MCP refresh: no API key or deployment configured");
|
|
61832
|
+
return;
|
|
61833
|
+
}
|
|
61834
|
+
const result = refreshConfiguredProviders(cfg);
|
|
61835
|
+
writeMcpRefreshCache({ version: VERSION });
|
|
61836
|
+
logger.info("mcp-refresh", `Version ${VERSION}: refreshed ${result.updated.length}, failed ${result.failed.length}`);
|
|
61837
|
+
if (notify && result.updated.length > 0) {
|
|
61838
|
+
displayNotice3(result.updated.map((provider) => provider.name()));
|
|
61839
|
+
}
|
|
61840
|
+
} catch (err) {
|
|
61841
|
+
logger.error("mcp-refresh", `MCP refresh check failed: ${err}`);
|
|
61842
|
+
}
|
|
61843
|
+
}
|
|
61844
|
+
var import_picocolors33, CACHE_FILENAME5 = "mcp-refresh.json", MCP_FORMAT_CHANGES;
|
|
61845
|
+
var init_mcp_refresh_check = __esm(() => {
|
|
61846
|
+
init_config();
|
|
61847
|
+
init_logger();
|
|
61848
|
+
init_refresh();
|
|
61849
|
+
init_update_check();
|
|
61850
|
+
import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
61851
|
+
MCP_FORMAT_CHANGES = ["0.53.0"];
|
|
61852
|
+
});
|
|
61853
|
+
|
|
61668
61854
|
// src/rules/installer.ts
|
|
61669
|
-
import { existsSync as
|
|
61855
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync15, readFileSync as readFileSync24, unlinkSync as unlinkSync5, writeFileSync as writeFileSync16 } from "node:fs";
|
|
61670
61856
|
import { homedir as homedir12 } from "node:os";
|
|
61671
|
-
import { dirname as dirname11, join as
|
|
61857
|
+
import { dirname as dirname11, join as join41 } from "node:path";
|
|
61672
61858
|
function claudeConfigDir4() {
|
|
61673
|
-
return process.env.CLAUDE_CONFIG_DIR ||
|
|
61859
|
+
return process.env.CLAUDE_CONFIG_DIR || join41(homedir12(), ".claude");
|
|
61674
61860
|
}
|
|
61675
61861
|
function codexHome4() {
|
|
61676
|
-
return process.env.CODEX_HOME ||
|
|
61862
|
+
return process.env.CODEX_HOME || join41(homedir12(), ".codex");
|
|
61677
61863
|
}
|
|
61678
61864
|
function isRuleAgent(agent) {
|
|
61679
61865
|
return Object.hasOwn(RULE_TARGETS, agent);
|
|
@@ -61699,17 +61885,17 @@ async function fetchDosuRule(fetchImpl = globalThis.fetch) {
|
|
|
61699
61885
|
return normalizeRule(FALLBACK_DOSU_RULE);
|
|
61700
61886
|
}
|
|
61701
61887
|
function ensureParent(path) {
|
|
61702
|
-
|
|
61888
|
+
mkdirSync15(dirname11(path), { recursive: true });
|
|
61703
61889
|
}
|
|
61704
61890
|
function writeIfChanged(path, content) {
|
|
61705
|
-
if (!
|
|
61891
|
+
if (!existsSync25(path)) {
|
|
61706
61892
|
ensureParent(path);
|
|
61707
|
-
|
|
61893
|
+
writeFileSync16(path, content, "utf-8");
|
|
61708
61894
|
return "created";
|
|
61709
61895
|
}
|
|
61710
|
-
if (
|
|
61896
|
+
if (readFileSync24(path, "utf-8") === content)
|
|
61711
61897
|
return "unchanged";
|
|
61712
|
-
|
|
61898
|
+
writeFileSync16(path, content, "utf-8");
|
|
61713
61899
|
return "updated";
|
|
61714
61900
|
}
|
|
61715
61901
|
function findSection(content) {
|
|
@@ -61735,14 +61921,14 @@ function buildSection(content, lineEnding = `
|
|
|
61735
61921
|
return `${DOSU_RULE_SECTION_START}${lineEnding}${body}${lineEnding}${DOSU_RULE_SECTION_END}`;
|
|
61736
61922
|
}
|
|
61737
61923
|
function upsertSection(path, content) {
|
|
61738
|
-
if (!
|
|
61924
|
+
if (!existsSync25(path)) {
|
|
61739
61925
|
const section = buildSection(content);
|
|
61740
61926
|
ensureParent(path);
|
|
61741
|
-
|
|
61927
|
+
writeFileSync16(path, `${section}
|
|
61742
61928
|
`, "utf-8");
|
|
61743
61929
|
return "created";
|
|
61744
61930
|
}
|
|
61745
|
-
const existing =
|
|
61931
|
+
const existing = readFileSync24(path, "utf-8");
|
|
61746
61932
|
const lineEnding = lineEndingFor(existing);
|
|
61747
61933
|
const section = buildSection(content, lineEnding);
|
|
61748
61934
|
const location = findSection(existing);
|
|
@@ -61755,7 +61941,7 @@ function upsertSection(path, content) {
|
|
|
61755
61941
|
}
|
|
61756
61942
|
if (next === existing)
|
|
61757
61943
|
return "unchanged";
|
|
61758
|
-
|
|
61944
|
+
writeFileSync16(path, next, "utf-8");
|
|
61759
61945
|
return "updated";
|
|
61760
61946
|
}
|
|
61761
61947
|
function installRuleForAgent(agent, content) {
|
|
@@ -61772,13 +61958,13 @@ function removeRuleForAgent(agent) {
|
|
|
61772
61958
|
return null;
|
|
61773
61959
|
const target = RULE_TARGETS[agent];
|
|
61774
61960
|
const path = target.path();
|
|
61775
|
-
if (!
|
|
61961
|
+
if (!existsSync25(path))
|
|
61776
61962
|
return { agent, path, action: "not_found" };
|
|
61777
61963
|
if (target.kind === "file") {
|
|
61778
61964
|
unlinkSync5(path);
|
|
61779
61965
|
return { agent, path, action: "removed" };
|
|
61780
61966
|
}
|
|
61781
|
-
const existing =
|
|
61967
|
+
const existing = readFileSync24(path, "utf-8");
|
|
61782
61968
|
const lineEnding = lineEndingFor(existing);
|
|
61783
61969
|
const location = findSection(existing);
|
|
61784
61970
|
if (!location)
|
|
@@ -61787,7 +61973,7 @@ function removeRuleForAgent(agent) {
|
|
|
61787
61973
|
if (!next) {
|
|
61788
61974
|
unlinkSync5(path);
|
|
61789
61975
|
} else {
|
|
61790
|
-
|
|
61976
|
+
writeFileSync16(path, `${next}${lineEnding}`, "utf-8");
|
|
61791
61977
|
}
|
|
61792
61978
|
return { agent, path, action: "removed" };
|
|
61793
61979
|
}
|
|
@@ -61815,36 +62001,36 @@ var init_installer = __esm(() => {
|
|
|
61815
62001
|
RULE_TARGETS = {
|
|
61816
62002
|
claude: {
|
|
61817
62003
|
kind: "file",
|
|
61818
|
-
path: () =>
|
|
62004
|
+
path: () => join41(claudeConfigDir4(), "rules", "dosu.md")
|
|
61819
62005
|
},
|
|
61820
62006
|
cursor: {
|
|
61821
62007
|
kind: "file",
|
|
61822
|
-
path: () =>
|
|
62008
|
+
path: () => join41(homedir12(), ".cursor", "rules", "dosu.mdc"),
|
|
61823
62009
|
cursorFrontmatter: true
|
|
61824
62010
|
},
|
|
61825
62011
|
codex: {
|
|
61826
62012
|
kind: "section",
|
|
61827
|
-
path: () =>
|
|
62013
|
+
path: () => join41(codexHome4(), "AGENTS.md")
|
|
61828
62014
|
},
|
|
61829
62015
|
opencode: {
|
|
61830
62016
|
kind: "section",
|
|
61831
|
-
path: () =>
|
|
62017
|
+
path: () => join41(homedir12(), ".config", "opencode", "AGENTS.md")
|
|
61832
62018
|
},
|
|
61833
62019
|
gemini: {
|
|
61834
62020
|
kind: "section",
|
|
61835
|
-
path: () =>
|
|
62021
|
+
path: () => join41(homedir12(), ".gemini", "GEMINI.md")
|
|
61836
62022
|
},
|
|
61837
62023
|
antigravity: {
|
|
61838
62024
|
kind: "section",
|
|
61839
|
-
path: () =>
|
|
62025
|
+
path: () => join41(homedir12(), ".gemini", "GEMINI.md")
|
|
61840
62026
|
}
|
|
61841
62027
|
};
|
|
61842
62028
|
});
|
|
61843
62029
|
|
|
61844
62030
|
// src/setup/agents-md-step.ts
|
|
61845
62031
|
import { execSync as execSync3 } from "node:child_process";
|
|
61846
|
-
import { existsSync as
|
|
61847
|
-
import { join as
|
|
62032
|
+
import { existsSync as existsSync26, readFileSync as readFileSync25, writeFileSync as writeFileSync17 } from "node:fs";
|
|
62033
|
+
import { join as join42 } from "node:path";
|
|
61848
62034
|
function inGitWorkTree(cwd = process.cwd()) {
|
|
61849
62035
|
try {
|
|
61850
62036
|
const stdout = execSync3("git rev-parse --is-inside-work-tree", {
|
|
@@ -61858,10 +62044,10 @@ function inGitWorkTree(cwd = process.cwd()) {
|
|
|
61858
62044
|
}
|
|
61859
62045
|
function dosuAgentsSectionState(cwd = process.cwd()) {
|
|
61860
62046
|
try {
|
|
61861
|
-
const path =
|
|
61862
|
-
if (!
|
|
62047
|
+
const path = join42(cwd, "AGENTS.md");
|
|
62048
|
+
if (!existsSync26(path))
|
|
61863
62049
|
return "missing";
|
|
61864
|
-
const content =
|
|
62050
|
+
const content = readFileSync25(path, "utf-8");
|
|
61865
62051
|
const startMatch = content.match(SECTION_START_RE);
|
|
61866
62052
|
if (!startMatch || !content.includes(DOSU_SECTION_END))
|
|
61867
62053
|
return "missing";
|
|
@@ -61896,14 +62082,14 @@ function findSection2(content) {
|
|
|
61896
62082
|
return { start, end };
|
|
61897
62083
|
}
|
|
61898
62084
|
function upsertDosuAgentsSection(cwd = process.cwd(), content = FALLBACK_DOSU_RULE) {
|
|
61899
|
-
const path =
|
|
61900
|
-
if (!
|
|
62085
|
+
const path = join42(cwd, "AGENTS.md");
|
|
62086
|
+
if (!existsSync26(path)) {
|
|
61901
62087
|
const section = buildDosuAgentsSection(content);
|
|
61902
|
-
|
|
62088
|
+
writeFileSync17(path, `${section}
|
|
61903
62089
|
`);
|
|
61904
62090
|
return { path, action: "created" };
|
|
61905
62091
|
}
|
|
61906
|
-
const existing =
|
|
62092
|
+
const existing = readFileSync25(path, "utf-8");
|
|
61907
62093
|
const lineEnding = lineEndingFor2(existing);
|
|
61908
62094
|
const section = renderDosuAgentsSection(content, lineEnding);
|
|
61909
62095
|
const location = findSection2(existing);
|
|
@@ -61915,7 +62101,7 @@ function upsertDosuAgentsSection(cwd = process.cwd(), content = FALLBACK_DOSU_RU
|
|
|
61915
62101
|
}
|
|
61916
62102
|
if (next === existing)
|
|
61917
62103
|
return { path, action: "unchanged" };
|
|
61918
|
-
|
|
62104
|
+
writeFileSync17(path, next);
|
|
61919
62105
|
return { path, action: "updated" };
|
|
61920
62106
|
}
|
|
61921
62107
|
async function stepUpdateAgentsMd(cwd = process.cwd(), content) {
|
|
@@ -61971,15 +62157,15 @@ var init_errors3 = __esm(() => {
|
|
|
61971
62157
|
var MCP_PROVIDER_SLUG2 = "dosu_mcp";
|
|
61972
62158
|
|
|
61973
62159
|
// src/sessions/session-title.ts
|
|
61974
|
-
import { existsSync as
|
|
62160
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync16, readFileSync as readFileSync26, renameSync as renameSync6, statSync as statSync9, writeFileSync as writeFileSync18 } from "node:fs";
|
|
61975
62161
|
import { homedir as homedir13 } from "node:os";
|
|
61976
|
-
import { join as
|
|
62162
|
+
import { join as join43 } from "node:path";
|
|
61977
62163
|
function cachePath2(configDir) {
|
|
61978
|
-
return
|
|
62164
|
+
return join43(configDir, CACHE_FILENAME6);
|
|
61979
62165
|
}
|
|
61980
62166
|
function loadCacheFile2(configDir) {
|
|
61981
62167
|
try {
|
|
61982
|
-
const raw = JSON.parse(
|
|
62168
|
+
const raw = JSON.parse(readFileSync26(cachePath2(configDir), "utf-8"));
|
|
61983
62169
|
if (raw.schema_version !== CACHE_SCHEMA_VERSION2 || typeof raw.entries !== "object")
|
|
61984
62170
|
return {};
|
|
61985
62171
|
return raw.entries;
|
|
@@ -61989,12 +62175,12 @@ function loadCacheFile2(configDir) {
|
|
|
61989
62175
|
}
|
|
61990
62176
|
function saveCacheFile2(configDir, entries) {
|
|
61991
62177
|
try {
|
|
61992
|
-
if (!
|
|
61993
|
-
|
|
62178
|
+
if (!existsSync27(configDir))
|
|
62179
|
+
mkdirSync16(configDir, { recursive: true, mode: 448 });
|
|
61994
62180
|
const path = cachePath2(configDir);
|
|
61995
62181
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
61996
62182
|
const file = { schema_version: CACHE_SCHEMA_VERSION2, entries };
|
|
61997
|
-
|
|
62183
|
+
writeFileSync18(tmp, JSON.stringify(file), { mode: 384 });
|
|
61998
62184
|
renameSync6(tmp, path);
|
|
61999
62185
|
} catch {}
|
|
62000
62186
|
}
|
|
@@ -62027,15 +62213,15 @@ function claudeSummaryFromHead(text) {
|
|
|
62027
62213
|
}
|
|
62028
62214
|
return null;
|
|
62029
62215
|
}
|
|
62030
|
-
function reconstructSession(harness, id, slug, home = homedir13(), exists =
|
|
62216
|
+
function reconstructSession(harness, id, slug, home = homedir13(), exists = existsSync27) {
|
|
62031
62217
|
if (!slug)
|
|
62032
62218
|
return null;
|
|
62033
62219
|
const candidates = [];
|
|
62034
62220
|
if (harness === "claude") {
|
|
62035
|
-
candidates.push(
|
|
62221
|
+
candidates.push(join43(home, ".claude", "projects", slug, `${id}.jsonl`));
|
|
62036
62222
|
} else if (harness === "cursor") {
|
|
62037
|
-
const project =
|
|
62038
|
-
candidates.push(
|
|
62223
|
+
const project = join43(home, ".cursor", "projects", slug);
|
|
62224
|
+
candidates.push(join43(project, "agent-transcripts", id, `${id}.jsonl`), join43(project, "agent-transcripts", `${id}.jsonl`));
|
|
62039
62225
|
} else {
|
|
62040
62226
|
return null;
|
|
62041
62227
|
}
|
|
@@ -62047,7 +62233,7 @@ function reconstructSession(harness, id, slug, home = homedir13(), exists = exis
|
|
|
62047
62233
|
}
|
|
62048
62234
|
function readHead2(path) {
|
|
62049
62235
|
try {
|
|
62050
|
-
return
|
|
62236
|
+
return readFileSync26(path, "utf-8").slice(0, 128 * 1024);
|
|
62051
62237
|
} catch {
|
|
62052
62238
|
return null;
|
|
62053
62239
|
}
|
|
@@ -62098,7 +62284,7 @@ function createSessionTitleResolver(configDir = getConfigDir(), deps = {}) {
|
|
|
62098
62284
|
}
|
|
62099
62285
|
};
|
|
62100
62286
|
}
|
|
62101
|
-
var
|
|
62287
|
+
var CACHE_FILENAME6 = "session-titles.json", CACHE_SCHEMA_VERSION2 = 3, HEAD_LINES2 = 50, SESSION_NAME_MAX = 80;
|
|
62102
62288
|
var init_session_title = __esm(() => {
|
|
62103
62289
|
init_config();
|
|
62104
62290
|
init_read();
|
|
@@ -62127,7 +62313,7 @@ var init_alt_screen = __esm(() => {
|
|
|
62127
62313
|
});
|
|
62128
62314
|
|
|
62129
62315
|
// src/tui/activity-view.ts
|
|
62130
|
-
import { existsSync as
|
|
62316
|
+
import { existsSync as existsSync28, readFileSync as readFileSync27 } from "node:fs";
|
|
62131
62317
|
import { basename as basename5 } from "node:path";
|
|
62132
62318
|
function reduceActivityViewKey(key) {
|
|
62133
62319
|
if (key === "q" || key === ESC7 || key === CTRL_C4)
|
|
@@ -62268,15 +62454,15 @@ function statusLine(status) {
|
|
|
62268
62454
|
if (status.running) {
|
|
62269
62455
|
const since = status.startedAt ? ` · since ${localTime(status.startedAt)}` : "";
|
|
62270
62456
|
const pid = status.pid !== undefined ? ` (pid ${status.pid})` : "";
|
|
62271
|
-
return `\uD83D\uDCDA ${
|
|
62457
|
+
return `\uD83D\uDCDA ${import_picocolors34.default.bold(brand("Studying sessions..."))}${import_picocolors34.default.dim(`${pid}${since}`)}`;
|
|
62272
62458
|
}
|
|
62273
62459
|
if (status.state.paused) {
|
|
62274
|
-
return `${
|
|
62460
|
+
return `${import_picocolors34.default.yellow("○")} ${import_picocolors34.default.bold("Paused")} ${import_picocolors34.default.dim("· studying stays off until you resume")}`;
|
|
62275
62461
|
}
|
|
62276
62462
|
if (status.staleLock) {
|
|
62277
|
-
return `${
|
|
62463
|
+
return `${import_picocolors34.default.yellow("○")} ${import_picocolors34.default.bold("Not running")} ${import_picocolors34.default.dim("· a previous run exited without cleaning up")}`;
|
|
62278
62464
|
}
|
|
62279
|
-
return `${
|
|
62465
|
+
return `${import_picocolors34.default.dim("○")} ${import_picocolors34.default.bold("Idle")} ${import_picocolors34.default.dim("· hooks study new sessions automatically")}`;
|
|
62280
62466
|
}
|
|
62281
62467
|
function progressLine(done, ready, width, notes = 0) {
|
|
62282
62468
|
const total = done + ready;
|
|
@@ -62285,7 +62471,7 @@ function progressLine(done, ready, width, notes = 0) {
|
|
|
62285
62471
|
const cells = Math.max(10, Math.min(30, width - 44));
|
|
62286
62472
|
const ratio = Math.max(0, Math.min(1, done / total));
|
|
62287
62473
|
const filled = Math.min(cells, Math.round(ratio * cells));
|
|
62288
|
-
const bar = brand("█".repeat(filled)) +
|
|
62474
|
+
const bar = brand("█".repeat(filled)) + import_picocolors34.default.dim("░".repeat(cells - filled));
|
|
62289
62475
|
const pct = Math.floor(ratio * 100);
|
|
62290
62476
|
const suffix = notes > 0 ? ` · ${notes} suggested page${notes === 1 ? "" : "s"}` : "";
|
|
62291
62477
|
return `${bar} ${done}/${total} studied · ${pct}%${suffix}`;
|
|
@@ -62324,17 +62510,17 @@ function confirmBox(queuedCount, backlog, width, mode = "start") {
|
|
|
62324
62510
|
const verb = mode === "clear" ? "clear" : mode === "stop" ? "stop" : mode === "resume" ? "resume" : "start";
|
|
62325
62511
|
const maxInner = Math.max(20, Math.min(width, contentWidth()) - 4);
|
|
62326
62512
|
const rows = [
|
|
62327
|
-
|
|
62328
|
-
...wrapLine(scope, maxInner, "").map((line) =>
|
|
62513
|
+
import_picocolors34.default.bold(brand(title)),
|
|
62514
|
+
...wrapLine(scope, maxInner, "").map((line) => import_picocolors34.default.dim(line)),
|
|
62329
62515
|
"",
|
|
62330
|
-
`${
|
|
62516
|
+
`${import_picocolors34.default.bold("enter")} ${verb} · ${import_picocolors34.default.bold("esc")} cancel`
|
|
62331
62517
|
];
|
|
62332
62518
|
const inner = Math.min(maxInner, Math.max(...rows.map(visibleWidth2)));
|
|
62333
62519
|
const pad = (row) => row + " ".repeat(Math.max(0, inner - visibleWidth2(row)));
|
|
62334
62520
|
return [
|
|
62335
|
-
|
|
62336
|
-
...rows.map((row) => `${
|
|
62337
|
-
|
|
62521
|
+
import_picocolors34.default.dim(`╭${"─".repeat(inner + 2)}╮`),
|
|
62522
|
+
...rows.map((row) => `${import_picocolors34.default.dim("│")} ${pad(row)} ${import_picocolors34.default.dim("│")}`),
|
|
62523
|
+
import_picocolors34.default.dim(`╰${"─".repeat(inner + 2)}╯`)
|
|
62338
62524
|
];
|
|
62339
62525
|
}
|
|
62340
62526
|
function renderActivityFrame(status, activity, width, backlog = null, pane = DEFAULT_PANE, queued = [], studiedBeforeRun = 0, open = [], runProgress = null, projectNames = {}, sessionNames = {}) {
|
|
@@ -62350,7 +62536,7 @@ function renderActivityFrame(status, activity, width, backlog = null, pane = DEF
|
|
|
62350
62536
|
progress = progressLine(studiedDelta + stepDone, Math.max(0, backlog.ready - stepDone), width, runProgress?.notes ?? 0);
|
|
62351
62537
|
}
|
|
62352
62538
|
const refusal = !status.running && status.state.last_refusal;
|
|
62353
|
-
const refusalLines = refusal ? wrapLine(`! Studying paused: ${refusal.message} (${localTime(refusal.at)})`, width).map((line) =>
|
|
62539
|
+
const refusalLines = refusal ? wrapLine(`! Studying paused: ${refusal.message} (${localTime(refusal.at)})`, width).map((line) => import_picocolors34.default.yellow(line)) : [];
|
|
62354
62540
|
const fullRows = Boolean(pane.fullRows);
|
|
62355
62541
|
const withName = (item, key) => projectNames[key] ? { ...item, project: projectNames[key] } : item;
|
|
62356
62542
|
const latestPass = new Map;
|
|
@@ -62375,7 +62561,7 @@ function renderActivityFrame(status, activity, width, backlog = null, pane = DEF
|
|
|
62375
62561
|
const height = fullRows ? ACTIVITY_VIEW_FULL_LIST_ROWS : ACTIVITY_VIEW_LIST_LINES;
|
|
62376
62562
|
const { visible, above, below } = windowList(source, pane.scroll, height);
|
|
62377
62563
|
const display = fullRows ? visible.flatMap((row) => wrapRow(row, width)) : visible;
|
|
62378
|
-
const listRows = display.length > 0 ? display.map((row) =>
|
|
62564
|
+
const listRows = display.length > 0 ? display.map((row) => import_picocolors34.default.dim(row)) : [import_picocolors34.default.dim(empty)];
|
|
62379
62565
|
const scrollParts = [];
|
|
62380
62566
|
if (above > 0)
|
|
62381
62567
|
scrollParts.push(`↑ ${above} earlier`);
|
|
@@ -62385,14 +62571,14 @@ function renderActivityFrame(status, activity, width, backlog = null, pane = DEF
|
|
|
62385
62571
|
breadcrumb(["home", "activity"], width),
|
|
62386
62572
|
"",
|
|
62387
62573
|
statusLine(status),
|
|
62388
|
-
|
|
62389
|
-
...queueDetail.length > 0 ? wrapLine(queueDetail.join(" · "), width).map((line) =>
|
|
62574
|
+
import_picocolors34.default.dim(studied),
|
|
62575
|
+
...queueDetail.length > 0 ? wrapLine(queueDetail.join(" · "), width).map((line) => import_picocolors34.default.dim(line)) : [],
|
|
62390
62576
|
...progress ? [progress] : [],
|
|
62391
62577
|
...refusalLines,
|
|
62392
62578
|
"",
|
|
62393
62579
|
...tabBar(pane.tab, queued.length, open.length, latestPass.size, width),
|
|
62394
62580
|
...listRows,
|
|
62395
|
-
...scrollParts.length > 0 ? [
|
|
62581
|
+
...scrollParts.length > 0 ? [import_picocolors34.default.dim(clip(scrollParts.join(" · "), width))] : [],
|
|
62396
62582
|
"",
|
|
62397
62583
|
...pane.confirm ? centerBlock(confirmBox(queued.length, backlog, width, pane.confirm), width) : [
|
|
62398
62584
|
...wrapLine([
|
|
@@ -62402,7 +62588,7 @@ function renderActivityFrame(status, activity, width, backlog = null, pane = DEF
|
|
|
62402
62588
|
status.running ? "s stop" : status.state.paused ? "s resume" : "s sync now",
|
|
62403
62589
|
...!status.running && status.state.watermark ? ["c clear"] : [],
|
|
62404
62590
|
"esc back"
|
|
62405
|
-
].join(" · "), width, "").map((line) =>
|
|
62591
|
+
].join(" · "), width, "").map((line) => import_picocolors34.default.dim(line))
|
|
62406
62592
|
]
|
|
62407
62593
|
];
|
|
62408
62594
|
return lines.join(`
|
|
@@ -62436,7 +62622,7 @@ function createRowNamer() {
|
|
|
62436
62622
|
names.titles[key] = t;
|
|
62437
62623
|
};
|
|
62438
62624
|
for (const s of [...backlog.queued, ...backlog.open]) {
|
|
62439
|
-
if (!
|
|
62625
|
+
if (!existsSync28(s.path))
|
|
62440
62626
|
continue;
|
|
62441
62627
|
const key = `${s.harness}/${s.id}`;
|
|
62442
62628
|
const dir = dirs.resolve(s);
|
|
@@ -62473,7 +62659,7 @@ function createRowNamer() {
|
|
|
62473
62659
|
}
|
|
62474
62660
|
function defaultReadLog2() {
|
|
62475
62661
|
try {
|
|
62476
|
-
return
|
|
62662
|
+
return readFileSync27(logger.getLogPath(), "utf-8");
|
|
62477
62663
|
} catch {
|
|
62478
62664
|
return "";
|
|
62479
62665
|
}
|
|
@@ -62654,7 +62840,7 @@ ${CLEAR_BELOW}`);
|
|
|
62654
62840
|
input.on("data", onData);
|
|
62655
62841
|
});
|
|
62656
62842
|
}
|
|
62657
|
-
var
|
|
62843
|
+
var import_picocolors34, ESC7, HIDE_CURSOR3, SHOW_CURSOR3, CTRL_C4, KEY_UP4, KEY_DOWN4, KEY_RIGHT3, KEY_LEFT3, CURSOR_HOME, CLEAR_BELOW, CLEAR_EOL, ACTIVITY_VIEW_POLL_MS = 500, ACTIVITY_VIEW_LIST_LINES = 10, ACTIVITY_VIEW_FULL_LIST_ROWS = 5, ACTIVITY_VIEW_BUFFER_LINES = 200, ACTIVITY_VIEW_TABS, DEFAULT_PANE, TITLE_READS_PER_DRAW = 25;
|
|
62658
62844
|
var init_activity_view = __esm(() => {
|
|
62659
62845
|
init_follow();
|
|
62660
62846
|
init_logger();
|
|
@@ -62669,7 +62855,7 @@ var init_activity_view = __esm(() => {
|
|
|
62669
62855
|
init_alt_screen();
|
|
62670
62856
|
init_layout();
|
|
62671
62857
|
init_menu();
|
|
62672
|
-
|
|
62858
|
+
import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
62673
62859
|
ESC7 = String.fromCharCode(27);
|
|
62674
62860
|
HIDE_CURSOR3 = `${ESC7}[?25l`;
|
|
62675
62861
|
SHOW_CURSOR3 = `${ESC7}[?25h`;
|
|
@@ -63450,6 +63636,7 @@ async function runSetupFlow(opts = {}) {
|
|
|
63450
63636
|
}));
|
|
63451
63637
|
return;
|
|
63452
63638
|
}
|
|
63639
|
+
writeMcpRefreshCache({ version: VERSION });
|
|
63453
63640
|
const configuredProviders = configured.filter((result) => (result.action === "install" || result.action === "skip") && !result.error);
|
|
63454
63641
|
const mcpCompleted = configuredProviders.length > 0;
|
|
63455
63642
|
if (mcpCompleted) {
|
|
@@ -63894,25 +64081,14 @@ async function runSwitchTarget(scope = "org") {
|
|
|
63894
64081
|
return;
|
|
63895
64082
|
updateTarget(cfg, { api_key: apiKey });
|
|
63896
64083
|
saveConfig(cfg);
|
|
63897
|
-
const
|
|
63898
|
-
|
|
63899
|
-
|
|
63900
|
-
|
|
63901
|
-
|
|
63902
|
-
}
|
|
63903
|
-
});
|
|
63904
|
-
for (const provider of configured) {
|
|
63905
|
-
try {
|
|
63906
|
-
provider.install(cfg, true);
|
|
63907
|
-
logger.info("setup", `Switch: updated ${provider.name()}`);
|
|
63908
|
-
log2.success(`${provider.name()} ${dim("· updated")}`);
|
|
63909
|
-
} catch (err) {
|
|
63910
|
-
const error = err instanceof Error ? err : new Error(String(err));
|
|
63911
|
-
logger.error("setup", `Switch: update failed for ${provider.name()}: ${error.message}`);
|
|
63912
|
-
log2.error(`Failed to update ${provider.name()}: ${error.message}`);
|
|
63913
|
-
}
|
|
64084
|
+
const refreshed = refreshConfiguredProviders(cfg);
|
|
64085
|
+
for (const provider of refreshed.updated) {
|
|
64086
|
+
log2.success(`${provider.name()} ${dim("· updated")}`);
|
|
64087
|
+
}
|
|
64088
|
+
for (const { provider, error } of refreshed.failed) {
|
|
64089
|
+
log2.error(`Failed to update ${provider.name()}: ${error.message}`);
|
|
63914
64090
|
}
|
|
63915
|
-
if (
|
|
64091
|
+
if (refreshed.updated.length + refreshed.failed.length > 0) {
|
|
63916
64092
|
log2.info("Restart your AI agents so they pick up the new MCP target.");
|
|
63917
64093
|
}
|
|
63918
64094
|
}
|
|
@@ -64162,7 +64338,7 @@ async function stepSelectTools(detected) {
|
|
|
64162
64338
|
initialValues: preselected,
|
|
64163
64339
|
statusFor: (id, picked) => {
|
|
64164
64340
|
if (configuredMap.get(id))
|
|
64165
|
-
return picked ? dim("configured") :
|
|
64341
|
+
return picked ? dim("configured") : import_picocolors35.default.yellow("will remove");
|
|
64166
64342
|
return picked ? brand("will configure") : undefined;
|
|
64167
64343
|
},
|
|
64168
64344
|
summary: (picked) => {
|
|
@@ -64337,7 +64513,7 @@ ${dim(wrapLog("Run it inside a session to keep that session out of studying. Rem
|
|
|
64337
64513
|
log2.success("All agents already configured. No changes needed.");
|
|
64338
64514
|
}
|
|
64339
64515
|
}
|
|
64340
|
-
var
|
|
64516
|
+
var import_picocolors35, OAUTH_ANALYTICS_REASONS, SETUP_HANDSHAKE_TIMEOUT_MS = 1800000, LIBRARY_SELECT_CANCELLED;
|
|
64341
64517
|
var init_flow2 = __esm(() => {
|
|
64342
64518
|
init_dist();
|
|
64343
64519
|
init_errors3();
|
|
@@ -64348,6 +64524,7 @@ var init_flow2 = __esm(() => {
|
|
|
64348
64524
|
init_agents();
|
|
64349
64525
|
init_agents3();
|
|
64350
64526
|
init_providers();
|
|
64527
|
+
init_refresh();
|
|
64351
64528
|
init_agents4();
|
|
64352
64529
|
init_detach();
|
|
64353
64530
|
init_sync();
|
|
@@ -64355,12 +64532,13 @@ var init_flow2 = __esm(() => {
|
|
|
64355
64532
|
init_activity_view();
|
|
64356
64533
|
init_layout();
|
|
64357
64534
|
init_prompts();
|
|
64535
|
+
init_mcp_refresh_check();
|
|
64358
64536
|
init_agents_md_step();
|
|
64359
64537
|
init_analytics2();
|
|
64360
64538
|
init_github_step();
|
|
64361
64539
|
init_rules_step();
|
|
64362
64540
|
init_styles();
|
|
64363
|
-
|
|
64541
|
+
import_picocolors35 = __toESM(require_picocolors(), 1);
|
|
64364
64542
|
OAUTH_ANALYTICS_REASONS = new Set([
|
|
64365
64543
|
"access_denied",
|
|
64366
64544
|
"bad_oauth_state",
|
|
@@ -64488,7 +64666,7 @@ function renderAnalyticsFrame(state, tab, scroll, pageStats = null, pagesPending
|
|
|
64488
64666
|
const rows = analyticsTabRows(tab, state, pageStats);
|
|
64489
64667
|
const { visible, above, below } = windowReport(rows, scroll);
|
|
64490
64668
|
const empty = tab === "overview" ? "No analytics yet. They appear after the first study run." : tab === "projects" ? "No per-project history yet. It fills in as sessions are studied." : pagesPending ? "Loading page analytics..." : "No page analytics yet.";
|
|
64491
|
-
const listRows = visible.length > 0 ? visible.map((row) =>
|
|
64669
|
+
const listRows = visible.length > 0 ? visible.map((row) => import_picocolors36.default.dim(row)) : [import_picocolors36.default.dim(empty)];
|
|
64492
64670
|
const scrollParts = [];
|
|
64493
64671
|
if (above > 0)
|
|
64494
64672
|
scrollParts.push(`↑ ${above} earlier`);
|
|
@@ -64504,9 +64682,9 @@ function renderAnalyticsFrame(state, tab, scroll, pageStats = null, pagesPending
|
|
|
64504
64682
|
], tab, width, { spread: false }),
|
|
64505
64683
|
"",
|
|
64506
64684
|
...listRows,
|
|
64507
|
-
...scrollParts.length > 0 ? [
|
|
64685
|
+
...scrollParts.length > 0 ? [import_picocolors36.default.dim(scrollParts.join(" · "))] : [],
|
|
64508
64686
|
"",
|
|
64509
|
-
|
|
64687
|
+
import_picocolors36.default.dim("tab switch · ↑↓ scroll · esc back")
|
|
64510
64688
|
];
|
|
64511
64689
|
return lines.join(`
|
|
64512
64690
|
`);
|
|
@@ -64601,7 +64779,7 @@ ${CLEAR_BELOW2}`);
|
|
|
64601
64779
|
input.on("data", onData);
|
|
64602
64780
|
});
|
|
64603
64781
|
}
|
|
64604
|
-
var
|
|
64782
|
+
var import_picocolors36, ESC8, HIDE_CURSOR4, SHOW_CURSOR4, CTRL_C5, KEY_UP5, KEY_DOWN5, KEY_RIGHT4, KEY_LEFT4, CURSOR_HOME2, CLEAR_BELOW2, CLEAR_EOL2, ANALYTICS_VIEW_POLL_MS = 1000, ANALYTICS_VIEW_LINES = 14, ANALYTICS_VIEW_TABS, TOP_PAGES_LIMIT = 5, TOP_CITED_DAYS = 30, label = (text) => text.padEnd(26);
|
|
64605
64783
|
var init_analytics_view = __esm(() => {
|
|
64606
64784
|
init_trpc();
|
|
64607
64785
|
init_config();
|
|
@@ -64609,7 +64787,7 @@ var init_analytics_view = __esm(() => {
|
|
|
64609
64787
|
init_alt_screen();
|
|
64610
64788
|
init_layout();
|
|
64611
64789
|
init_menu();
|
|
64612
|
-
|
|
64790
|
+
import_picocolors36 = __toESM(require_picocolors(), 1);
|
|
64613
64791
|
ESC8 = String.fromCharCode(27);
|
|
64614
64792
|
HIDE_CURSOR4 = `${ESC8}[?25l`;
|
|
64615
64793
|
SHOW_CURSOR4 = `${ESC8}[?25h`;
|
|
@@ -64627,7 +64805,7 @@ var init_analytics_view = __esm(() => {
|
|
|
64627
64805
|
// src/tui/banner.ts
|
|
64628
64806
|
function paintLogoRow(row) {
|
|
64629
64807
|
return row.map(([tone, art]) => {
|
|
64630
|
-
if (!
|
|
64808
|
+
if (!import_picocolors37.default.isColorSupported)
|
|
64631
64809
|
return art;
|
|
64632
64810
|
const { fg, fallback } = LOGO_TONES[tone];
|
|
64633
64811
|
return hasTruecolor() ? `${fg}${art}\x1B[39m` : fallback(art);
|
|
@@ -64635,14 +64813,14 @@ function paintLogoRow(row) {
|
|
|
64635
64813
|
}
|
|
64636
64814
|
function checklistRows(ctx) {
|
|
64637
64815
|
const on = brand(CHECK2);
|
|
64638
|
-
const off =
|
|
64816
|
+
const off = import_picocolors37.default.dim(CIRCLE);
|
|
64639
64817
|
const rows = [["workspace", ctx.directory]];
|
|
64640
64818
|
rows.push([
|
|
64641
64819
|
"account",
|
|
64642
|
-
ctx.sessionExpired ? `${off} ${
|
|
64820
|
+
ctx.sessionExpired ? `${off} ${import_picocolors37.default.yellow("session expired")} ${import_picocolors37.default.dim(`${DOT3} run Log in`)}` : ctx.signedIn ? `${on} signed in` : `${off} ${import_picocolors37.default.dim(`not signed in ${DOT3} run Setup`)}`
|
|
64643
64821
|
]);
|
|
64644
64822
|
const missing = new Set(ctx.setupMissing ?? []);
|
|
64645
|
-
const warnRow = `${off} ${
|
|
64823
|
+
const warnRow = `${off} ${import_picocolors37.default.yellow("not configured")} ${import_picocolors37.default.dim(`${DOT3} run Setup`)}`;
|
|
64646
64824
|
if (missing.has("MCP"))
|
|
64647
64825
|
rows.push(["mcp", warnRow]);
|
|
64648
64826
|
else if (ctx.deploymentName)
|
|
@@ -64654,7 +64832,7 @@ function checklistRows(ctx) {
|
|
|
64654
64832
|
if (ctx.repoAgentsMd) {
|
|
64655
64833
|
rows.push([
|
|
64656
64834
|
"repo",
|
|
64657
|
-
ctx.repoAgentsMd === "current" ? `${on} AGENTS.md has the Dosu section` : `${off} ${
|
|
64835
|
+
ctx.repoAgentsMd === "current" ? `${on} AGENTS.md has the Dosu section` : `${off} ${import_picocolors37.default.yellow(ctx.repoAgentsMd === "outdated" ? "AGENTS.md Dosu section outdated" : "AGENTS.md missing the Dosu section")} ${import_picocolors37.default.dim(`${DOT3} run Setup`)}`
|
|
64658
64836
|
]);
|
|
64659
64837
|
}
|
|
64660
64838
|
if (missing.has("agents"))
|
|
@@ -64666,24 +64844,24 @@ function checklistRows(ctx) {
|
|
|
64666
64844
|
if (ctx.studying) {
|
|
64667
64845
|
rows.push([
|
|
64668
64846
|
"sync",
|
|
64669
|
-
`\uD83D\uDCDA ${brand("studying sessions...")} ${
|
|
64847
|
+
`\uD83D\uDCDA ${brand("studying sessions...")} ${import_picocolors37.default.dim(`${DOT3} see activity`)}`
|
|
64670
64848
|
]);
|
|
64671
64849
|
}
|
|
64672
64850
|
if (ctx.update) {
|
|
64673
64851
|
rows.push([
|
|
64674
64852
|
"update",
|
|
64675
|
-
`${
|
|
64853
|
+
`${import_picocolors37.default.yellow(`↑ ${ctx.update.version} available`)} ${import_picocolors37.default.dim(`${DOT3} ${ctx.update.hint}`)}`
|
|
64676
64854
|
]);
|
|
64677
64855
|
}
|
|
64678
64856
|
const labelWidth = Math.max(...rows.map(([label]) => label.length));
|
|
64679
|
-
return rows.map(([label, value]) => `${
|
|
64857
|
+
return rows.map(([label, value]) => `${import_picocolors37.default.dim(label.padEnd(labelWidth))} ${value}`);
|
|
64680
64858
|
}
|
|
64681
64859
|
function renderBanner(ctx) {
|
|
64682
64860
|
const logo = LOGO_ROWS.map(paintLogoRow);
|
|
64683
64861
|
const text = [
|
|
64684
64862
|
...checklistRows(ctx),
|
|
64685
64863
|
"",
|
|
64686
|
-
`${brandBadge("dosu-cli")} ${
|
|
64864
|
+
`${brandBadge("dosu-cli")} ${import_picocolors37.default.dim(`${ctx.version} ${DOT3} ${ctx.webAppHost}`)}`
|
|
64687
64865
|
];
|
|
64688
64866
|
const height = Math.max(logo.length, text.length);
|
|
64689
64867
|
const combined = [];
|
|
@@ -64696,10 +64874,10 @@ function renderBanner(ctx) {
|
|
|
64696
64874
|
return ["", ...combined, ""].join(`
|
|
64697
64875
|
`);
|
|
64698
64876
|
}
|
|
64699
|
-
var
|
|
64877
|
+
var import_picocolors37, CHECK2 = "✔", CIRCLE = "○", DOT3 = "·", LOGO_ROWS, LOGO_MARK, LOGO_WIDTH, LOGO_TONES, COLUMN_GAP = " ";
|
|
64700
64878
|
var init_banner = __esm(() => {
|
|
64701
64879
|
init_styles();
|
|
64702
|
-
|
|
64880
|
+
import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
64703
64881
|
LOGO_ROWS = [
|
|
64704
64882
|
[["sage", "▄▄▄▄▄▄"]],
|
|
64705
64883
|
[["sage", "██ ▀▄"]],
|
|
@@ -64710,8 +64888,8 @@ var init_banner = __esm(() => {
|
|
|
64710
64888
|
LOGO_MARK = LOGO_ROWS.map((row) => row.map(([, art]) => art).join(""));
|
|
64711
64889
|
LOGO_WIDTH = Math.max(...LOGO_MARK.map((row) => row.length));
|
|
64712
64890
|
LOGO_TONES = {
|
|
64713
|
-
sage: { fg: "\x1B[38;2;180;187;145m", fallback:
|
|
64714
|
-
moss: { fg: "\x1B[38;2;119;133;97m", fallback: (art) =>
|
|
64891
|
+
sage: { fg: "\x1B[38;2;180;187;145m", fallback: import_picocolors37.default.green },
|
|
64892
|
+
moss: { fg: "\x1B[38;2;119;133;97m", fallback: (art) => import_picocolors37.default.dim(import_picocolors37.default.green(art)) }
|
|
64715
64893
|
};
|
|
64716
64894
|
});
|
|
64717
64895
|
|
|
@@ -64823,16 +65001,16 @@ function renderPagesFrame(model, width, selected) {
|
|
|
64823
65001
|
const body = [];
|
|
64824
65002
|
let scrollHint = "";
|
|
64825
65003
|
if (model.phase === "loading") {
|
|
64826
|
-
body.push(
|
|
65004
|
+
body.push(import_picocolors38.default.dim("Loading pages…"));
|
|
64827
65005
|
} else if (model.phase === "error") {
|
|
64828
|
-
body.push(
|
|
65006
|
+
body.push(import_picocolors38.default.yellow(clip3(model.message, width)));
|
|
64829
65007
|
} else if (model.pages.length === 0) {
|
|
64830
|
-
body.push(
|
|
65008
|
+
body.push(import_picocolors38.default.dim("No pages in this Library yet."));
|
|
64831
65009
|
} else {
|
|
64832
65010
|
const rows = pageRows2(model.pages, width - 2);
|
|
64833
65011
|
const { start, above } = windowSelection(rows.length, selected);
|
|
64834
65012
|
const visible = rows.slice(start, start + PAGES_VIEW_LINES);
|
|
64835
|
-
body.push(...visible.map((row, i) => start + i === selected ? `${brand("▸")} ${
|
|
65013
|
+
body.push(...visible.map((row, i) => start + i === selected ? `${brand("▸")} ${import_picocolors38.default.bold(row)}` : ` ${import_picocolors38.default.dim(row)}`));
|
|
64836
65014
|
const below = Math.max(0, Math.max(model.total, rows.length) - start - PAGES_VIEW_LINES);
|
|
64837
65015
|
const parts = [];
|
|
64838
65016
|
if (above > 0)
|
|
@@ -64841,14 +65019,14 @@ function renderPagesFrame(model, width, selected) {
|
|
|
64841
65019
|
parts.push(`↓ ${below} more`);
|
|
64842
65020
|
scrollHint = parts.join(" · ");
|
|
64843
65021
|
}
|
|
64844
|
-
const count = model.phase === "ready" ? ` ${
|
|
65022
|
+
const count = model.phase === "ready" ? ` ${import_picocolors38.default.dim(model.pages.length < model.total ? `(${model.pages.length} of ${model.total})` : `(${model.pages.length})`)}` : "";
|
|
64845
65023
|
const lines = [
|
|
64846
65024
|
`${breadcrumb(["home", "pages"], width)}${count}`,
|
|
64847
65025
|
"",
|
|
64848
65026
|
...body,
|
|
64849
|
-
...scrollHint ? [
|
|
65027
|
+
...scrollHint ? [import_picocolors38.default.dim(scrollHint)] : [],
|
|
64850
65028
|
"",
|
|
64851
|
-
|
|
65029
|
+
import_picocolors38.default.dim("↑↓ move · enter open · esc back")
|
|
64852
65030
|
];
|
|
64853
65031
|
return lines.join(`
|
|
64854
65032
|
`);
|
|
@@ -64857,9 +65035,9 @@ function renderPageFrame(page, content, width, scroll) {
|
|
|
64857
65035
|
const body = [];
|
|
64858
65036
|
let scrollHint = "";
|
|
64859
65037
|
if (content.phase === "loading") {
|
|
64860
|
-
body.push(
|
|
65038
|
+
body.push(import_picocolors38.default.dim("Loading page…"));
|
|
64861
65039
|
} else if (content.phase === "error") {
|
|
64862
|
-
body.push(
|
|
65040
|
+
body.push(import_picocolors38.default.yellow(clip3(content.message, width)));
|
|
64863
65041
|
} else {
|
|
64864
65042
|
const rows = wrapBody(content.body, width);
|
|
64865
65043
|
const { visible, above, below } = windowReport(rows, scroll, PAGE_BODY_LINES);
|
|
@@ -64874,12 +65052,12 @@ function renderPageFrame(page, content, width, scroll) {
|
|
|
64874
65052
|
const meta = `${page.type} · ${page.published ? "published" : "draft"} · updated ${page.updated_at.slice(0, 10)}`;
|
|
64875
65053
|
const lines = [
|
|
64876
65054
|
breadcrumb(["home", "pages", page.title], width),
|
|
64877
|
-
|
|
65055
|
+
import_picocolors38.default.dim(clip3(meta, width)),
|
|
64878
65056
|
"",
|
|
64879
65057
|
...body,
|
|
64880
|
-
...scrollHint ? [
|
|
65058
|
+
...scrollHint ? [import_picocolors38.default.dim(scrollHint)] : [],
|
|
64881
65059
|
"",
|
|
64882
|
-
|
|
65060
|
+
import_picocolors38.default.dim("↑↓ scroll · esc back to pages")
|
|
64883
65061
|
];
|
|
64884
65062
|
return lines.join(`
|
|
64885
65063
|
`);
|
|
@@ -65028,7 +65206,7 @@ ${CLEAR_BELOW3}`);
|
|
|
65028
65206
|
input.on("data", onData);
|
|
65029
65207
|
});
|
|
65030
65208
|
}
|
|
65031
|
-
var
|
|
65209
|
+
var import_picocolors38, ESC9, HIDE_CURSOR5, SHOW_CURSOR5, CTRL_C6, KEY_UP6, KEY_DOWN6, CURSOR_HOME3, CLEAR_BELOW3, CLEAR_EOL3, PAGES_VIEW_LINES = 12, PAGE_BODY_LINES = 14, PAGES_FETCH_BATCH = 100;
|
|
65032
65210
|
var init_pages_view = __esm(() => {
|
|
65033
65211
|
init_trpc();
|
|
65034
65212
|
init_config();
|
|
@@ -65038,7 +65216,7 @@ var init_pages_view = __esm(() => {
|
|
|
65038
65216
|
init_analytics_view();
|
|
65039
65217
|
init_layout();
|
|
65040
65218
|
init_menu();
|
|
65041
|
-
|
|
65219
|
+
import_picocolors38 = __toESM(require_picocolors(), 1);
|
|
65042
65220
|
ESC9 = String.fromCharCode(27);
|
|
65043
65221
|
HIDE_CURSOR5 = `${ESC9}[?25l`;
|
|
65044
65222
|
SHOW_CURSOR5 = `${ESC9}[?25h`;
|
|
@@ -65152,7 +65330,7 @@ function isSetUp(cfg) {
|
|
|
65152
65330
|
}
|
|
65153
65331
|
function setupHint(cfg) {
|
|
65154
65332
|
const started = Boolean(cfg.active_account?.target);
|
|
65155
|
-
return
|
|
65333
|
+
return import_picocolors39.default.yellow(started ? `incomplete · missing ${missingSetupSteps(cfg).join(" + ")}` : "not set up yet");
|
|
65156
65334
|
}
|
|
65157
65335
|
function isStudying() {
|
|
65158
65336
|
try {
|
|
@@ -65398,7 +65576,7 @@ function handleLogout(cfg) {
|
|
|
65398
65576
|
saveConfig(cfg);
|
|
65399
65577
|
log2.success("Credentials cleared.");
|
|
65400
65578
|
}
|
|
65401
|
-
var
|
|
65579
|
+
var import_picocolors39, ESC10, CLEAR_SCREEN;
|
|
65402
65580
|
var init_tui = __esm(() => {
|
|
65403
65581
|
init_client();
|
|
65404
65582
|
init_config();
|
|
@@ -65421,7 +65599,7 @@ var init_tui = __esm(() => {
|
|
|
65421
65599
|
init_menu();
|
|
65422
65600
|
init_pages_view();
|
|
65423
65601
|
init_prompts();
|
|
65424
|
-
|
|
65602
|
+
import_picocolors39 = __toESM(require_picocolors(), 1);
|
|
65425
65603
|
ESC10 = String.fromCharCode(27);
|
|
65426
65604
|
CLEAR_SCREEN = `${ESC10}[2J${ESC10}[H`;
|
|
65427
65605
|
});
|
|
@@ -66025,18 +66203,15 @@ var init_flow3 = __esm(() => {
|
|
|
66025
66203
|
});
|
|
66026
66204
|
|
|
66027
66205
|
// src/cli/cli.ts
|
|
66028
|
-
import {
|
|
66029
|
-
closeSync as closeSync6,
|
|
66030
|
-
constants as constants3,
|
|
66031
|
-
fstatSync as fstatSync2,
|
|
66032
|
-
openSync as openSync6,
|
|
66033
|
-
readFileSync as readFileSync27,
|
|
66034
|
-
readSync as readSync5,
|
|
66035
|
-
unlinkSync as unlinkSync6
|
|
66036
|
-
} from "node:fs";
|
|
66206
|
+
import { readFileSync as readFileSync28, unlinkSync as unlinkSync6 } from "node:fs";
|
|
66037
66207
|
function shouldRunBackgroundChecks(actionName) {
|
|
66038
66208
|
return actionName !== "upgrade";
|
|
66039
66209
|
}
|
|
66210
|
+
function shouldRunMcpRefreshCheck(actionCommand) {
|
|
66211
|
+
if (actionCommand.name() === "setup")
|
|
66212
|
+
return false;
|
|
66213
|
+
return !(actionCommand.name() === "refresh" && actionCommand.parent?.name() === "mcp");
|
|
66214
|
+
}
|
|
66040
66215
|
function commandTelemetryName(actionCommand) {
|
|
66041
66216
|
const segments = [];
|
|
66042
66217
|
let current = actionCommand;
|
|
@@ -66053,7 +66228,7 @@ function shouldTrackCommand(command) {
|
|
|
66053
66228
|
}
|
|
66054
66229
|
function commandTelemetryContext() {
|
|
66055
66230
|
try {
|
|
66056
|
-
const cfg =
|
|
66231
|
+
const cfg = loadConfigNonBlocking();
|
|
66057
66232
|
if (!cfg)
|
|
66058
66233
|
return { mode: "cloud", isAuthenticated: false };
|
|
66059
66234
|
const authenticated = isAuthenticated(cfg);
|
|
@@ -66073,29 +66248,6 @@ function commandTelemetryContext() {
|
|
|
66073
66248
|
return { mode: "cloud", isAuthenticated: false };
|
|
66074
66249
|
}
|
|
66075
66250
|
}
|
|
66076
|
-
function loadConfigForTelemetry() {
|
|
66077
|
-
let fd;
|
|
66078
|
-
try {
|
|
66079
|
-
const nonblocking = typeof constants3.O_NONBLOCK === "number" ? constants3.O_NONBLOCK : 0;
|
|
66080
|
-
fd = openSync6(getConfigPath(), constants3.O_RDONLY | nonblocking);
|
|
66081
|
-
const file = fstatSync2(fd);
|
|
66082
|
-
if (!file.isFile() || file.size > MAX_TELEMETRY_CONFIG_BYTES)
|
|
66083
|
-
return;
|
|
66084
|
-
const content = Buffer.alloc(MAX_TELEMETRY_CONFIG_BYTES + 1);
|
|
66085
|
-
const bytesRead = readSync5(fd, content, 0, content.byteLength, 0);
|
|
66086
|
-
if (bytesRead > MAX_TELEMETRY_CONFIG_BYTES)
|
|
66087
|
-
return;
|
|
66088
|
-
return parseConfig(JSON.parse(content.subarray(0, bytesRead).toString("utf8")));
|
|
66089
|
-
} catch {
|
|
66090
|
-
return;
|
|
66091
|
-
} finally {
|
|
66092
|
-
if (fd !== undefined) {
|
|
66093
|
-
try {
|
|
66094
|
-
closeSync6(fd);
|
|
66095
|
-
} catch {}
|
|
66096
|
-
}
|
|
66097
|
-
}
|
|
66098
|
-
}
|
|
66099
66251
|
function startTelemetry(telemetry, command, context) {
|
|
66100
66252
|
if (!telemetry)
|
|
66101
66253
|
return false;
|
|
@@ -66154,12 +66306,15 @@ function createProgram(options = {}) {
|
|
|
66154
66306
|
const opts = thisCommand.optsWithGlobals();
|
|
66155
66307
|
logger.init({ debug: opts.debug });
|
|
66156
66308
|
if (shouldRunBackgroundChecks(actionCommand.name())) {
|
|
66309
|
+
const launchesTUI = actionCommand.parent === null;
|
|
66157
66310
|
if (!process.env.CI) {
|
|
66158
|
-
const launchesTUI = actionCommand.parent === null;
|
|
66159
66311
|
await checkForUpdates({ notify: !launchesTUI });
|
|
66160
66312
|
}
|
|
66161
66313
|
checkForSkillUpdates();
|
|
66162
66314
|
checkForReadyTasks();
|
|
66315
|
+
if (shouldRunMcpRefreshCheck(actionCommand)) {
|
|
66316
|
+
checkForMcpRefresh({ notify: !launchesTUI });
|
|
66317
|
+
}
|
|
66163
66318
|
}
|
|
66164
66319
|
const command = commandTelemetryName(actionCommand);
|
|
66165
66320
|
if (options.telemetry && shouldTrackCommand(command)) {
|
|
@@ -66386,6 +66541,31 @@ Start ${provider.name()} in any project to use the Dosu MCP.`);
|
|
|
66386
66541
|
Start ${provider.name()} in this project directory to use the Dosu MCP.`);
|
|
66387
66542
|
}
|
|
66388
66543
|
});
|
|
66544
|
+
mcp.command("refresh").description("Rewrite the Dosu MCP entry in every configured AI tool from the current setup").action(() => {
|
|
66545
|
+
const cfg = loadConfig();
|
|
66546
|
+
if (!canRefreshMcp(cfg)) {
|
|
66547
|
+
throw new CliUsageError("Dosu is not set up yet. Run 'dosu setup' first");
|
|
66548
|
+
}
|
|
66549
|
+
const configured = configuredProviders();
|
|
66550
|
+
if (configured.length === 0) {
|
|
66551
|
+
console.log("No AI tools with Dosu configured. Run 'dosu setup' to add Dosu to a tool.");
|
|
66552
|
+
return;
|
|
66553
|
+
}
|
|
66554
|
+
console.log(`Refreshing Dosu MCP config for configured AI tools...
|
|
66555
|
+
`);
|
|
66556
|
+
const result = refreshConfiguredProviders(cfg);
|
|
66557
|
+
writeMcpRefreshCache({ version: VERSION });
|
|
66558
|
+
for (const provider of result.updated) {
|
|
66559
|
+
console.log(` ✓ ${provider.name()}`);
|
|
66560
|
+
}
|
|
66561
|
+
for (const { provider, error } of result.failed) {
|
|
66562
|
+
console.log(` ✗ ${provider.name()}: ${error.message}`);
|
|
66563
|
+
}
|
|
66564
|
+
console.log(`
|
|
66565
|
+
Restart your AI agents so they pick up the change.`);
|
|
66566
|
+
if (result.failed.length > 0)
|
|
66567
|
+
process.exitCode = 1;
|
|
66568
|
+
});
|
|
66389
66569
|
mcp.command("list").description("List available AI tools").action(() => {
|
|
66390
66570
|
console.log(`Available AI tools:
|
|
66391
66571
|
`);
|
|
@@ -66466,7 +66646,7 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
|
|
|
66466
66646
|
}
|
|
66467
66647
|
if (opts.follow) {
|
|
66468
66648
|
try {
|
|
66469
|
-
const lines =
|
|
66649
|
+
const lines = readFileSync28(logPath, "utf-8").split(`
|
|
66470
66650
|
`);
|
|
66471
66651
|
if (lines.at(-1) === "")
|
|
66472
66652
|
lines.pop();
|
|
@@ -66482,7 +66662,7 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
|
|
|
66482
66662
|
if (opts.tail !== undefined) {
|
|
66483
66663
|
const n = typeof opts.tail === "string" ? parseInt(opts.tail, 10) || 50 : 50;
|
|
66484
66664
|
try {
|
|
66485
|
-
const content =
|
|
66665
|
+
const content = readFileSync28(logPath, "utf-8");
|
|
66486
66666
|
const lines = content.split(`
|
|
66487
66667
|
`);
|
|
66488
66668
|
console.log(lines.slice(-n).join(`
|
|
@@ -66534,7 +66714,7 @@ function processCommandTelemetry() {
|
|
|
66534
66714
|
return;
|
|
66535
66715
|
}
|
|
66536
66716
|
}
|
|
66537
|
-
var TELEMETRY_FLUSH_TIMEOUT_MS = 750,
|
|
66717
|
+
var TELEMETRY_FLUSH_TIMEOUT_MS = 750, CliUsageError, FOLLOW_POLL_MS = 500, DEFAULT_TAIL_LINES = 50;
|
|
66538
66718
|
var init_cli = __esm(() => {
|
|
66539
66719
|
init_commander();
|
|
66540
66720
|
init_client();
|
|
@@ -66560,13 +66740,14 @@ var init_cli = __esm(() => {
|
|
|
66560
66740
|
init_follow();
|
|
66561
66741
|
init_logger();
|
|
66562
66742
|
init_providers();
|
|
66743
|
+
init_refresh();
|
|
66563
66744
|
init_styles();
|
|
66564
66745
|
init_settings();
|
|
66565
66746
|
init_telemetry();
|
|
66747
|
+
init_mcp_refresh_check();
|
|
66566
66748
|
init_pending_tasks_check();
|
|
66567
66749
|
init_skill_update_check();
|
|
66568
66750
|
init_update_check();
|
|
66569
|
-
MAX_TELEMETRY_CONFIG_BYTES = 64 * 1024;
|
|
66570
66751
|
CliUsageError = class CliUsageError extends Error {
|
|
66571
66752
|
exitCode = 1;
|
|
66572
66753
|
constructor(message) {
|
|
@@ -66607,4 +66788,4 @@ main().catch((err) => {
|
|
|
66607
66788
|
process.exit(1);
|
|
66608
66789
|
});
|
|
66609
66790
|
|
|
66610
|
-
//# debugId=
|
|
66791
|
+
//# debugId=6712b11a-8117-30cb-6475-6e2164756e21
|