@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.
- package/README.md +123 -19
- package/bin/dosu.js +73 -126
- 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
|
+
[](https://www.npmjs.com/package/@dosu/cli)
|
|
6
|
+
[](https://github.com/dosu-ai/dosu-cli/actions/workflows/ci.yml)
|
|
7
|
+
[](https://codecov.io/gh/dosu-ai/dosu-cli)
|
|
8
|
+
[](#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
|
-
##
|
|
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
|
-
|
|
154
|
+
```bash
|
|
155
|
+
dosu setup --agent --tool claude
|
|
156
|
+
```
|
|
71
157
|
|
|
72
|
-
|
|
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
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
92
|
-
- Pre-releases: `v0.1.0-alpha`, `v0.1.0-beta`, `v0.1.0-rc1`
|
|
196
|
+
## License
|
|
93
197
|
|
|
94
|
-
|
|
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/
|
|
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
|
|
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-
|
|
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, [],
|
|
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
|
|
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-
|
|
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
|
|
2948
|
-
|
|
2949
|
-
|
|
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
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2971
|
+
init_getErrorShape_BPSzUA7W();
|
|
2972
|
+
init_codes_DagpWZLc();
|
|
2973
|
+
init_tracked_DWInO6EQ();
|
|
2966
2974
|
});
|
|
2967
2975
|
|
|
2968
|
-
// node_modules/@trpc/client/dist/TRPCClientError-
|
|
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
|
|
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), {}, {
|
|
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-
|
|
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
|
|
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-
|
|
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
|
|
3242
|
+
var init_httpLink_lG_6juPY = __esm(() => {
|
|
3232
3243
|
init_objectSpread2_BvkFp__Y();
|
|
3233
|
-
|
|
3234
|
-
|
|
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-
|
|
3251
|
+
// node_modules/@trpc/client/dist/httpBatchLink-LhidKAPw.mjs
|
|
3241
3252
|
var import_objectSpread26;
|
|
3242
|
-
var
|
|
3253
|
+
var init_httpBatchLink_LhidKAPw = __esm(() => {
|
|
3243
3254
|
init_objectSpread2_BvkFp__Y();
|
|
3244
|
-
|
|
3245
|
-
|
|
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-
|
|
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
|
|
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
|
|
3406
|
+
var init_wsLink_DSf4KOdW = __esm(() => {
|
|
3393
3407
|
init_objectSpread2_BvkFp__Y();
|
|
3394
|
-
|
|
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
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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("--
|
|
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
|
-
|
|
14451
|
-
|
|
14452
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
14484
|
+
const result = await client.topic.getPagesByTopicId.query({
|
|
14538
14485
|
knowledge_store_id: ksId,
|
|
14539
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
43
|
-
"@trpc/server": "11.
|
|
44
|
-
"@types/bun": "^1.3.
|
|
45
|
-
"@vitest/coverage-v8": "^
|
|
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.
|
|
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
|
}
|