@dosu/cli 0.20.1 → 0.20.3

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.
Files changed (3) hide show
  1. package/README.md +123 -19
  2. package/bin/dosu.js +73 -126
  3. package/package.json +12 -14
package/README.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # dosu-cli
2
2
 
3
+ > Connect [Dosu](https://dosu.dev) to your AI coding tools. `dosu` authenticates you, picks a Dosu deployment, and wires the Dosu MCP server into Claude Code, Cursor, Codex, and more — plus commands to drive the Dosu platform from your terminal.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@dosu/cli.svg)](https://www.npmjs.com/package/@dosu/cli)
6
+ [![CI](https://github.com/dosu-ai/dosu-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/dosu-ai/dosu-cli/actions/workflows/ci.yml)
7
+ [![codecov](https://codecov.io/gh/dosu-ai/dosu-cli/branch/main/graph/badge.svg)](https://codecov.io/gh/dosu-ai/dosu-cli)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](#license)
9
+
10
+ ## Quick Start
11
+
12
+ ```bash
13
+ npx @dosu/cli setup
14
+ ```
15
+
16
+ The interactive wizard authenticates you via browser OAuth, lets you pick a Dosu deployment (or OSS / public-library mode), mints an API key, detects which AI tools you have installed, and writes the Dosu MCP server entry into each one's config. Restart your AI tool and Dosu is available.
17
+
18
+ Run `dosu` with no arguments any time to open the interactive menu.
19
+
3
20
  ## Installation
4
21
 
5
22
  ### npx / npm (Recommended)
@@ -65,30 +82,117 @@ Or right-click the binary, select "Open", and click "Open" in the dialog.
65
82
 
66
83
  **Note:** Installing via Homebrew avoids this issue automatically.
67
84
 
68
- ## Releasing (for maintainers)
85
+ ## Usage
86
+
87
+ ### Core commands
88
+
89
+ | Command | Description |
90
+ |---|---|
91
+ | `dosu` | Launch the interactive TUI menu |
92
+ | `dosu setup` | Run the setup wizard (auth → deployment → detect tools → configure) |
93
+ | `dosu login` | Authenticate with Dosu via browser OAuth |
94
+ | `dosu logout` | Clear saved credentials |
95
+ | `dosu status` | Show current authentication and MCP status |
96
+ | `dosu mcp list` | List supported AI tools |
97
+ | `dosu mcp add <tool>` | Add the Dosu MCP server to a specific tool |
98
+ | `dosu logs` | View or manage debug logs (`--tail`, `--clear`) |
99
+
100
+ `dosu mcp add` takes `-g, --global` to install for all projects instead of project-local, and `--show-secret` to print the full manual config.
101
+
102
+ ### Platform commands
103
+
104
+ Once authenticated against a deployment, you can drive the Dosu platform without leaving the terminal:
105
+
106
+ | Command | Description |
107
+ |---|---|
108
+ | `dosu ask` | Ask a question and get an AI-generated answer |
109
+ | `dosu knowledge` | Search and browse your knowledge base |
110
+ | `dosu docs` | Manage documents (list, create, update, import, publish, AI-generate) |
111
+ | `dosu suggest` | Review and manage AI document suggestions |
112
+ | `dosu threads` | List and manage conversation threads |
113
+ | `dosu review` | Document review workflow |
114
+ | `dosu sources` | Manage connected data sources (list, sync, update) |
115
+ | `dosu integrations` | List and inspect platform integrations (Slack, GitHub, …) |
116
+ | `dosu tags` | List knowledge base tags and tagged pages |
117
+ | `dosu members` | Manage team members and access requests |
118
+ | `dosu org` | Show organization information |
119
+ | `dosu deployments` | List / show / switch deployments |
120
+ | `dosu analytics` | View usage statistics |
121
+ | `dosu insights` | Open a visual report of your Dosu space activity |
122
+ | `dosu skill` | Install / update / remove the Dosu agent skill |
123
+ | `dosu hooks` | Install / remove / diagnose Dosu coding-agent hooks |
124
+
125
+ Run `dosu <command> --help` for subcommands and flags.
126
+
127
+ ### Supported AI tools
128
+
129
+ `dosu mcp add <id>` and the setup wizard support:
130
+
131
+ | ID | Tool |
132
+ |---|---|
133
+ | `claude` | Claude Code |
134
+ | `claude-desktop` | Claude Desktop |
135
+ | `cursor` | Cursor |
136
+ | `vscode` | VS Code |
137
+ | `codex` | Codex CLI |
138
+ | `gemini` | Gemini CLI |
139
+ | `windsurf` | Windsurf |
140
+ | `zed` | Zed |
141
+ | `cline` | Cline |
142
+ | `cline-cli` | Cline CLI |
143
+ | `copilot` | GitHub Copilot CLI |
144
+ | `opencode` | OpenCode |
145
+ | `antigravity` | Antigravity |
146
+ | `mcporter` | MCPorter |
147
+ | `factory` | Factory |
148
+ | `manual` | Manual Configuration (prints config to paste yourself) |
149
+
150
+ ### Non-interactive / agent setup
151
+
152
+ For coding agents and CI, `setup` has a non-interactive mode:
69
153
 
70
- Releases are automated via `bun build --compile` and GitHub Actions.
154
+ ```bash
155
+ dosu setup --agent --tool claude
156
+ ```
71
157
 
72
- ### Creating a Release
158
+ Combine with `dosu login --request` / `--check <ticket>` for human-in-the-loop authentication, and `--mode oss|cloud` to skip the mode prompt.
159
+
160
+ ## Configuration
161
+
162
+ Credentials and the selected deployment live in `~/.config/dosu-cli/config.json`. Set `DOSU_DEV=true` to isolate config under `~/.config/dosu-cli-dev/`.
163
+
164
+ To repoint a published build at a different backend without rebuilding, set any of these runtime overrides:
165
+
166
+ - `DOSU_WEB_APP_URL_OVERRIDE`
167
+ - `DOSU_BACKEND_URL_OVERRIDE`
168
+ - `SUPABASE_URL_OVERRIDE`
169
+ - `SUPABASE_ANON_KEY_OVERRIDE`
170
+
171
+ ## Development
172
+
173
+ ```bash
174
+ bun install # install dependencies
175
+ bun run dev # run the CLI from source
176
+ bun run test # run tests (vitest)
177
+ bun run check # lint + format check (Biome)
178
+ bun run typecheck # tsc --noEmit
179
+ ```
180
+
181
+ See [AGENTS.md](AGENTS.md) for architecture and contributor notes.
182
+
183
+ ## Releasing (for maintainers)
73
184
 
74
- 1. **Ensure all changes are committed and pushed to `main`**
185
+ Releases are fully automated with [semantic-release](https://github.com/semantic-release/semantic-release) there are no manual version tags. Every push to a release branch is analyzed for [Conventional Commit](https://www.conventionalcommits.org/) messages, which determine the version bump.
75
186
 
76
- 2. **Create and push a new tag:**
77
- ```bash
78
- git tag v0.2.0
79
- git push origin v0.2.0
80
- ```
187
+ | Branch | npm dist-tag | Version shape |
188
+ |---|---|---|
189
+ | `main` | `latest` | `0.20.1` |
190
+ | `alpha` | `alpha` | `0.20.1-alpha.1` |
81
191
 
82
- 3. **GitHub Actions will automatically:**
83
- - Run tests
84
- - Build binaries for all platforms (macOS, Linux, Windows)
85
- - Create a GitHub release with the binaries
86
- - Publish to npm (`@dosu/cli`)
87
- - Update the Homebrew formula
192
+ On a qualifying push, the CI pipeline bumps the version, builds binaries for all platforms, creates a GitHub release with the archives, publishes to npm, and (for stable releases only) updates the Homebrew formula.
88
193
 
89
- ### Version Naming
194
+ Commit messages that don't follow Conventional Commits are invisible to semantic-release and won't trigger a release. See [AGENTS.md](AGENTS.md) for the full type → release-impact table and the alpha channel workflow.
90
195
 
91
- - Production releases: `v1.0.0`, `v1.1.0`, `v2.0.0`
92
- - Pre-releases: `v0.1.0-alpha`, `v0.1.0-beta`, `v0.1.0-rc1`
196
+ ## License
93
197
 
94
- Pre-release tags (containing `-alpha`, `-beta`, `-rc`) are automatically marked as pre-releases on GitHub and published to npm under the `next` dist-tag.
198
+ MIT see the `license` field in [package.json](package.json).
package/bin/dosu.js CHANGED
@@ -2733,12 +2733,15 @@ var init_splitLink_B7Cuf2c_ = __esm(() => {
2733
2733
  init_observable();
2734
2734
  });
2735
2735
 
2736
- // node_modules/@trpc/server/dist/utils-CLZnJdb_.mjs
2736
+ // node_modules/@trpc/server/dist/codes-DagpWZLc.mjs
2737
2737
  function isObject(value) {
2738
2738
  return !!value && !Array.isArray(value) && typeof value === "object";
2739
2739
  }
2740
+ function emptyObject() {
2741
+ return Object.create(null);
2742
+ }
2740
2743
  var TRPC_ERROR_CODES_BY_KEY, retryableRpcCodes;
2741
- var init_utils_CLZnJdb_ = __esm(() => {
2744
+ var init_codes_DagpWZLc = __esm(() => {
2742
2745
  TRPC_ERROR_CODES_BY_KEY = {
2743
2746
  PARSE_ERROR: -32700,
2744
2747
  BAD_REQUEST: -32600,
@@ -2770,7 +2773,7 @@ var init_utils_CLZnJdb_ = __esm(() => {
2770
2773
  ];
2771
2774
  });
2772
2775
 
2773
- // node_modules/@trpc/server/dist/getErrorShape-BH60iMC2.mjs
2776
+ // node_modules/@trpc/server/dist/getErrorShape-BPSzUA7W.mjs
2774
2777
  function createInnerProxy(callback, path, memo) {
2775
2778
  var _memo$cacheKey;
2776
2779
  const cacheKey = path.join(".");
@@ -2782,6 +2785,10 @@ function createInnerProxy(callback, path, memo) {
2782
2785
  },
2783
2786
  apply(_1, _2, args) {
2784
2787
  const lastOfPath = path[path.length - 1];
2788
+ if (lastOfPath === "valueOf" || lastOfPath === "toString" || lastOfPath === "toJSON") {
2789
+ const debugPath = path.slice(0, -1).join(".");
2790
+ return `tRPC.proxy(${debugPath})`;
2791
+ }
2785
2792
  let opts = {
2786
2793
  args,
2787
2794
  path
@@ -2822,14 +2829,15 @@ var __create3, __defProp3, __getOwnPropDesc2, __getOwnPropNames3, __getProtoOf3,
2822
2829
  }) : target, mod)), noop = () => {}, freezeIfAvailable = (obj) => {
2823
2830
  if (Object.freeze)
2824
2831
  Object.freeze(obj);
2825
- }, createRecursiveProxy = (callback) => createInnerProxy(callback, [], Object.create(null)), createFlatProxy = (callback) => {
2832
+ }, createRecursiveProxy = (callback) => createInnerProxy(callback, [], emptyObject()), createFlatProxy = (callback) => {
2826
2833
  return new Proxy(noop, { get(_obj, name) {
2827
2834
  if (name === "then")
2828
2835
  return;
2829
2836
  return callback(name);
2830
2837
  } });
2831
2838
  }, require_typeof2, require_toPrimitive2, require_toPropertyKey2, require_defineProperty2, require_objectSpread22, import_objectSpread2;
2832
- var init_getErrorShape_BH60iMC2 = __esm(() => {
2839
+ var init_getErrorShape_BPSzUA7W = __esm(() => {
2840
+ init_codes_DagpWZLc();
2833
2841
  __create3 = Object.create;
2834
2842
  __defProp3 = Object.defineProperty;
2835
2843
  __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
@@ -2912,7 +2920,7 @@ var init_getErrorShape_BH60iMC2 = __esm(() => {
2912
2920
  import_objectSpread2 = __toESM3(require_objectSpread22(), 1);
2913
2921
  });
2914
2922
 
2915
- // node_modules/@trpc/server/dist/tracked-DBSMdVzR.mjs
2923
+ // node_modules/@trpc/server/dist/tracked-DWInO6EQ.mjs
2916
2924
  function transformResultInner(response, transformer) {
2917
2925
  if ("error" in response) {
2918
2926
  const error = transformer.deserialize(response.error);
@@ -2944,9 +2952,9 @@ function transformResult(response, transformer) {
2944
2952
  return result;
2945
2953
  }
2946
2954
  var import_defineProperty, import_objectSpread2$1, TransformResultError, import_objectSpread22, trackedSymbol;
2947
- var init_tracked_DBSMdVzR = __esm(() => {
2948
- init_getErrorShape_BH60iMC2();
2949
- init_utils_CLZnJdb_();
2955
+ var init_tracked_DWInO6EQ = __esm(() => {
2956
+ init_getErrorShape_BPSzUA7W();
2957
+ init_codes_DagpWZLc();
2950
2958
  import_defineProperty = __toESM3(require_defineProperty2(), 1);
2951
2959
  import_objectSpread2$1 = __toESM3(require_objectSpread22(), 1);
2952
2960
  TransformResultError = class extends Error {
@@ -2960,12 +2968,12 @@ var init_tracked_DBSMdVzR = __esm(() => {
2960
2968
 
2961
2969
  // node_modules/@trpc/server/dist/unstable-core-do-not-import.mjs
2962
2970
  var init_unstable_core_do_not_import = __esm(() => {
2963
- init_getErrorShape_BH60iMC2();
2964
- init_tracked_DBSMdVzR();
2965
- init_utils_CLZnJdb_();
2971
+ init_getErrorShape_BPSzUA7W();
2972
+ init_codes_DagpWZLc();
2973
+ init_tracked_DWInO6EQ();
2966
2974
  });
2967
2975
 
2968
- // node_modules/@trpc/client/dist/TRPCClientError-CjKyS10w.mjs
2976
+ // node_modules/@trpc/client/dist/TRPCClientError-apv8gw59.mjs
2969
2977
  function isTRPCClientError(cause) {
2970
2978
  return cause instanceof TRPCClientError;
2971
2979
  }
@@ -2980,7 +2988,7 @@ function getMessageFromUnknownError(err, fallback) {
2980
2988
  return fallback;
2981
2989
  }
2982
2990
  var import_defineProperty2, import_objectSpread23, TRPCClientError;
2983
- var init_TRPCClientError_CjKyS10w = __esm(() => {
2991
+ var init_TRPCClientError_apv8gw59 = __esm(() => {
2984
2992
  init_objectSpread2_BvkFp__Y();
2985
2993
  init_unstable_core_do_not_import();
2986
2994
  import_defineProperty2 = __toESM2(require_defineProperty(), 1);
@@ -3009,7 +3017,10 @@ var init_TRPCClientError_CjKyS10w = __esm(() => {
3009
3017
  return cause;
3010
3018
  }
3011
3019
  if (isTRPCErrorResponse(cause))
3012
- return new TRPCClientError2(cause.error.message, (0, import_objectSpread23.default)((0, import_objectSpread23.default)({}, opts), {}, { result: cause }));
3020
+ return new TRPCClientError2(cause.error.message, (0, import_objectSpread23.default)((0, import_objectSpread23.default)({}, opts), {}, {
3021
+ result: cause,
3022
+ cause: opts.cause
3023
+ }));
3013
3024
  return new TRPCClientError2(getMessageFromUnknownError(cause, "Unknown error"), (0, import_objectSpread23.default)((0, import_objectSpread23.default)({}, opts), {}, { cause }));
3014
3025
  }
3015
3026
  };
@@ -3038,7 +3049,7 @@ function getTransformer(transformer) {
3038
3049
  }
3039
3050
  var init_unstable_internals_Bg7n9BBj = () => {};
3040
3051
 
3041
- // node_modules/@trpc/client/dist/httpUtils-Dv57hbOd.mjs
3052
+ // node_modules/@trpc/client/dist/httpUtils-pyf5RF99.mjs
3042
3053
  function getFetch(customFetchImpl) {
3043
3054
  if (customFetchImpl)
3044
3055
  return customFetchImpl;
@@ -3068,7 +3079,7 @@ function getInput(opts) {
3068
3079
  return "input" in opts ? opts.transformer.input.serialize(opts.input) : arrayToDict(opts.inputs.map((_input) => opts.transformer.input.serialize(_input)));
3069
3080
  }
3070
3081
  async function fetchHTTPResponse(opts) {
3071
- var _opts$methodOverride;
3082
+ var _opts$methodOverride, _opts$trpcAcceptHeade;
3072
3083
  throwIfAborted(opts.signal);
3073
3084
  const url = opts.getUrl(opts);
3074
3085
  const body = opts.getBody(opts);
@@ -3079,7 +3090,7 @@ async function fetchHTTPResponse(opts) {
3079
3090
  return Object.fromEntries(heads);
3080
3091
  return heads;
3081
3092
  })();
3082
- const headers = (0, import_objectSpread24.default)((0, import_objectSpread24.default)((0, import_objectSpread24.default)({}, opts.contentTypeHeader && method !== "GET" ? { "content-type": opts.contentTypeHeader } : {}), opts.trpcAcceptHeader ? { "trpc-accept": opts.trpcAcceptHeader } : undefined), resolvedHeaders);
3093
+ const headers = (0, import_objectSpread24.default)((0, import_objectSpread24.default)((0, import_objectSpread24.default)({}, opts.contentTypeHeader && method !== "GET" ? { "content-type": opts.contentTypeHeader } : {}), opts.trpcAcceptHeader ? { [(_opts$trpcAcceptHeade = opts.trpcAcceptHeaderKey) !== null && _opts$trpcAcceptHeade !== undefined ? _opts$trpcAcceptHeade : "trpc-accept"]: opts.trpcAcceptHeader } : undefined), resolvedHeaders);
3083
3094
  return getFetch(opts.fetch)(url, {
3084
3095
  method,
3085
3096
  signal: opts.signal,
@@ -3135,7 +3146,7 @@ var isFunction2 = (fn) => typeof fn === "function", import_objectSpread24, METHO
3135
3146
  throw new DOMException("AbortError", "AbortError");
3136
3147
  throw new AbortError;
3137
3148
  };
3138
- var init_httpUtils_Dv57hbOd = __esm(() => {
3149
+ var init_httpUtils_pyf5RF99 = __esm(() => {
3139
3150
  init_objectSpread2_BvkFp__Y();
3140
3151
  init_unstable_internals_Bg7n9BBj();
3141
3152
  import_objectSpread24 = __toESM2(require_objectSpread2(), 1);
@@ -3154,7 +3165,7 @@ var init_httpUtils_Dv57hbOd = __esm(() => {
3154
3165
  };
3155
3166
  });
3156
3167
 
3157
- // node_modules/@trpc/client/dist/httpLink-DCFpUmZF.mjs
3168
+ // node_modules/@trpc/client/dist/httpLink-lG_6juPY.mjs
3158
3169
  function isOctetType(input) {
3159
3170
  return input instanceof Uint8Array || input instanceof Blob;
3160
3171
  }
@@ -3228,21 +3239,21 @@ var import_objectSpread25, universalRequester = (opts) => {
3228
3239
  }
3229
3240
  return jsonHttpRequester(opts);
3230
3241
  };
3231
- var init_httpLink_DCFpUmZF = __esm(() => {
3242
+ var init_httpLink_lG_6juPY = __esm(() => {
3232
3243
  init_objectSpread2_BvkFp__Y();
3233
- init_TRPCClientError_CjKyS10w();
3234
- init_httpUtils_Dv57hbOd();
3244
+ init_TRPCClientError_apv8gw59();
3245
+ init_httpUtils_pyf5RF99();
3235
3246
  init_observable();
3236
3247
  init_unstable_core_do_not_import();
3237
3248
  import_objectSpread25 = __toESM2(require_objectSpread2(), 1);
3238
3249
  });
3239
3250
 
3240
- // node_modules/@trpc/client/dist/httpBatchLink-BOe5aCcR.mjs
3251
+ // node_modules/@trpc/client/dist/httpBatchLink-LhidKAPw.mjs
3241
3252
  var import_objectSpread26;
3242
- var init_httpBatchLink_BOe5aCcR = __esm(() => {
3253
+ var init_httpBatchLink_LhidKAPw = __esm(() => {
3243
3254
  init_objectSpread2_BvkFp__Y();
3244
- init_TRPCClientError_CjKyS10w();
3245
- init_httpUtils_Dv57hbOd();
3255
+ init_TRPCClientError_apv8gw59();
3256
+ init_httpUtils_pyf5RF99();
3246
3257
  import_objectSpread26 = __toESM2(require_objectSpread2(), 1);
3247
3258
  });
3248
3259
 
@@ -3253,7 +3264,7 @@ var init_loggerLink_ineCN1PO = __esm(() => {
3253
3264
  import_objectSpread27 = __toESM2(require_objectSpread2(), 1);
3254
3265
  });
3255
3266
 
3256
- // node_modules/@trpc/client/dist/wsLink-CatceK3c.mjs
3267
+ // node_modules/@trpc/client/dist/wsLink-DSf4KOdW.mjs
3257
3268
  function withResolvers() {
3258
3269
  let resolve;
3259
3270
  let reject;
@@ -3275,12 +3286,12 @@ async function prepareUrl(urlOptions) {
3275
3286
  const connectionParams = `${prefix}connectionParams=1`;
3276
3287
  return url + connectionParams;
3277
3288
  }
3278
- async function buildConnectionMessage(connectionParams) {
3289
+ async function buildConnectionMessage(connectionParams, encoder) {
3279
3290
  const message = {
3280
3291
  method: "connectionParams",
3281
3292
  data: await resultOf(connectionParams)
3282
3293
  };
3283
- return JSON.stringify(message);
3294
+ return encoder.encode(message);
3284
3295
  }
3285
3296
  function asyncWsOpen(ws) {
3286
3297
  const { promise, resolve, reject } = withResolvers();
@@ -3331,6 +3342,7 @@ var resultOf = (value, ...args) => {
3331
3342
  (0, import_defineProperty$1.default)(this, "WebSocketPonyfill", undefined);
3332
3343
  (0, import_defineProperty$1.default)(this, "urlOptions", undefined);
3333
3344
  (0, import_defineProperty$1.default)(this, "keepAliveOpts", undefined);
3345
+ (0, import_defineProperty$1.default)(this, "encoder", undefined);
3334
3346
  (0, import_defineProperty$1.default)(this, "wsObservable", behaviorSubject(null));
3335
3347
  (0, import_defineProperty$1.default)(this, "openPromise", null);
3336
3348
  this.WebSocketPonyfill = (_opts$WebSocketPonyfi = opts.WebSocketPonyfill) !== null && _opts$WebSocketPonyfi !== undefined ? _opts$WebSocketPonyfi : WebSocket;
@@ -3338,6 +3350,7 @@ var resultOf = (value, ...args) => {
3338
3350
  throw new Error("No WebSocket implementation found - you probably don't want to use this on the server, but if you do you need to pass a `WebSocket`-ponyfill");
3339
3351
  this.urlOptions = opts.urlOptions;
3340
3352
  this.keepAliveOpts = opts.keepAlive;
3353
+ this.encoder = opts.encoder;
3341
3354
  }
3342
3355
  get ws() {
3343
3356
  return this.wsObservable.get();
@@ -3359,6 +3372,7 @@ var resultOf = (value, ...args) => {
3359
3372
  const wsPromise = prepareUrl(_this.urlOptions).then((url) => new _this.WebSocketPonyfill(url));
3360
3373
  _this.openPromise = wsPromise.then(async (ws) => {
3361
3374
  _this.ws = ws;
3375
+ ws.binaryType = "arraybuffer";
3362
3376
  ws.addEventListener("message", function({ data }) {
3363
3377
  if (data === "PING")
3364
3378
  this.send("PONG");
@@ -3371,7 +3385,7 @@ var resultOf = (value, ...args) => {
3371
3385
  });
3372
3386
  await asyncWsOpen(ws);
3373
3387
  if (_this.urlOptions.connectionParams)
3374
- ws.send(await buildConnectionMessage(_this.urlOptions.connectionParams));
3388
+ ws.send(await buildConnectionMessage(_this.urlOptions.connectionParams, _this.encoder));
3375
3389
  });
3376
3390
  try {
3377
3391
  await _this.openPromise;
@@ -3389,9 +3403,9 @@ var resultOf = (value, ...args) => {
3389
3403
  }
3390
3404
  }
3391
3405
  }, import_defineProperty3, import_objectSpread28;
3392
- var init_wsLink_CatceK3c = __esm(() => {
3406
+ var init_wsLink_DSf4KOdW = __esm(() => {
3393
3407
  init_objectSpread2_BvkFp__Y();
3394
- init_TRPCClientError_CjKyS10w();
3408
+ init_TRPCClientError_apv8gw59();
3395
3409
  init_unstable_internals_Bg7n9BBj();
3396
3410
  init_observable();
3397
3411
  import_defineProperty$3 = __toESM2(require_defineProperty(), 1);
@@ -3520,13 +3534,13 @@ var import_defineProperty4, import_objectSpread2$4, TRPCUntypedClient = class {
3520
3534
  var init_dist = __esm(() => {
3521
3535
  init_objectSpread2_BvkFp__Y();
3522
3536
  init_splitLink_B7Cuf2c_();
3523
- init_TRPCClientError_CjKyS10w();
3524
- init_httpUtils_Dv57hbOd();
3525
- init_httpLink_DCFpUmZF();
3526
- init_httpBatchLink_BOe5aCcR();
3537
+ init_TRPCClientError_apv8gw59();
3538
+ init_httpUtils_pyf5RF99();
3539
+ init_httpLink_lG_6juPY();
3540
+ init_httpBatchLink_LhidKAPw();
3527
3541
  init_unstable_internals_Bg7n9BBj();
3528
3542
  init_loggerLink_ineCN1PO();
3529
- init_wsLink_CatceK3c();
3543
+ init_wsLink_DSf4KOdW();
3530
3544
  init_observable();
3531
3545
  init_unstable_core_do_not_import();
3532
3546
  import_defineProperty4 = __toESM2(require_defineProperty(), 1);
@@ -4548,7 +4562,7 @@ var init_dist4 = __esm(() => {
4548
4562
  function getVersionString() {
4549
4563
  return `v${VERSION}`;
4550
4564
  }
4551
- var VERSION = "0.20.1";
4565
+ var VERSION = "0.20.3";
4552
4566
 
4553
4567
  // src/debug/logger.ts
4554
4568
  import {
@@ -12816,7 +12830,7 @@ function deploymentsCommand() {
12816
12830
  printTable(["ID", "Name", "Org", "Status"], deployments.map((d) => [
12817
12831
  d.deployment_id.slice(0, 8),
12818
12832
  d.name ?? "(unnamed)",
12819
- d.org_name ?? "—",
12833
+ d.org_id ? d.org_id.slice(0, 8) : "—",
12820
12834
  d.enabled ? import_picocolors6.default.green("active") : import_picocolors6.default.dim("disabled")
12821
12835
  ]), { rawData: deployments });
12822
12836
  if (cfg.deployment_id) {
@@ -12832,15 +12846,20 @@ ${import_picocolors6.default.dim(`Current: ${cfg.deployment_name ?? cfg.deployme
12832
12846
  }
12833
12847
  const client = createTypedClient(cfg);
12834
12848
  const deployment = await client.workspaces.get.query(cfg.deployment_id);
12849
+ if (!deployment) {
12850
+ console.error(import_picocolors6.default.red(`Deployment not found: ${cfg.deployment_id}`));
12851
+ process.exit(1);
12852
+ }
12835
12853
  if (opts.json) {
12836
12854
  printResult(deployment, opts);
12837
12855
  return;
12838
12856
  }
12857
+ const org = await client.organization.getOrganizationById.query(deployment.org_id);
12839
12858
  printInfo([
12840
12859
  ["ID", deployment.deployment_id],
12841
12860
  ["Name", deployment.name],
12842
12861
  ["Description", deployment.description],
12843
- ["Organization", deployment.org_name],
12862
+ ["Organization", org?.name ?? deployment.org_id],
12844
12863
  ["Status", deployment.enabled ? "active" : "disabled"],
12845
12864
  ["Space ID", deployment.space_id],
12846
12865
  ["Created", formatDate(deployment.created_at)]
@@ -12850,6 +12869,10 @@ ${import_picocolors6.default.dim(`Current: ${cfg.deployment_name ?? cfg.deployme
12850
12869
  const cfg = requireConfig3();
12851
12870
  const client = createTypedClient(cfg);
12852
12871
  const deployment = await client.workspaces.get.query(id);
12872
+ if (!deployment) {
12873
+ console.error(import_picocolors6.default.red(`Deployment not found: ${id}`));
12874
+ process.exit(1);
12875
+ }
12853
12876
  cfg.deployment_id = deployment.deployment_id;
12854
12877
  cfg.deployment_name = deployment.name;
12855
12878
  cfg.org_id = deployment.org_id;
@@ -12980,7 +13003,7 @@ function docsCommand() {
12980
13003
  const result = await client.page.listWithTags.query({
12981
13004
  knowledge_store_id: ksId,
12982
13005
  searchTerm: opts.search,
12983
- tag_id: opts.tag,
13006
+ topic_id: opts.tag,
12984
13007
  limit: Number.parseInt(opts.limit ?? "20", 10)
12985
13008
  });
12986
13009
  const pages = result.data;
@@ -14390,22 +14413,6 @@ function suggestCommand() {
14390
14413
  }
14391
14414
  console.log(import_picocolors21.default.green("Document suggestions are being generated."));
14392
14415
  });
14393
- cmd.command("accept").description("Accept a suggestion and create a document").argument("<id>", "Suggestion ID").option("--title <title>", "Custom title for the document").option("--instructions <text>", "Custom instructions for generation").option("--json", "Output as JSON").action(async (id, opts) => {
14394
- const cfg = requireConfig11();
14395
- const client = createTypedClient(cfg);
14396
- const ksId = await getKnowledgeStoreId2(client, cfg.space_id);
14397
- const result = await client.suggestedDoc.generateDocBySuggestedDocId.mutate({
14398
- knowledgeStoreId: ksId,
14399
- suggestedDocId: id,
14400
- title: opts.title,
14401
- instructions: opts.instructions
14402
- });
14403
- if (opts.json) {
14404
- printResult(result, opts);
14405
- return;
14406
- }
14407
- console.log(import_picocolors21.default.green("Document created from suggestion."));
14408
- });
14409
14416
  cmd.command("reject").description("Reject a suggestion").argument("<id>", "Suggestion ID").option("--json", "Output as JSON").action(async (id, opts) => {
14410
14417
  const cfg = requireConfig11();
14411
14418
  const client = createTypedClient(cfg);
@@ -14443,22 +14450,13 @@ async function getKnowledgeStoreId3(client, spaceId) {
14443
14450
  }
14444
14451
  function tagsCommand() {
14445
14452
  const cmd = new Command("tags").description("Manage knowledge base tags");
14446
- cmd.command("list").description("List all tags").option("--search <query>", "Search tags by name").option("--json", "Output as JSON").action(async (opts) => {
14453
+ cmd.command("list").description("List all tags").option("--json", "Output as JSON").action(async (opts) => {
14447
14454
  const cfg = requireConfig12();
14448
14455
  const client = createTypedClient(cfg);
14449
14456
  const ksId = await getKnowledgeStoreId3(client, cfg.space_id);
14450
- let tags;
14451
- if (opts.search) {
14452
- const result = await client.tag.listKnowledgeStoreTagsWithPagination.query({
14453
- knowledge_store_id: ksId,
14454
- searchTerm: opts.search
14455
- });
14456
- tags = result.data;
14457
- } else {
14458
- tags = await client.tag.listKnowledgeStoreTags.query({
14459
- knowledge_store_id: ksId
14460
- });
14461
- }
14457
+ const tags = await client.topic.listTopicsByKnowledgeStore.query({
14458
+ knowledge_store_id: ksId
14459
+ });
14462
14460
  if (opts.json) {
14463
14461
  printResult(tags, opts);
14464
14462
  return;
@@ -14467,63 +14465,12 @@ function tagsCommand() {
14467
14465
  console.log(import_picocolors22.default.dim("No tags found."));
14468
14466
  return;
14469
14467
  }
14470
- printTable(["ID", "Name", "Description"], tags.map((t) => [t.id.slice(0, 8), t.name, t.description ?? "—"]), { rawData: tags });
14471
- });
14472
- cmd.command("create").description("Create a new tag").requiredOption("--name <name>", "Tag name").option("--description <desc>", "Tag description").option("--json", "Output as JSON").action(async (opts) => {
14473
- const cfg = requireConfig12();
14474
- const client = createTypedClient(cfg);
14475
- const ksId = await getKnowledgeStoreId3(client, cfg.space_id);
14476
- const result = await client.tag.create.mutate({
14477
- knowledge_store_id: ksId,
14478
- name: opts.name,
14479
- description: opts.description ?? ""
14480
- });
14481
- if (opts.json) {
14482
- printResult(result, opts);
14483
- return;
14484
- }
14485
- console.log(import_picocolors22.default.green(`Tag "${opts.name}" created.`));
14486
- });
14487
- cmd.command("update").description("Update a tag").argument("<id>", "Tag ID").requiredOption("--name <name>", "New tag name").option("--description <desc>", "New description").option("--json", "Output as JSON").action(async (id, opts) => {
14488
- const cfg = requireConfig12();
14489
- const client = createTypedClient(cfg);
14490
- const ksId = await getKnowledgeStoreId3(client, cfg.space_id);
14491
- const result = await client.tag.update.mutate({
14492
- id,
14493
- knowledge_store_id: ksId,
14494
- name: opts.name,
14495
- description: opts.description
14496
- });
14497
- if (opts.json) {
14498
- printResult(result, opts);
14499
- return;
14500
- }
14501
- console.log(import_picocolors22.default.green(`Tag updated.`));
14502
- });
14503
- cmd.command("delete").description("Delete a tag").argument("<id>", "Tag ID").option("--json", "Output as JSON").action(async (id, opts) => {
14504
- const cfg = requireConfig12();
14505
- const client = createTypedClient(cfg);
14506
- await client.tag.delete.mutate(id);
14507
- if (opts.json) {
14508
- printResult({ success: true, id }, opts);
14509
- return;
14510
- }
14511
- console.log(import_picocolors22.default.green("Tag deleted."));
14512
- });
14513
- cmd.command("add").description("Add a tag to a page").argument("<tag-id>", "Tag ID").argument("<page-id>", "Page ID").option("--json", "Output as JSON").action(async (tagId, pageId, opts) => {
14514
- const cfg = requireConfig12();
14515
- const client = createTypedClient(cfg);
14516
- await client.tag.addToPage.mutate({ tag_id: tagId, page_id: pageId });
14517
- if (opts.json) {
14518
- printResult({ success: true, tag_id: tagId, page_id: pageId }, opts);
14519
- return;
14520
- }
14521
- console.log(import_picocolors22.default.green("Tag added to page."));
14468
+ printTable(["ID", "Name", "Description"], tags.map((t) => [t.topic_id.slice(0, 8), t.name, t.description ?? "—"]), { rawData: tags });
14522
14469
  });
14523
14470
  cmd.command("remove").description("Remove a tag from a page").argument("<tag-id>", "Tag ID").argument("<page-id>", "Page ID").option("--json", "Output as JSON").action(async (tagId, pageId, opts) => {
14524
14471
  const cfg = requireConfig12();
14525
14472
  const client = createTypedClient(cfg);
14526
- await client.tag.removeFromPage.mutate({ tag_id: tagId, page_id: pageId });
14473
+ await client.topic.removeFromPage.mutate({ topic_id: tagId, page_id: pageId });
14527
14474
  if (opts.json) {
14528
14475
  printResult({ success: true, tag_id: tagId, page_id: pageId }, opts);
14529
14476
  return;
@@ -14534,9 +14481,9 @@ function tagsCommand() {
14534
14481
  const cfg = requireConfig12();
14535
14482
  const client = createTypedClient(cfg);
14536
14483
  const ksId = await getKnowledgeStoreId3(client, cfg.space_id);
14537
- const result = await client.tag.getPagesByTagId.query({
14484
+ const result = await client.topic.getPagesByTopicId.query({
14538
14485
  knowledge_store_id: ksId,
14539
- tag_id: tagId,
14486
+ topic_id: tagId,
14540
14487
  searchTerm: opts.search,
14541
14488
  limit: Number.parseInt(opts.limit ?? "10", 10)
14542
14489
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dosu/cli",
3
- "version": "0.20.1",
3
+ "version": "0.20.3",
4
4
  "type": "module",
5
5
  "description": "Dosu CLI - Manage MCP servers for AI tools",
6
6
  "license": "MIT",
@@ -35,25 +35,23 @@
35
35
  "node": ">=18"
36
36
  },
37
37
  "devDependencies": {
38
- "@biomejs/biome": "^2.4.9",
38
+ "@biomejs/biome": "^2.5.0",
39
+ "@clack/prompts": "^0.10.1",
40
+ "@dosu/api-types": "0.0.10",
39
41
  "@semantic-release/changelog": "^6.0.3",
40
42
  "@semantic-release/exec": "^7.1.0",
41
43
  "@semantic-release/git": "^10.0.1",
42
- "@trpc/client": "11.8.0",
43
- "@trpc/server": "11.8.0",
44
- "@types/bun": "^1.3.11",
45
- "@vitest/coverage-v8": "^3.2.0",
46
- "semantic-release": "^25.0.3",
47
- "typescript": "^5.8.3",
48
- "vitest": "^3.1.1"
49
- },
50
- "dependencies": {
51
- "@clack/prompts": "^0.10.0",
52
- "@dosu/api-types": "0.0.7",
44
+ "@trpc/client": "11.17.0",
45
+ "@trpc/server": "11.17.0",
46
+ "@types/bun": "^1.3.14",
47
+ "@vitest/coverage-v8": "^4.1.9",
53
48
  "commander": "^13.1.0",
54
- "open": "^10.1.0",
49
+ "open": "^10.2.0",
55
50
  "picocolors": "^1.1.1",
51
+ "semantic-release": "^25.0.5",
56
52
  "superjson": "^2.2.6",
53
+ "typescript": "^6.0.3",
54
+ "vitest": "^4.1.9",
57
55
  "write-file-atomic": "^5.0.1"
58
56
  }
59
57
  }