vibora 9.7.2 → 9.8.0
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/vibora.js +78 -11
- package/package.json +1 -1
- package/server/index.js +16 -0
package/bin/vibora.js
CHANGED
|
@@ -45126,7 +45126,7 @@ function installUv() {
|
|
|
45126
45126
|
var package_default = {
|
|
45127
45127
|
name: "vibora",
|
|
45128
45128
|
private: true,
|
|
45129
|
-
version: "9.
|
|
45129
|
+
version: "9.8.0",
|
|
45130
45130
|
description: "Harness Attention. Orchestrate Agents. Ship.",
|
|
45131
45131
|
license: "PolyForm-Perimeter-1.0.0",
|
|
45132
45132
|
type: "module",
|
|
@@ -45659,7 +45659,7 @@ import { join as join4 } from "path";
|
|
|
45659
45659
|
// plugins/vibora-opencode/index.ts
|
|
45660
45660
|
var vibora_opencode_default = `import type { Plugin } from "@opencode-ai/plugin"
|
|
45661
45661
|
import { appendFileSync } from "node:fs"
|
|
45662
|
-
import {
|
|
45662
|
+
import { spawn } from "node:child_process"
|
|
45663
45663
|
import { tmpdir } from "node:os"
|
|
45664
45664
|
import { join } from "node:path"
|
|
45665
45665
|
|
|
@@ -45681,20 +45681,72 @@ const log = (msg: string) => {
|
|
|
45681
45681
|
}
|
|
45682
45682
|
|
|
45683
45683
|
/**
|
|
45684
|
-
* Execute vibora command using
|
|
45685
|
-
* Using
|
|
45684
|
+
* Execute vibora command using spawn with shell option for proper PATH resolution.
|
|
45685
|
+
* Using spawn with explicit args array prevents shell injection while shell:true
|
|
45686
45686
|
* ensures PATH is properly resolved (for NVM, fnm, etc. managed node installations).
|
|
45687
|
+
* Includes 10 second timeout protection to prevent hanging.
|
|
45687
45688
|
*/
|
|
45688
45689
|
async function runViboraCommand(args: string[]): Promise<{ exitCode: number; stdout: string; stderr: string }> {
|
|
45689
45690
|
return new Promise((resolve) => {
|
|
45690
|
-
|
|
45691
|
-
|
|
45692
|
-
|
|
45693
|
-
|
|
45694
|
-
|
|
45695
|
-
|
|
45691
|
+
let stdout = ''
|
|
45692
|
+
let stderr = ''
|
|
45693
|
+
let resolved = false
|
|
45694
|
+
let processExited = false
|
|
45695
|
+
let killTimeoutId: ReturnType<typeof setTimeout> | null = null
|
|
45696
|
+
|
|
45697
|
+
const child = spawn(VIBORA_CMD, args, { shell: true })
|
|
45698
|
+
|
|
45699
|
+
const cleanup = () => {
|
|
45700
|
+
processExited = true
|
|
45701
|
+
if (killTimeoutId) {
|
|
45702
|
+
clearTimeout(killTimeoutId)
|
|
45703
|
+
killTimeoutId = null
|
|
45704
|
+
}
|
|
45705
|
+
}
|
|
45706
|
+
|
|
45707
|
+
child.stdout?.on('data', (data) => {
|
|
45708
|
+
stdout += data.toString()
|
|
45709
|
+
})
|
|
45710
|
+
|
|
45711
|
+
child.stderr?.on('data', (data) => {
|
|
45712
|
+
stderr += data.toString()
|
|
45713
|
+
})
|
|
45714
|
+
|
|
45715
|
+
child.on('close', (code) => {
|
|
45716
|
+
cleanup()
|
|
45717
|
+
if (!resolved) {
|
|
45718
|
+
resolved = true
|
|
45719
|
+
resolve({ exitCode: code || 0, stdout, stderr })
|
|
45696
45720
|
}
|
|
45697
45721
|
})
|
|
45722
|
+
|
|
45723
|
+
child.on('error', (err) => {
|
|
45724
|
+
cleanup()
|
|
45725
|
+
if (!resolved) {
|
|
45726
|
+
resolved = true
|
|
45727
|
+
resolve({ exitCode: 1, stdout, stderr: err.message || '' })
|
|
45728
|
+
}
|
|
45729
|
+
})
|
|
45730
|
+
|
|
45731
|
+
// Add timeout protection to prevent hanging
|
|
45732
|
+
const timeoutId = setTimeout(() => {
|
|
45733
|
+
if (!resolved) {
|
|
45734
|
+
resolved = true
|
|
45735
|
+
log(\`Command timeout: \${VIBORA_CMD} \${args.join(' ')}\`)
|
|
45736
|
+
child.kill('SIGTERM')
|
|
45737
|
+
// Schedule SIGKILL if process doesn't exit after SIGTERM
|
|
45738
|
+
killTimeoutId = setTimeout(() => {
|
|
45739
|
+
if (!processExited) {
|
|
45740
|
+
log(\`Process didn't exit after SIGTERM, sending SIGKILL\`)
|
|
45741
|
+
child.kill('SIGKILL')
|
|
45742
|
+
}
|
|
45743
|
+
}, 2000)
|
|
45744
|
+
resolve({ exitCode: -1, stdout, stderr: \`Command timed out after \${VIBORA_COMMAND_TIMEOUT_MS}ms\` })
|
|
45745
|
+
}
|
|
45746
|
+
}, VIBORA_COMMAND_TIMEOUT_MS)
|
|
45747
|
+
|
|
45748
|
+
// Clear timeout if command completes
|
|
45749
|
+
child.on('exit', () => clearTimeout(timeoutId))
|
|
45698
45750
|
})
|
|
45699
45751
|
}
|
|
45700
45752
|
|
|
@@ -45706,9 +45758,12 @@ let lastStatus: "in-progress" | "review" | "" = ""
|
|
|
45706
45758
|
|
|
45707
45759
|
const VIBORA_CMD = "vibora"
|
|
45708
45760
|
const IDLE_CONFIRMATION_DELAY_MS = 1500
|
|
45761
|
+
const VIBORA_COMMAND_TIMEOUT_MS = 10000
|
|
45762
|
+
const STATUS_CHANGE_DEBOUNCE_MS = 500
|
|
45709
45763
|
|
|
45710
45764
|
let deferredContextCheck: Promise<boolean> | null = null
|
|
45711
45765
|
let isViboraContext: boolean | null = null
|
|
45766
|
+
let pendingStatusCommand: Promise<{ exitCode: number; stdout: string; stderr: string }> | null = null
|
|
45712
45767
|
|
|
45713
45768
|
export const ViboraPlugin: Plugin = async ({ $, directory }) => {
|
|
45714
45769
|
log("Plugin initializing...")
|
|
@@ -45760,16 +45815,28 @@ export const ViboraPlugin: Plugin = async ({ $, directory }) => {
|
|
|
45760
45815
|
if (status === lastStatus) return
|
|
45761
45816
|
|
|
45762
45817
|
cancelPendingIdle()
|
|
45818
|
+
|
|
45819
|
+
if (pendingStatusCommand) {
|
|
45820
|
+
log(\`Status change already in progress, will retry after \${STATUS_CHANGE_DEBOUNCE_MS}ms\`)
|
|
45821
|
+
setTimeout(() => setStatus(status), STATUS_CHANGE_DEBOUNCE_MS)
|
|
45822
|
+
return
|
|
45823
|
+
}
|
|
45824
|
+
|
|
45763
45825
|
lastStatus = status
|
|
45826
|
+
|
|
45764
45827
|
;(async () => {
|
|
45765
45828
|
try {
|
|
45766
45829
|
log(\`Setting status: \${status}\`)
|
|
45767
|
-
|
|
45830
|
+
pendingStatusCommand = runViboraCommand(['current-task', status, '--path', directory])
|
|
45831
|
+
const res = await pendingStatusCommand
|
|
45832
|
+
pendingStatusCommand = null
|
|
45833
|
+
|
|
45768
45834
|
if (res.exitCode !== 0) {
|
|
45769
45835
|
log(\`Status update failed: exitCode=\${res.exitCode}, stderr=\${res.stderr}\`)
|
|
45770
45836
|
}
|
|
45771
45837
|
} catch (e) {
|
|
45772
45838
|
log(\`Status update error: \${e}\`)
|
|
45839
|
+
pendingStatusCommand = null
|
|
45773
45840
|
}
|
|
45774
45841
|
})()
|
|
45775
45842
|
}
|
package/package.json
CHANGED
package/server/index.js
CHANGED
|
@@ -4976,6 +4976,13 @@ function updateNotificationSettings(updates) {
|
|
|
4976
4976
|
const changes = {};
|
|
4977
4977
|
if (updates.enabled !== undefined && updates.enabled !== current.enabled) {
|
|
4978
4978
|
changes.enabled = { from: current.enabled, to: updates.enabled };
|
|
4979
|
+
if (updates.enabled === false) {
|
|
4980
|
+
log2.settings.warn("Notifications being DISABLED", {
|
|
4981
|
+
from: current.enabled,
|
|
4982
|
+
to: updates.enabled,
|
|
4983
|
+
stack: new Error().stack
|
|
4984
|
+
});
|
|
4985
|
+
}
|
|
4979
4986
|
}
|
|
4980
4987
|
if (updates.toast?.enabled !== undefined && updates.toast.enabled !== current.toast.enabled) {
|
|
4981
4988
|
changes["toast.enabled"] = { from: current.toast.enabled, to: updates.toast.enabled };
|
|
@@ -5127,6 +5134,7 @@ function ensureLatestSettings() {
|
|
|
5127
5134
|
parsed = JSON.parse(fs2.readFileSync(settingsPath, "utf-8"));
|
|
5128
5135
|
} catch {}
|
|
5129
5136
|
}
|
|
5137
|
+
const originalNotificationsEnabled = parsed.notifications?.enabled;
|
|
5130
5138
|
migrateSettings(parsed);
|
|
5131
5139
|
const merged = deepMergeWithDefaults(parsed, DEFAULT_SETTINGS);
|
|
5132
5140
|
if (!merged.notifications || typeof merged.notifications !== "object") {
|
|
@@ -5134,6 +5142,14 @@ function ensureLatestSettings() {
|
|
|
5134
5142
|
} else {
|
|
5135
5143
|
merged.notifications = deepMergeWithDefaults(merged.notifications, DEFAULT_NOTIFICATION_SETTINGS);
|
|
5136
5144
|
}
|
|
5145
|
+
const mergedNotificationsEnabled = merged.notifications?.enabled;
|
|
5146
|
+
if (originalNotificationsEnabled !== mergedNotificationsEnabled) {
|
|
5147
|
+
log2.settings.warn("Notification enabled state changed during settings normalization", {
|
|
5148
|
+
from: originalNotificationsEnabled,
|
|
5149
|
+
to: mergedNotificationsEnabled,
|
|
5150
|
+
reason: originalNotificationsEnabled === undefined ? "missing key, using default" : "value changed during merge"
|
|
5151
|
+
});
|
|
5152
|
+
}
|
|
5137
5153
|
if (!merged.zai || typeof merged.zai !== "object") {
|
|
5138
5154
|
merged.zai = { ...DEFAULT_ZAI_SETTINGS };
|
|
5139
5155
|
} else {
|