@trydecember/cli 0.3.11 → 0.3.13

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # December
2
2
 
3
- December is an AI coding assistant that lives in your terminal. It understands your codebase and helps you build faster by writing code, fixing bugs, and running commands. Use it directly in your terminal or alongside your favorite IDE.
3
+ December is an AI coding agent that lives in your terminal. It understands your codebase and helps you build faster by writing code, fixing bugs, and running commands. Use it directly in your terminal or alongside your favorite IDE.
4
4
 
5
5
  **Also available on the web at <a href="https://trydecember.com" target="_blank">trydecember.com</a>**
6
6
 
@@ -14,12 +14,20 @@ December is an AI coding assistant that lives in your terminal. It understands y
14
14
 
15
15
  ### Get Started
16
16
 
17
- 1. Install December:
17
+ 1. Install December (via npm, curl, or powershell):
18
18
 
19
19
  ```bash
20
20
  npm install -g @trydecember/cli
21
21
  ```
22
22
 
23
+ ```bash
24
+ curl -fsSL https://trydecember.com/install.sh | bash
25
+ ```
26
+
27
+ ```powershell
28
+ irm https://trydecember.com/install.ps1 | iex
29
+ ```
30
+
23
31
  2. Navigate to your project directory and run `december`.
24
32
 
25
33
  ### Feedback & Bugs
package/dist/december.js CHANGED
@@ -23143,13 +23143,13 @@ var init_dist = __esm(() => {
23143
23143
  });
23144
23144
 
23145
23145
  // ../../packages/shared/src/env.ts
23146
- var env3;
23146
+ var env3, effectiveJwtSecret;
23147
23147
  var init_env = __esm(() => {
23148
23148
  init_dist();
23149
23149
  init_zod();
23150
23150
  env3 = createEnv({
23151
23151
  server: {
23152
- ENV: exports_external.enum(["DEV", "TEST", "PROD"]).default("DEV"),
23152
+ NODE_ENV: exports_external.enum(["development", "test", "production"]).default("development"),
23153
23153
  PORT: exports_external.coerce.number().default(3000),
23154
23154
  LOG_LEVEL: exports_external.enum(["debug", "info", "warn", "error"]).default("info"),
23155
23155
  DATABASE_URL: exports_external.string().optional(),
@@ -23161,13 +23161,21 @@ var init_env = __esm(() => {
23161
23161
  FIRECRACKER_BINARY: exports_external.string().default("./firecracker"),
23162
23162
  FIRECRACKER_KERNEL_PATH: exports_external.string().default("./vmlinux.bin"),
23163
23163
  FIRECRACKER_ROOTFS_PATH: exports_external.string().default("./ubuntu-rootfs.ext4"),
23164
- JWT_SECRET: exports_external.string().default("default-dev-jwt-secret")
23164
+ JWT_SECRET: exports_external.string().default(process.env.ACCESS_TOKEN_SECRET || "default-dev-jwt-secret")
23165
23165
  },
23166
23166
  clientPrefix: "",
23167
23167
  client: {},
23168
23168
  runtimeEnv: process.env,
23169
- emptyStringAsUndefined: true
23169
+ emptyStringAsUndefined: true,
23170
+ onValidationError: (error3) => {
23171
+ console.error("Shared environment validation error:", error3);
23172
+ throw new Error("Invalid shared environment variables");
23173
+ }
23170
23174
  });
23175
+ effectiveJwtSecret = env3.JWT_SECRET || process.env.ACCESS_TOKEN_SECRET;
23176
+ if (env3.NODE_ENV === "production" && (!effectiveJwtSecret || effectiveJwtSecret === "default-dev-jwt-secret")) {
23177
+ throw new Error("JWT_SECRET or ACCESS_TOKEN_SECRET must be configured with a secure secret in production.");
23178
+ }
23171
23179
  });
23172
23180
 
23173
23181
  // ../../packages/shared/src/truncate.ts
@@ -63418,6 +63426,9 @@ function decomposeContext(options) {
63418
63426
  };
63419
63427
  }
63420
63428
 
63429
+ // ../../packages/shared/src/usage-rates.ts
63430
+ var init_usage_rates = () => {};
63431
+
63421
63432
  // ../../packages/shared/src/index.ts
63422
63433
  var init_src = __esm(() => {
63423
63434
  init_env();
@@ -63425,6 +63436,7 @@ var init_src = __esm(() => {
63425
63436
  init_ignore();
63426
63437
  init_custom_commands();
63427
63438
  init_permissions2();
63439
+ init_usage_rates();
63428
63440
  });
63429
63441
 
63430
63442
  // ../../packages/providers/src/providers/anthropic.ts
@@ -104728,7 +104740,8 @@ async function streamAssistantResponse(agent, eventQueue, signal, turnCount = 1)
104728
104740
  eventQueue.push({
104729
104741
  type: "AgentUsage",
104730
104742
  promptTokens: chunk.promptTokens,
104731
- completionTokens: chunk.completionTokens
104743
+ completionTokens: chunk.completionTokens,
104744
+ model: loggedModel
104732
104745
  });
104733
104746
  }
104734
104747
  }
@@ -108811,13 +108824,18 @@ function createLocalBashOperations() {
108811
108824
  cwd,
108812
108825
  detached: process.platform !== "win32",
108813
108826
  env: options.env ?? process.env,
108814
- shell: true
108827
+ shell: true,
108828
+ stdio: ["pipe", "pipe", "pipe"]
108815
108829
  });
108830
+ try {
108831
+ child.stdin?.end?.();
108832
+ } catch {}
108816
108833
  if (child.pid)
108817
108834
  trackDetachedChildPid(child.pid);
108818
108835
  let output = "";
108836
+ let resolved = false;
108819
108837
  const handleData = (data) => {
108820
- const chunk = data.toString();
108838
+ const chunk = typeof data === "string" ? data : data.toString();
108821
108839
  output += chunk;
108822
108840
  options.onData(chunk);
108823
108841
  };
@@ -108842,13 +108860,19 @@ function createLocalBashOperations() {
108842
108860
  else
108843
108861
  options.signal.addEventListener("abort", onAbort, { once: true });
108844
108862
  }
108845
- child.on("close", (code) => {
108863
+ const cleanup = () => {
108846
108864
  if (child.pid)
108847
108865
  untrackDetachedChildPid(child.pid);
108848
108866
  if (timeoutHandle)
108849
108867
  clearTimeout(timeoutHandle);
108850
108868
  if (options.signal)
108851
108869
  options.signal.removeEventListener("abort", onAbort);
108870
+ };
108871
+ const finish = (code) => {
108872
+ if (resolved)
108873
+ return;
108874
+ resolved = true;
108875
+ cleanup();
108852
108876
  if (timedOut) {
108853
108877
  return reject(new Error("timeout"));
108854
108878
  }
@@ -108856,6 +108880,17 @@ function createLocalBashOperations() {
108856
108880
  return reject(new Error("aborted"));
108857
108881
  }
108858
108882
  resolve4({ exitCode: code, output });
108883
+ };
108884
+ child.on("close", finish);
108885
+ child.on("exit", (code) => {
108886
+ setTimeout(() => finish(code), 50);
108887
+ });
108888
+ child.on("error", (err) => {
108889
+ if (resolved)
108890
+ return;
108891
+ resolved = true;
108892
+ cleanup();
108893
+ reject(err);
108859
108894
  });
108860
108895
  });
108861
108896
  }
@@ -264508,10 +264543,14 @@ function startDirectCommand(command, options = {}) {
264508
264543
  stdio: ["pipe", "pipe", "pipe"],
264509
264544
  detached: !isWindows3
264510
264545
  });
264546
+ try {
264547
+ child.stdin?.end?.();
264548
+ } catch {}
264511
264549
  let timeoutTimer = null;
264512
264550
  const promise4 = new Promise((resolve4) => {
264551
+ let closed = false;
264513
264552
  child.stdout?.on("data", (data2) => {
264514
- const str2 = data2.toString("utf8");
264553
+ const str2 = typeof data2 === "string" ? data2 : data2.toString("utf8");
264515
264554
  output += str2;
264516
264555
  if (isBackground && bgTaskId) {
264517
264556
  taskManager.appendOutput(bgTaskId, str2);
@@ -264520,7 +264559,7 @@ function startDirectCommand(command, options = {}) {
264520
264559
  }
264521
264560
  });
264522
264561
  child.stderr?.on("data", (data2) => {
264523
- const str2 = data2.toString("utf8");
264562
+ const str2 = typeof data2 === "string" ? data2 : data2.toString("utf8");
264524
264563
  output += str2;
264525
264564
  if (isBackground && bgTaskId) {
264526
264565
  taskManager.appendOutput(bgTaskId, str2);
@@ -264529,6 +264568,9 @@ function startDirectCommand(command, options = {}) {
264529
264568
  }
264530
264569
  });
264531
264570
  child.on("error", (err) => {
264571
+ if (closed)
264572
+ return;
264573
+ closed = true;
264532
264574
  const errStr = `
264533
264575
  Failed to start process: ${err?.message || err}
264534
264576
  `;
@@ -264544,7 +264586,10 @@ Failed to start process: ${err?.message || err}
264544
264586
  taskId: bgTaskId
264545
264587
  });
264546
264588
  });
264547
- child.on("close", (code) => {
264589
+ const finish = (code) => {
264590
+ if (closed)
264591
+ return;
264592
+ closed = true;
264548
264593
  if (timeoutTimer)
264549
264594
  clearTimeout(timeoutTimer);
264550
264595
  const finalCode = isAborted2 ? 130 : code ?? 0;
@@ -264557,6 +264602,10 @@ Failed to start process: ${err?.message || err}
264557
264602
  isBackground: false
264558
264603
  });
264559
264604
  }
264605
+ };
264606
+ child.on("close", finish);
264607
+ child.on("exit", (code) => {
264608
+ setTimeout(() => finish(code), 50);
264560
264609
  });
264561
264610
  if (timeoutMs > 0 && timeoutMs < Infinity) {
264562
264611
  timeoutTimer = setTimeout(() => {
@@ -265149,7 +265198,7 @@ Provider: ${displayName}
265149
265198
  *Prompts go directly to the provider API; December servers do not track, log, or bill this usage. Token consumption, quotas, and billing are managed in your ${displayName} account at [${billingLink}](${billingLink})*`;
265150
265199
  }
265151
265200
  var PROVIDER_BILLING_LINKS, PROVIDER_DISPLAY_NAMES;
265152
- var init_usage_rates = __esm(() => {
265201
+ var init_usage_rates2 = __esm(() => {
265153
265202
  init_messages5();
265154
265203
  PROVIDER_BILLING_LINKS = {
265155
265204
  december: "https://trydecember.com/settings/usage",
@@ -265435,7 +265484,7 @@ function instantiateProvider(provider, apiKey) {
265435
265484
  return openaiProvider(`http://localhost:${process.env.SERVER_PORT}/api/v1`, apiKey);
265436
265485
  }
265437
265486
  const serverUrl = process.env.SERVER_URL || "https://api.trydecember.com";
265438
- const proxyUrl = `${serverUrl}/api/v1/cli`;
265487
+ const proxyUrl = `${serverUrl.replace(/\/+$/, "")}/api/v1/cli`;
265439
265488
  return openaiProvider(proxyUrl, apiKey);
265440
265489
  }
265441
265490
  }
@@ -266350,7 +266399,6 @@ function useAgentSession({
266350
266399
  }, [
266351
266400
  agent2,
266352
266401
  isAuthenticated,
266353
- addToast,
266354
266402
  setActiveMessages,
266355
266403
  setAuthMode,
266356
266404
  setCurrentGrillIndex,
@@ -267143,7 +267191,7 @@ var init_use_agent_session = __esm(async () => {
267143
267191
  init_error_parser();
267144
267192
  init_models5();
267145
267193
  init_openrouter_models();
267146
- init_usage_rates();
267194
+ init_usage_rates2();
267147
267195
  init_use_agent_runner();
267148
267196
  await __promiseAll([
267149
267197
  init_store(),
@@ -267191,13 +267239,17 @@ var init_local_operations = __esm(() => {
267191
267239
  cwd: targetCwd,
267192
267240
  detached: process.platform !== "win32",
267193
267241
  env: options.env ?? process.env,
267194
- shell: true
267242
+ shell: true,
267243
+ stdio: ["pipe", "pipe", "pipe"]
267195
267244
  });
267245
+ try {
267246
+ child.stdin?.end?.();
267247
+ } catch {}
267196
267248
  const task = taskManager.addTask(command, child);
267197
267249
  let output = "";
267198
267250
  let resolved = false;
267199
267251
  const handleData = (data2) => {
267200
- const chunk2 = data2.toString();
267252
+ const chunk2 = typeof data2 === "string" ? data2 : data2.toString();
267201
267253
  output += chunk2;
267202
267254
  taskManager.appendOutput(task.id, chunk2);
267203
267255
  if (!resolved && options.onData) {
@@ -267219,7 +267271,7 @@ var init_local_operations = __esm(() => {
267219
267271
  resolve4({ exitCode: null, output, taskId: task.id });
267220
267272
  }
267221
267273
  }, options.waitMsBeforeAsync) : undefined;
267222
- child.on("close", (code) => {
267274
+ const finish = (code) => {
267223
267275
  if (bgTimeout)
267224
267276
  clearTimeout(bgTimeout);
267225
267277
  if (timeoutHandle)
@@ -267229,6 +267281,25 @@ var init_local_operations = __esm(() => {
267229
267281
  resolved = true;
267230
267282
  resolve4({ exitCode: code, output });
267231
267283
  }
267284
+ };
267285
+ child.on("close", finish);
267286
+ child.on("exit", (code) => {
267287
+ setTimeout(() => finish(code), 50);
267288
+ });
267289
+ child.on("error", (err) => {
267290
+ if (bgTimeout)
267291
+ clearTimeout(bgTimeout);
267292
+ if (timeoutHandle)
267293
+ clearTimeout(timeoutHandle);
267294
+ taskManager.markCompleted(task.id, 1);
267295
+ if (!resolved) {
267296
+ resolved = true;
267297
+ const errMsg = `
267298
+ Failed to start process: ${err?.message || err}
267299
+ `;
267300
+ output += errMsg;
267301
+ resolve4({ exitCode: 1, output });
267302
+ }
267232
267303
  });
267233
267304
  });
267234
267305
  },
@@ -267456,7 +267527,7 @@ import path20 from "node:path";
267456
267527
  // package.json
267457
267528
  var package_default = {
267458
267529
  name: "@trydecember/cli",
267459
- version: "0.3.11",
267530
+ version: "0.3.13",
267460
267531
  description: "AI coding agent for terminal and cloud.",
267461
267532
  homepage: "https://trydecember.com",
267462
267533
  repository: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trydecember/cli",
3
- "version": "0.3.11",
3
+ "version": "0.3.13",
4
4
  "description": "AI coding agent for terminal and cloud.",
5
5
  "homepage": "https://trydecember.com",
6
6
  "repository": {
@@ -6,11 +6,10 @@ if (process.env.CI || process.env.NODE_ENV === 'development') {
6
6
  }
7
7
 
8
8
  const BLUE = '\x1b[38;2;135;178;244m'
9
- const GREEN = '\x1b[38;2;110;231;183m'
10
9
  const WHITE = '\x1b[38;2;244;244;245m'
11
10
  const TRUNK = '\x1b[38;2;63;63;70m'
12
11
  const RESET = '\x1b[0m'
13
12
 
14
- console.log(`\n${BLUE}✱${RESET} ${GREEN}december successfully installed${RESET}`)
13
+ console.log(`\n${BLUE}✱${RESET} ${BLUE}december successfully installed${RESET}`)
15
14
  console.log(`${TRUNK}│${RESET}`)
16
15
  console.log(`${BLUE}✱${RESET} run ${WHITE}december${RESET} to start your session\n`)