vibeostheog 0.23.42 → 0.23.43
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/CHANGELOG.md +4 -0
- package/package.json +1 -1
- package/src/lib/hooks/footer.js +44 -37
- package/src/lib/hooks/tool-execute.js +33 -23
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibeostheog",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.43",
|
|
4
4
|
"description": "Cost-aware delegation enforcer for OpenCode. Tracks model usage, routes Task subagents to cheaper tiers, surfaces cumulative savings in chat. Includes research audit, reporting framework, project memory, progressive scratchpad decadence, and trinity CLI for brain/medium/cheap slot switching.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"release": "node scripts/release.mjs",
|
package/src/lib/hooks/footer.js
CHANGED
|
@@ -168,21 +168,27 @@ async function _appendFooter(input, output, directory) {
|
|
|
168
168
|
output?.messageId ||
|
|
169
169
|
output?.message?.id ||
|
|
170
170
|
null;
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
171
|
+
if (messageID && textCompletePainted.has(messageID))
|
|
172
|
+
return;
|
|
173
|
+
function _payload(obj) {
|
|
174
|
+
if (obj?.message && typeof obj.message === "object")
|
|
175
|
+
return obj.message;
|
|
176
|
+
return obj;
|
|
177
|
+
}
|
|
178
|
+
function _extractText(obj) {
|
|
179
|
+
const payload = _payload(obj);
|
|
180
|
+
if (typeof payload?.text === "string")
|
|
181
|
+
return payload.text;
|
|
182
|
+
if (typeof payload?.result === "string")
|
|
183
|
+
return payload.result;
|
|
184
|
+
if (typeof payload?.content === "string")
|
|
185
|
+
return payload.content;
|
|
186
|
+
if (Array.isArray(payload?.content))
|
|
187
|
+
return payload.content.filter(p => p?.type === "text").map(p => p.text).filter(Boolean).join("\n");
|
|
188
|
+
if (Array.isArray(payload?.parts))
|
|
189
|
+
return payload.parts.filter(p => p?.type === "text").map(p => p.text).filter(Boolean).join("\n");
|
|
190
|
+
return "";
|
|
191
|
+
}
|
|
186
192
|
const text = _extractText(output);
|
|
187
193
|
if (!text)
|
|
188
194
|
return;
|
|
@@ -330,31 +336,32 @@ async function _appendFooter(input, output, directory) {
|
|
|
330
336
|
}
|
|
331
337
|
}
|
|
332
338
|
catch { }
|
|
339
|
+
}
|
|
340
|
+
function _setFooter(obj, text) {
|
|
341
|
+
const target = _payload(obj);
|
|
342
|
+
if (typeof target?.text === "string")
|
|
343
|
+
target.text = text;
|
|
344
|
+
else if (typeof target?.result === "string")
|
|
345
|
+
target.result = text;
|
|
346
|
+
else if (typeof target?.content === "string")
|
|
347
|
+
target.content = text;
|
|
348
|
+
else if (Array.isArray(target?.content)) {
|
|
349
|
+
const textParts = target.content.filter(p => p?.type === "text");
|
|
350
|
+
if (textParts.length > 0)
|
|
351
|
+
textParts[textParts.length - 1].text = text;
|
|
352
|
+
else
|
|
353
|
+
target.content.push({ type: "text", text });
|
|
333
354
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
obj.result = text;
|
|
339
|
-
else if (typeof obj?.content === "string")
|
|
340
|
-
obj.content = text;
|
|
341
|
-
else if (Array.isArray(obj?.content)) {
|
|
342
|
-
const textParts = obj.content.filter(p => p?.type === "text");
|
|
343
|
-
if (textParts.length > 0)
|
|
344
|
-
textParts[textParts.length - 1].text = text;
|
|
345
|
-
else
|
|
346
|
-
obj.content.push({ type: "text", text });
|
|
347
|
-
}
|
|
348
|
-
else if (Array.isArray(obj?.parts)) {
|
|
349
|
-
const textParts = obj.parts.filter(p => p?.type === "text");
|
|
350
|
-
if (textParts.length > 0)
|
|
351
|
-
textParts[textParts.length - 1].text = text;
|
|
352
|
-
else
|
|
353
|
-
obj.parts.push({ type: "text", text });
|
|
354
|
-
}
|
|
355
|
+
else if (Array.isArray(target?.parts)) {
|
|
356
|
+
const textParts = target.parts.filter(p => p?.type === "text");
|
|
357
|
+
if (textParts.length > 0)
|
|
358
|
+
textParts[textParts.length - 1].text = text;
|
|
355
359
|
else
|
|
356
|
-
|
|
360
|
+
target.parts.push({ type: "text", text });
|
|
357
361
|
}
|
|
362
|
+
else
|
|
363
|
+
target.text = text;
|
|
364
|
+
}
|
|
358
365
|
_setFooter(output, footerText);
|
|
359
366
|
_lastStrippedText = stripped;
|
|
360
367
|
// CLI/pipe mode: stdout is already rendered, write footer to stderr
|
|
@@ -750,17 +750,21 @@ export const onToolExecuteAfter = async (input, output) => {
|
|
|
750
750
|
_footerText += ` | $${formatUsd(ltTotal)}`;
|
|
751
751
|
}
|
|
752
752
|
_footerText += ` | ${vibeBrand}${flashIcon} —\n\n`;
|
|
753
|
+
const footerTarget = _payload(output);
|
|
753
754
|
output.title = _footerText.trim();
|
|
754
|
-
if (
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
755
|
+
if (footerTarget !== output && footerTarget && typeof footerTarget === "object") {
|
|
756
|
+
footerTarget.title = _footerText.trim();
|
|
757
|
+
}
|
|
758
|
+
if (typeof footerTarget?.output === "string")
|
|
759
|
+
footerTarget.output = _footerText + footerTarget.output;
|
|
760
|
+
else if (typeof footerTarget?.result === "string")
|
|
761
|
+
footerTarget.result = _footerText + footerTarget.result;
|
|
762
|
+
else if (typeof footerTarget?.text === "string")
|
|
763
|
+
footerTarget.text = _footerText + footerTarget.text;
|
|
764
|
+
else if (typeof footerTarget?.content === "string")
|
|
765
|
+
footerTarget.content = _footerText + footerTarget.content;
|
|
762
766
|
else
|
|
763
|
-
|
|
767
|
+
footerTarget.output = _footerText;
|
|
764
768
|
_autoReportCount = (_autoReportCount || 0) + 1;
|
|
765
769
|
if (_autoReportCount % 5 === 0 && ltTotal > 0) {
|
|
766
770
|
saveReport({
|
|
@@ -847,30 +851,36 @@ export const onToolExecuteAfter = async (input, output) => {
|
|
|
847
851
|
return s;
|
|
848
852
|
});
|
|
849
853
|
}
|
|
854
|
+
function _payload(obj) {
|
|
855
|
+
if (obj?.message && typeof obj.message === "object")
|
|
856
|
+
return obj.message;
|
|
857
|
+
return obj;
|
|
858
|
+
}
|
|
850
859
|
// Inject pending delegation UI note (set in tool.execute.before).
|
|
851
860
|
// This surfaces the warning in the OC chat transcript, not just stderr.
|
|
852
861
|
if (pendingUiNote) {
|
|
862
|
+
const target = _payload(output);
|
|
853
863
|
if (enforcementBlocked) {
|
|
854
864
|
const note = `[vibeOS] ${pendingUiNote}`;
|
|
855
|
-
if (typeof
|
|
856
|
-
|
|
857
|
-
else if (typeof
|
|
858
|
-
|
|
859
|
-
else if (typeof
|
|
860
|
-
|
|
865
|
+
if (typeof target?.result === "string")
|
|
866
|
+
target.result += `\n\n${note}`;
|
|
867
|
+
else if (typeof target?.text === "string")
|
|
868
|
+
target.text += `\n\n${note}`;
|
|
869
|
+
else if (typeof target?.content === "string")
|
|
870
|
+
target.content += `\n\n${note}`;
|
|
861
871
|
else
|
|
862
|
-
|
|
872
|
+
target.result = pendingUiNote;
|
|
863
873
|
}
|
|
864
874
|
else {
|
|
865
875
|
const note = `\n\n${pendingUiNote}`;
|
|
866
|
-
if (typeof
|
|
867
|
-
|
|
868
|
-
else if (typeof
|
|
869
|
-
|
|
870
|
-
else if (typeof
|
|
871
|
-
|
|
876
|
+
if (typeof target?.result === "string")
|
|
877
|
+
target.result += note;
|
|
878
|
+
else if (typeof target?.text === "string")
|
|
879
|
+
target.text += note;
|
|
880
|
+
else if (typeof target?.content === "string")
|
|
881
|
+
target.content += note;
|
|
872
882
|
else
|
|
873
|
-
|
|
883
|
+
target.result = pendingUiNote;
|
|
874
884
|
}
|
|
875
885
|
pendingUiNote = null;
|
|
876
886
|
}
|