@dosu/cli 0.16.1 → 0.16.2

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 (2) hide show
  1. package/bin/dosu.js +43 -14
  2. package/package.json +1 -1
package/bin/dosu.js CHANGED
@@ -2218,6 +2218,34 @@ class Client {
2218
2218
  async delete(path) {
2219
2219
  return this.doRequest("DELETE", path);
2220
2220
  }
2221
+ async getWithApiKey(path) {
2222
+ return this.apiKeyRequest("GET", path);
2223
+ }
2224
+ async postWithApiKey(path, body) {
2225
+ return this.apiKeyRequest("POST", path, body);
2226
+ }
2227
+ async apiKeyRequest(method, path, body) {
2228
+ if (!this.config.api_key) {
2229
+ throw new Error("no API key available");
2230
+ }
2231
+ const url = this.baseURL + path;
2232
+ const headers = {
2233
+ "Content-Type": "application/json",
2234
+ "X-Dosu-API-Key": this.config.api_key
2235
+ };
2236
+ const options = { method, headers };
2237
+ if (body !== undefined) {
2238
+ options.body = JSON.stringify(body);
2239
+ }
2240
+ const controller = new AbortController;
2241
+ const timeout = setTimeout(() => controller.abort(), 1e4);
2242
+ options.signal = controller.signal;
2243
+ try {
2244
+ return await fetch(url, options);
2245
+ } finally {
2246
+ clearTimeout(timeout);
2247
+ }
2248
+ }
2221
2249
  async refreshToken() {
2222
2250
  if (!this.config.refresh_token) {
2223
2251
  throw new Error("no refresh token available");
@@ -4497,7 +4525,7 @@ var init_dist4 = __esm(() => {
4497
4525
  function getVersionString() {
4498
4526
  return `v${VERSION}`;
4499
4527
  }
4500
- var VERSION = "0.16.1";
4528
+ var VERSION = "0.16.2";
4501
4529
 
4502
4530
  // src/debug/logger.ts
4503
4531
  import {
@@ -5408,7 +5436,7 @@ function isDefinitiveError(err) {
5408
5436
  }
5409
5437
  async function requestCreateTicket(cfg, req) {
5410
5438
  const client = new Client(cfg);
5411
- const resp = await client.post(TICKETS_PATH, req);
5439
+ const resp = await client.postWithApiKey(TICKETS_PATH, req);
5412
5440
  if (resp.status !== 202 && resp.status !== 200 && resp.status !== 201) {
5413
5441
  throw new TicketHttpError(resp.status);
5414
5442
  }
@@ -5416,7 +5444,7 @@ async function requestCreateTicket(cfg, req) {
5416
5444
  }
5417
5445
  async function requestGetTicket(cfg, ticketId) {
5418
5446
  const client = new Client(cfg);
5419
- const resp = await client.get(`${TICKETS_PATH}/${encodeURIComponent(ticketId)}`);
5447
+ const resp = await client.getWithApiKey(`${TICKETS_PATH}/${encodeURIComponent(ticketId)}`);
5420
5448
  if (resp.status !== 200 && resp.status !== 202) {
5421
5449
  throw new TicketHttpError(resp.status);
5422
5450
  }
@@ -6224,7 +6252,8 @@ function installClaudeHooks(configPath, opts = {}) {
6224
6252
  if (typeof cfg.hooks !== "object" || cfg.hooks === null) {
6225
6253
  cfg.hooks = {};
6226
6254
  }
6227
- const events = [...DEFAULT_HOOK_EVENTS, ...opts.withStop ? ["Stop"] : []];
6255
+ const includeStop = opts.stop !== false;
6256
+ const events = DEFAULT_HOOK_EVENTS.filter((event) => event !== "Stop" || includeStop);
6228
6257
  for (const event of events) {
6229
6258
  const existing = Array.isArray(cfg.hooks[event]) ? cfg.hooks[event] : [];
6230
6259
  const preserved = existing.filter((g2) => !isDosuGroup(g2));
@@ -6284,7 +6313,7 @@ function inspectClaudeHooks(configPath) {
6284
6313
  var DEFAULT_HOOK_EVENTS, MARKER = "__dosu", EVENT_SUBCOMMAND;
6285
6314
  var init_claude_code = __esm(() => {
6286
6315
  init_config_helpers();
6287
- DEFAULT_HOOK_EVENTS = ["UserPromptSubmit", "PostToolUse"];
6316
+ DEFAULT_HOOK_EVENTS = ["UserPromptSubmit", "PostToolUse", "Stop"];
6288
6317
  EVENT_SUBCOMMAND = {
6289
6318
  UserPromptSubmit: "user-prompt-submit",
6290
6319
  PostToolUse: "post-tool-use",
@@ -12999,7 +13028,7 @@ async function runUserPromptSubmit(input, now = Date.now()) {
12999
13028
  return;
13000
13029
  }
13001
13030
  const cfg = loadConfig();
13002
- if (!isAuthenticated(cfg) || !cfg.deployment_id) {
13031
+ if (!cfg.api_key || !cfg.deployment_id) {
13003
13032
  logger.debug("hooks", "submit skipped reason=not-configured");
13004
13033
  return;
13005
13034
  }
@@ -13053,7 +13082,7 @@ async function runPostToolUse(input, now = Date.now()) {
13053
13082
  return;
13054
13083
  }
13055
13084
  const cfg = loadConfig();
13056
- if (!isAuthenticated(cfg) || !cfg.deployment_id) {
13085
+ if (!cfg.api_key || !cfg.deployment_id) {
13057
13086
  saveState({ ...state, lastCheckedAt: now });
13058
13087
  return;
13059
13088
  }
@@ -13110,7 +13139,7 @@ async function runStop(input, now = Date.now()) {
13110
13139
  return printContinue();
13111
13140
  }
13112
13141
  const cfg = loadConfig();
13113
- if (!isAuthenticated(cfg) || !cfg.deployment_id)
13142
+ if (!cfg.api_key || !cfg.deployment_id)
13114
13143
  return printContinue();
13115
13144
  const tc = await Promise.resolve().then(() => (init_ticket_client(), exports_ticket_client));
13116
13145
  let resp;
@@ -13210,7 +13239,7 @@ async function runInstall(agent, opts) {
13210
13239
  const { installClaudeHooks: installClaudeHooks2, claudeLocalSettingsPath: claudeLocalSettingsPath2 } = await Promise.resolve().then(() => (init_claude_code(), exports_claude_code));
13211
13240
  const configPath = claudeLocalSettingsPath2(resolveDir(opts.dir));
13212
13241
  try {
13213
- const { events } = installClaudeHooks2(configPath, { withStop: opts.withStop });
13242
+ const { events } = installClaudeHooks2(configPath, { stop: opts.stop });
13214
13243
  if (opts.json) {
13215
13244
  const { emitStep: emitStep2 } = await Promise.resolve().then(() => exports_output);
13216
13245
  emitStep2({ step: "hooks-install", path: configPath, events });
@@ -13300,7 +13329,7 @@ async function collectDoctorChecks(opts) {
13300
13329
  detail: "no deployment selected (run 'dosu setup')"
13301
13330
  });
13302
13331
  }
13303
- if (cfg.api_key && cfg.deployment_id && isAuthenticated(cfg)) {
13332
+ if (cfg.api_key && cfg.deployment_id) {
13304
13333
  const { Client: Client2 } = await Promise.resolve().then(() => (init_client(), exports_client));
13305
13334
  const ok = await new Client2(cfg).validateAPIKey(cfg.api_key, cfg.deployment_id);
13306
13335
  checks.push({
@@ -13312,7 +13341,7 @@ async function collectDoctorChecks(opts) {
13312
13341
  checks.push({
13313
13342
  name: "backend",
13314
13343
  status: "warn",
13315
- detail: "skipped (not authenticated / no deployment)"
13344
+ detail: "skipped (no API key / no deployment)"
13316
13345
  });
13317
13346
  }
13318
13347
  return checks;
@@ -13342,7 +13371,7 @@ function hooksCommand() {
13342
13371
  cmd.command("post-tool-use").description("Hook entrypoint: poll and inject ready knowledge once").action(async () => {
13343
13372
  await runHookEntrypoint("post-tool-use", readStdinRaw());
13344
13373
  });
13345
- cmd.command("stop").description("Hook entrypoint (opt-in): last-chance non-blocking delivery").action(async () => {
13374
+ cmd.command("stop").description("Hook entrypoint: last-chance knowledge delivery when the agent stops").action(async () => {
13346
13375
  await runHookEntrypoint("stop", readStdinRaw());
13347
13376
  });
13348
13377
  cmd.command("status").description("Show the active Dosu knowledge ticket for this session").option("--json", "Output JSON", false).action((opts) => {
@@ -13355,13 +13384,13 @@ function hooksCommand() {
13355
13384
  }
13356
13385
  runStatus(input, opts);
13357
13386
  });
13358
- cmd.command("install").description("Install Dosu hooks into a coding agent's local config").addArgument(new Argument("<agent>", "coding agent to configure").choices(SUPPORTED_AGENTS)).option("--scope <scope>", "Config scope (local only)", "local").option("--dir <path>", "Project root (defaults to current directory)").option("--with-stop", "Also install the optional Stop hook", false).option("--json", "Emit machine-readable JSON", false).addHelpText("after", [
13387
+ cmd.command("install").description("Install Dosu hooks into a coding agent's local config").addArgument(new Argument("<agent>", "coding agent to configure").choices(SUPPORTED_AGENTS)).option("--scope <scope>", "Config scope (local only)", "local").option("--dir <path>", "Project root (defaults to current directory)").option("--no-stop", "Skip the Stop hook (knowledge then delivers mid-session only, less reliably)").option("--json", "Emit machine-readable JSON", false).addHelpText("after", [
13359
13388
  "",
13360
13389
  `Supported agents: ${SUPPORTED_AGENTS.join(", ")}`,
13361
13390
  "",
13362
13391
  "Examples:",
13363
13392
  " $ dosu hooks install claude-code",
13364
- " $ dosu hooks install claude-code --with-stop",
13393
+ " $ dosu hooks install claude-code --no-stop",
13365
13394
  " $ dosu hooks install claude-code --dir ./my-project"
13366
13395
  ].join(`
13367
13396
  `)).action((agent, opts) => runInstall(agent, opts));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dosu/cli",
3
- "version": "0.16.1",
3
+ "version": "0.16.2",
4
4
  "type": "module",
5
5
  "description": "Dosu CLI - Manage MCP servers for AI tools",
6
6
  "license": "MIT",