buddy-workbench 0.1.81 → 0.1.83

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/bin/devbuddy.js CHANGED
@@ -64,10 +64,15 @@ function npmExecOptions(options = {}) {
64
64
  };
65
65
  }
66
66
 
67
+ function npmInstallArgs(packageSpec, global = false) {
68
+ const before = new Date(Date.now() - 48 * 60 * 60 * 1000).toISOString();
69
+ return ['install', ...(global ? ['--global'] : []), '--before', before, packageSpec];
70
+ }
71
+
67
72
  function scheduleWindowsSelfUpdate(packageSpec) {
68
73
  const updateScript = `import { execFileSync } from 'node:child_process';
69
74
  await new Promise((resolve) => setTimeout(resolve, 1500));
70
- execFileSync('npm.cmd', ['install', '--global', ${JSON.stringify(packageSpec)}], { shell: true, windowsHide: true, stdio: 'inherit' });`;
75
+ execFileSync('npm.cmd', ${JSON.stringify(npmInstallArgs(packageSpec, true))}, { shell: true, windowsHide: true, stdio: 'inherit' });`;
71
76
  const updater = spawn(process.execPath, ['--input-type=module', '-e', updateScript], {
72
77
  cwd: homedir(),
73
78
  detached: true,
@@ -117,7 +122,7 @@ function selfUpdate(args) {
117
122
  return;
118
123
  }
119
124
  try {
120
- execFileSync(npmCommand(), ['install', '--global', `${details.name}@${version}`], npmExecOptions({
125
+ execFileSync(npmCommand(), npmInstallArgs(`${details.name}@${version}`, true), npmExecOptions({
121
126
  cwd: root,
122
127
  stdio: 'inherit'
123
128
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "buddy-workbench",
3
- "version": "0.1.81",
3
+ "version": "0.1.83",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {
@@ -102,8 +102,9 @@ function aiCompletionUrl(host) {
102
102
  }
103
103
 
104
104
  function getAiMessageContent(data) {
105
- const content = data?.choices?.[0]?.message?.content;
105
+ const content = data?.choices?.[0]?.message?.content ?? data;
106
106
  if (Array.isArray(content)) return content.map((part) => part?.text || '').join('');
107
+ if (content && typeof content === 'object') return JSON.stringify(content);
107
108
  return typeof content === 'string' ? content : '';
108
109
  }
109
110
 
@@ -175,7 +176,7 @@ async function runAiReview({ aiApiHost, pr, files }) {
175
176
  const content = getAiMessageContent(response.data);
176
177
  if (!content.trim()) return { configured: true, status: 'error', reviewedFiles: files.length, error: 'AI review returned an empty response.' };
177
178
  const parsed = parseAiReview(content);
178
- return { configured: true, status: 'completed', reviewedFiles: files.length, content, ...parsed };
179
+ return { configured: true, status: 'completed', reviewedFiles: files.length, content: parsed.summary || content, ...parsed };
179
180
  } catch (error) {
180
181
  recordApiError({ source: 'AI API (PR Review)', method: 'POST', url: aiCompletionUrl(aiApiHost), message: error.message });
181
182
  return { configured: true, status: 'error', reviewedFiles: files.length, error: `AI review failed: ${error.message}` };