@trydecember/cli 0.3.3 → 0.3.6

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/dist/december.js +356 -28
  2. package/package.json +12 -12
package/dist/december.js CHANGED
@@ -108813,6 +108813,161 @@ var init_libesm = __esm(() => {
108813
108813
  init_apply();
108814
108814
  });
108815
108815
 
108816
+ // ../../packages/tools/src/fuzzy_patch.ts
108817
+ function trimRight(str2) {
108818
+ return str2.replace(/[ \t\r]+$/, "");
108819
+ }
108820
+ function splitLines(text) {
108821
+ const lines = text.split(`
108822
+ `);
108823
+ return lines.map((l) => l.endsWith("\r") ? l.slice(0, -1) : l);
108824
+ }
108825
+ function parseHunkHeader(line) {
108826
+ if (!line.startsWith("@@"))
108827
+ return null;
108828
+ const endHunk = line.indexOf("@@", 2);
108829
+ if (endHunk === -1)
108830
+ return null;
108831
+ const header = line.substring(2, endHunk).trim();
108832
+ const parts = header.split(/\s+/);
108833
+ if (parts.length < 2)
108834
+ return null;
108835
+ let oldPart = parts[0] || "";
108836
+ let newPart = parts[1] || "";
108837
+ if (oldPart.startsWith("-"))
108838
+ oldPart = oldPart.slice(1);
108839
+ if (newPart.startsWith("+"))
108840
+ newPart = newPart.slice(1);
108841
+ let oldStart = 1;
108842
+ let oldCount = 1;
108843
+ let newStart = 1;
108844
+ let newCount = 1;
108845
+ if (oldPart.includes(",")) {
108846
+ const [s2, c] = oldPart.split(",");
108847
+ oldStart = parseInt(s2 || "1", 10);
108848
+ oldCount = parseInt(c || "0", 10);
108849
+ } else if (oldPart) {
108850
+ oldStart = parseInt(oldPart, 10);
108851
+ }
108852
+ if (newPart.includes(",")) {
108853
+ const [s2, c] = newPart.split(",");
108854
+ newStart = parseInt(s2 || "1", 10);
108855
+ newCount = parseInt(c || "0", 10);
108856
+ } else if (newPart) {
108857
+ newStart = parseInt(newPart, 10);
108858
+ }
108859
+ return {
108860
+ oldStart,
108861
+ oldCount,
108862
+ newStart,
108863
+ newCount,
108864
+ oldLines: [],
108865
+ newLines: []
108866
+ };
108867
+ }
108868
+ function parseDiff(diffStr) {
108869
+ const hunks = [];
108870
+ const lines = splitLines(diffStr);
108871
+ let currentHunk = null;
108872
+ for (const line of lines) {
108873
+ if (line.startsWith("@@ ")) {
108874
+ if (currentHunk) {
108875
+ hunks.push(currentHunk);
108876
+ }
108877
+ currentHunk = parseHunkHeader(line);
108878
+ continue;
108879
+ }
108880
+ if (!currentHunk)
108881
+ continue;
108882
+ if (line === "") {
108883
+ currentHunk.oldLines.push("");
108884
+ currentHunk.newLines.push("");
108885
+ } else if (line.startsWith(" ")) {
108886
+ const content = line.slice(1);
108887
+ currentHunk.oldLines.push(content);
108888
+ currentHunk.newLines.push(content);
108889
+ } else if (line.startsWith("-")) {
108890
+ currentHunk.oldLines.push(line.slice(1));
108891
+ } else if (line.startsWith("+")) {
108892
+ currentHunk.newLines.push(line.slice(1));
108893
+ }
108894
+ }
108895
+ if (currentHunk) {
108896
+ hunks.push(currentHunk);
108897
+ }
108898
+ return hunks;
108899
+ }
108900
+ function matchScore(fileLines, fileIdx, patternLines) {
108901
+ if (fileIdx + patternLines.length > fileLines.length)
108902
+ return 0;
108903
+ if (patternLines.length === 0)
108904
+ return 1;
108905
+ let matches = 0;
108906
+ for (let i2 = 0;i2 < patternLines.length; i2++) {
108907
+ const f3 = fileLines[fileIdx + i2] || "";
108908
+ const p = patternLines[i2] || "";
108909
+ if (f3 === p) {
108910
+ matches += 2;
108911
+ } else if (trimRight(f3) === trimRight(p)) {
108912
+ matches += 1;
108913
+ }
108914
+ }
108915
+ return matches / (2 * patternLines.length);
108916
+ }
108917
+ function findBestMatchOffset(fileLines, hunk, fuzzFactor = 0.5) {
108918
+ const expectedIdx = Math.max(0, hunk.oldStart - 1);
108919
+ if (hunk.oldLines.length === 0) {
108920
+ return Math.min(expectedIdx, fileLines.length);
108921
+ }
108922
+ const score = matchScore(fileLines, expectedIdx, hunk.oldLines);
108923
+ if (score >= 0.99)
108924
+ return expectedIdx;
108925
+ const maxRadius = fileLines.length;
108926
+ let bestIdx = -1;
108927
+ let bestScore = fuzzFactor;
108928
+ for (let r2 = 1;r2 <= maxRadius; r2++) {
108929
+ const up = expectedIdx - r2;
108930
+ const down = expectedIdx + r2;
108931
+ if (up >= 0) {
108932
+ const s2 = matchScore(fileLines, up, hunk.oldLines);
108933
+ if (s2 > bestScore) {
108934
+ bestScore = s2;
108935
+ bestIdx = up;
108936
+ if (s2 >= 0.99)
108937
+ return bestIdx;
108938
+ }
108939
+ }
108940
+ if (down + hunk.oldLines.length <= fileLines.length) {
108941
+ const s2 = matchScore(fileLines, down, hunk.oldLines);
108942
+ if (s2 > bestScore) {
108943
+ bestScore = s2;
108944
+ bestIdx = down;
108945
+ if (s2 >= 0.99)
108946
+ return bestIdx;
108947
+ }
108948
+ }
108949
+ }
108950
+ return bestIdx;
108951
+ }
108952
+ function applyFuzzyPatchTS(originalContent, unifiedDiff, fuzzFactor = 0.5) {
108953
+ if (!originalContent || !unifiedDiff)
108954
+ return null;
108955
+ const hunks = parseDiff(unifiedDiff);
108956
+ if (hunks.length === 0)
108957
+ return null;
108958
+ const fileLines = splitLines(originalContent);
108959
+ for (const hunk of hunks) {
108960
+ const targetIdx = findBestMatchOffset(fileLines, hunk, fuzzFactor);
108961
+ if (targetIdx < 0) {
108962
+ return null;
108963
+ }
108964
+ const deleteCount = hunk.oldLines.length;
108965
+ fileLines.splice(targetIdx, deleteCount, ...hunk.newLines);
108966
+ }
108967
+ return fileLines.join(`
108968
+ `);
108969
+ }
108970
+
108816
108971
  // ../../packages/tools/src/edit_diff.ts
108817
108972
  var diffSchema, EditDiffTool;
108818
108973
  var init_edit_diff = __esm(() => {
@@ -108838,8 +108993,11 @@ var init_edit_diff = __esm(() => {
108838
108993
  }
108839
108994
  const normalizedContent = content.replace(/\r\n/g, `
108840
108995
  `);
108841
- const updated = applyPatch(normalizedContent, formattedDiff);
108842
- if (updated === false) {
108996
+ let updated = applyFuzzyPatchTS(normalizedContent, formattedDiff);
108997
+ if (updated === null) {
108998
+ updated = applyPatch(normalizedContent, formattedDiff);
108999
+ }
109000
+ if (updated === false || updated === null) {
108843
109001
  return `Error: Failed to apply unified diff patch to '${path10}'. Ensure context lines match the existing file exactly, or use edit_file instead.`;
108844
109002
  }
108845
109003
  await context.operations.fs.writeFile(path10, updated);
@@ -164927,6 +165085,161 @@ var init_web_search = __esm(() => {
164927
165085
  };
164928
165086
  });
164929
165087
 
165088
+ // ../../packages/tools/src/python_repl.ts
165089
+ import { spawn as spawn4 } from "node:child_process";
165090
+
165091
+ class PythonReplKernel {
165092
+ process = null;
165093
+ active = false;
165094
+ ensureProcess() {
165095
+ if (this.process && this.active && !this.process.killed) {
165096
+ return this.process;
165097
+ }
165098
+ const proc = spawn4("python3", ["-u", "-c", PYTHON_DAEMON_SCRIPT], {
165099
+ stdio: ["pipe", "pipe", "pipe"],
165100
+ env: { ...process.env, PYTHONUNBUFFERED: "1" }
165101
+ });
165102
+ proc.on("exit", () => {
165103
+ this.active = false;
165104
+ this.process = null;
165105
+ });
165106
+ this.process = proc;
165107
+ this.active = true;
165108
+ return proc;
165109
+ }
165110
+ reset() {
165111
+ if (this.process) {
165112
+ try {
165113
+ this.process.kill("SIGKILL");
165114
+ } catch {}
165115
+ }
165116
+ this.process = null;
165117
+ this.active = false;
165118
+ }
165119
+ async execute(code, timeoutSeconds = 30) {
165120
+ return new Promise((resolve4) => {
165121
+ let proc;
165122
+ try {
165123
+ proc = this.ensureProcess();
165124
+ } catch (err) {
165125
+ return resolve4(`Error initializing Python REPL: ${err.message}`);
165126
+ }
165127
+ let responseBuffer = "";
165128
+ const onData = (data2) => {
165129
+ responseBuffer += data2.toString();
165130
+ if (responseBuffer.includes(`
165131
+ `)) {
165132
+ cleanup();
165133
+ const line = responseBuffer.trim();
165134
+ try {
165135
+ const parsed = JSON.parse(line);
165136
+ const out = (parsed.output || "").trim();
165137
+ const err = (parsed.error || "").trim();
165138
+ let res = "";
165139
+ if (out)
165140
+ res += out;
165141
+ if (err)
165142
+ res += (res ? `
165143
+ [stderr]
165144
+ ` : "") + err;
165145
+ resolve4(res || "Code executed successfully with no output.");
165146
+ } catch (e2) {
165147
+ resolve4(`Failed to parse REPL output: ${e2.message}`);
165148
+ }
165149
+ }
165150
+ };
165151
+ const onError = (data2) => {};
165152
+ const timer = setTimeout(() => {
165153
+ cleanup();
165154
+ this.reset();
165155
+ resolve4(`Execution timed out after ${timeoutSeconds} seconds. REPL session reset.`);
165156
+ }, timeoutSeconds * 1000);
165157
+ const cleanup = () => {
165158
+ clearTimeout(timer);
165159
+ proc.stdout?.off("data", onData);
165160
+ proc.stderr?.off("data", onError);
165161
+ };
165162
+ proc.stdout?.on("data", onData);
165163
+ proc.stderr?.on("data", onError);
165164
+ if (!proc.stdin || proc.stdin.destroyed) {
165165
+ cleanup();
165166
+ this.reset();
165167
+ return resolve4("Error: Python REPL stdin is closed. Session reset.");
165168
+ }
165169
+ const payload = JSON.stringify({ code }) + `
165170
+ `;
165171
+ proc.stdin.write(payload, (err) => {
165172
+ if (err) {
165173
+ cleanup();
165174
+ this.reset();
165175
+ return resolve4(`Failed to write to Python REPL: ${err.message}`);
165176
+ }
165177
+ });
165178
+ });
165179
+ }
165180
+ }
165181
+ var pythonReplSchema, PYTHON_DAEMON_SCRIPT = `
165182
+ import sys, json, io, contextlib
165183
+
165184
+ globals_dict = {'__name__': '__main__', '__doc__': None, '__package__': None}
165185
+
165186
+ while True:
165187
+ line = sys.stdin.readline()
165188
+ if not line:
165189
+ break
165190
+ try:
165191
+ data = json.loads(line)
165192
+ code_str = data.get("code", "")
165193
+
165194
+ stdout_buf = io.StringIO()
165195
+ stderr_buf = io.StringIO()
165196
+
165197
+ with contextlib.redirect_stdout(stdout_buf), contextlib.redirect_stderr(stderr_buf):
165198
+ try:
165199
+ compiled = compile(code_str, '<repl>', 'eval')
165200
+ val = eval(compiled, globals_dict)
165201
+ if val is not None:
165202
+ print(repr(val))
165203
+ except SyntaxError:
165204
+ compiled = compile(code_str, '<repl>', 'exec')
165205
+ exec(compiled, globals_dict)
165206
+
165207
+ out = stdout_buf.getvalue()
165208
+ err = stderr_buf.getvalue()
165209
+ print(json.dumps({"success": True, "output": out, "error": err}), flush=True)
165210
+ except Exception as e:
165211
+ print(json.dumps({"success": False, "output": "", "error": str(e)}), flush=True)
165212
+ `, globalReplKernel, PythonReplTool;
165213
+ var init_python_repl = __esm(() => {
165214
+ init_src();
165215
+ init_esm2();
165216
+ pythonReplSchema = Type2.Object({
165217
+ code: Type2.String({ description: "Python code snippet to execute." }),
165218
+ reset: Type2.Optional(Type2.Boolean({ description: "Set to true to reset the stateful REPL session." })),
165219
+ timeoutSeconds: Type2.Optional(Type2.Number({ description: "Execution timeout in seconds. Defaults to 30." }))
165220
+ });
165221
+ globalReplKernel = new PythonReplKernel;
165222
+ PythonReplTool = {
165223
+ name: "python_repl",
165224
+ description: "Executes Python code in an interactive stateful REPL environment. Variables, functions, and imports are preserved across calls.",
165225
+ inputSchema: pythonReplSchema,
165226
+ execute: async ({ code, reset = false, timeoutSeconds = 30 }, context) => {
165227
+ try {
165228
+ if (reset) {
165229
+ globalReplKernel.reset();
165230
+ if (!code || !code.trim()) {
165231
+ return "Python REPL session reset successfully.";
165232
+ }
165233
+ }
165234
+ const resultText = await globalReplKernel.execute(code, timeoutSeconds);
165235
+ return truncateOutput(resultText, 1e4, 100).text;
165236
+ } catch (error6) {
165237
+ return `Python REPL execution error: ${error6.message}`;
165238
+ }
165239
+ }
165240
+ };
165241
+ });
165242
+
164930
165243
  // ../../packages/tools/src/index.ts
164931
165244
  var exports_src4 = {};
164932
165245
  __export(exports_src4, {
@@ -164939,6 +165252,7 @@ __export(exports_src4, {
164939
165252
  WriteFileTool: () => WriteFileTool,
164940
165253
  WebSearchTool: () => WebSearchTool,
164941
165254
  ReadFileTool: () => ReadFileTool,
165255
+ PythonReplTool: () => PythonReplTool,
164942
165256
  ManageTaskTool: () => ManageTaskTool,
164943
165257
  MCPTool: () => MCPTool,
164944
165258
  LsTool: () => LsTool,
@@ -164965,6 +165279,7 @@ var init_src5 = __esm(() => {
164965
165279
  init_browser();
164966
165280
  init_mcp();
164967
165281
  init_web_search();
165282
+ init_python_repl();
164968
165283
  });
164969
165284
 
164970
165285
  // ../../node_modules/.bun/react@19.2.7/node_modules/react/cjs/react.development.js
@@ -202520,7 +202835,7 @@ var init_render_to_string = __esm(async () => {
202520
202835
  });
202521
202836
 
202522
202837
  // ../../node_modules/.bun/ink@7.1.0+90ffd46201e3176f/node_modules/ink/build/components/Static.js
202523
- function Static12(props) {
202838
+ function Static13(props) {
202524
202839
  const { items, children: render4, style: customStyle } = props;
202525
202840
  const [index2, setIndex] = import_react17.useState(0);
202526
202841
  const itemsToRender = import_react17.useMemo(() => {
@@ -203399,7 +203714,7 @@ __export(exports_build, {
203399
203714
  kittyFlags: () => kittyFlags,
203400
203715
  Transform: () => Transform2,
203401
203716
  Text: () => Text3,
203402
- Static: () => Static12,
203717
+ Static: () => Static13,
203403
203718
  Spacer: () => Spacer,
203404
203719
  Newline: () => Newline,
203405
203720
  Box: () => Box_default
@@ -204565,7 +204880,7 @@ var init_shortcuts_menu = __esm(async () => {
204565
204880
  { key: "ctrl+c", desc: "Exit / Graceful interrupt" },
204566
204881
  { key: "ctrl+h", desc: "Session history" },
204567
204882
  { key: "ctrl+l", desc: "Login / Account menu" },
204568
- { key: "ctrl+o", desc: "Toggle expand commands" },
204883
+ { key: "ctrl+o", desc: "Toggle expand commands & thoughts" },
204569
204884
  { key: "ctrl+t", desc: "Tasks mode" },
204570
204885
  { key: "alt+enter", desc: "Insert newline" },
204571
204886
  { key: "esc", desc: "Cancel / Close menu" }
@@ -249855,13 +250170,21 @@ var init_smooth_markdown = __esm(async () => {
249855
250170
  });
249856
250171
 
249857
250172
  // ../../packages/tui/src/components/messages/bot-message.tsx
249858
- function CollapsibleThought({ content, isStreaming }) {
249859
- const [expanded, setExpanded] = import_react45.useState(false);
250173
+ function CollapsibleThought({
250174
+ content,
250175
+ isStreaming,
250176
+ forceExpanded
250177
+ }) {
250178
+ const [userExpanded, setUserExpanded] = import_react45.useState(null);
250179
+ const expanded = userExpanded !== null ? userExpanded : forceExpanded ?? true;
249860
250180
  const words2 = content.trim() ? content.trim().split(/\s+/).length : 0;
249861
250181
  const tokenCount = Math.max(1, Math.round(words2 * 1.33));
249862
250182
  use_input_default((input, key) => {
249863
250183
  if (key.ctrl && input.toLowerCase() === "o" || input === "\x0F") {
249864
- setExpanded((prev2) => !prev2);
250184
+ setUserExpanded((prev2) => {
250185
+ const current = prev2 !== null ? prev2 : forceExpanded ?? true;
250186
+ return !current;
250187
+ });
249865
250188
  }
249866
250189
  });
249867
250190
  if (isStreaming) {
@@ -249945,11 +250268,14 @@ function CollapsibleCommandOutput({
249945
250268
  forceExpanded
249946
250269
  }) {
249947
250270
  const { isFocused } = use_focus_default({ autoFocus: true });
249948
- const [userExpanded, setUserExpanded] = import_react45.useState(false);
249949
- const isExpanded = userExpanded || Boolean(forceExpanded);
250271
+ const [userExpanded, setUserExpanded] = import_react45.useState(null);
250272
+ const isExpanded = userExpanded !== null ? userExpanded : forceExpanded ?? true;
249950
250273
  use_input_default((input, key) => {
249951
250274
  if (key.ctrl && (key.name === "o" || input?.toLowerCase() === "o") || input === "\x0F") {
249952
- setUserExpanded((prev2) => !prev2);
250275
+ setUserExpanded((prev2) => {
250276
+ const current = prev2 !== null ? prev2 : forceExpanded ?? true;
250277
+ return !current;
250278
+ });
249953
250279
  }
249954
250280
  });
249955
250281
  const lines = output ? output.trim().split(/\r?\n/) : [];
@@ -250104,7 +250430,8 @@ var init_bot_message = __esm(async () => {
250104
250430
  const thoughtContent = part.replace(/^<thought(?:>| [^>]*>)/i, "").replace(/<\/thought>$/i, "").trim();
250105
250431
  return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(CollapsibleThought, {
250106
250432
  content: thoughtContent,
250107
- isStreaming
250433
+ isStreaming,
250434
+ forceExpanded: expandCommands
250108
250435
  }, pidx, false, undefined, this);
250109
250436
  }
250110
250437
  if (part.trim() === "")
@@ -250147,7 +250474,8 @@ var init_bot_message = __esm(async () => {
250147
250474
  const isStreaming = block.isStreaming ?? idx === blocks.length - 1;
250148
250475
  return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(CollapsibleThought, {
250149
250476
  content: block.content,
250150
- isStreaming
250477
+ isStreaming,
250478
+ forceExpanded: expandCommands
250151
250479
  }, idx, false, undefined, this);
250152
250480
  }
250153
250481
  case "compaction": {
@@ -254936,7 +255264,7 @@ function useAgentSession({
254936
255264
  settingsFollowUpMode,
254937
255265
  setSettingsFollowUpMode
254938
255266
  } = state;
254939
- const [expandCommands, setExpandCommands] = import_react55.useState(false);
255267
+ const [expandCommands, setExpandCommands] = import_react55.useState(true);
254940
255268
  const toggleExpandCommands = import_react55.useCallback(() => {
254941
255269
  setExpandCommands((prev2) => !prev2);
254942
255270
  }, []);
@@ -261027,7 +261355,7 @@ var exports_local_operations = {};
261027
261355
  __export(exports_local_operations, {
261028
261356
  localOperations: () => localOperations
261029
261357
  });
261030
- import { exec as exec5, spawn as spawn4 } from "node:child_process";
261358
+ import { exec as exec5, spawn as spawn5 } from "node:child_process";
261031
261359
  import fs14 from "node:fs/promises";
261032
261360
  import path13 from "node:path";
261033
261361
  import { promisify as promisify3 } from "node:util";
@@ -261042,7 +261370,7 @@ var init_local_operations = __esm(() => {
261042
261370
  bash: {
261043
261371
  exec: async (command, cwd2, options) => {
261044
261372
  return new Promise((resolve4, reject2) => {
261045
- const child = spawn4(command, {
261373
+ const child = spawn5(command, {
261046
261374
  cwd: cwd2,
261047
261375
  detached: process.platform !== "win32",
261048
261376
  env: options.env ?? process.env,
@@ -261284,8 +261612,17 @@ var init_version_check = __esm(() => {
261284
261612
  // package.json
261285
261613
  var package_default = {
261286
261614
  name: "@trydecember/cli",
261287
- version: "0.3.3",
261288
- description: "AI coding assistant for your terminal — write code, fix bugs, and run commands.",
261615
+ version: "0.3.6",
261616
+ description: "coding agent that runs in your terminal and the cloud.",
261617
+ homepage: "https://trydecember.com",
261618
+ repository: {
261619
+ type: "git",
261620
+ url: "https://github.com/phasehumans/december",
261621
+ directory: "apps/cli"
261622
+ },
261623
+ bugs: {
261624
+ url: "https://github.com/phasehumans/december/issues"
261625
+ },
261289
261626
  module: "src/index.ts",
261290
261627
  type: "module",
261291
261628
  private: false,
@@ -261296,15 +261633,6 @@ var package_default = {
261296
261633
  "terminal",
261297
261634
  "agent"
261298
261635
  ],
261299
- homepage: "https://trydecember.com",
261300
- repository: {
261301
- type: "git",
261302
- url: "https://github.com/phasehumans/december.git",
261303
- directory: "apps/cli"
261304
- },
261305
- bugs: {
261306
- url: "https://github.com/phasehumans/december/issues"
261307
- },
261308
261636
  engines: {
261309
261637
  node: ">=18.0.0"
261310
261638
  },
@@ -261313,7 +261641,7 @@ var package_default = {
261313
261641
  },
261314
261642
  main: "./dist/december.js",
261315
261643
  bin: {
261316
- december: "./dist/december.js"
261644
+ december: "dist/december.js"
261317
261645
  },
261318
261646
  files: [
261319
261647
  "dist",
package/package.json CHANGED
@@ -1,7 +1,16 @@
1
1
  {
2
2
  "name": "@trydecember/cli",
3
- "version": "0.3.3",
4
- "description": "AI coding assistant for your terminal — write code, fix bugs, and run commands.",
3
+ "version": "0.3.6",
4
+ "description": "coding agent that runs in your terminal and the cloud.",
5
+ "homepage": "https://trydecember.com",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/phasehumans/december",
9
+ "directory": "apps/cli"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/phasehumans/december/issues"
13
+ },
5
14
  "module": "src/index.ts",
6
15
  "type": "module",
7
16
  "private": false,
@@ -12,15 +21,6 @@
12
21
  "terminal",
13
22
  "agent"
14
23
  ],
15
- "homepage": "https://trydecember.com",
16
- "repository": {
17
- "type": "git",
18
- "url": "https://github.com/phasehumans/december.git",
19
- "directory": "apps/cli"
20
- },
21
- "bugs": {
22
- "url": "https://github.com/phasehumans/december/issues"
23
- },
24
24
  "engines": {
25
25
  "node": ">=18.0.0"
26
26
  },
@@ -29,7 +29,7 @@
29
29
  },
30
30
  "main": "./dist/december.js",
31
31
  "bin": {
32
- "december": "./dist/december.js"
32
+ "december": "dist/december.js"
33
33
  },
34
34
  "files": [
35
35
  "dist",