@aion0/forge 0.5.5 → 0.5.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.
package/RELEASE_NOTES.md CHANGED
@@ -1,18 +1,8 @@
1
- # Forge v0.5.5
1
+ # Forge v0.5.6
2
2
 
3
3
  Released: 2026-03-28
4
4
 
5
- ## Changes since v0.5.4
5
+ ## Changes since v0.5.5
6
6
 
7
- ### Features
8
- - feat: API token auth for Help AI — password-based, 24h validity
9
- - feat: enhanced agent role presets with detailed prompts + UI Designer
10
7
 
11
- ### Bug Fixes
12
- - fix: whitelist all /api/workspace routes in auth middleware
13
-
14
- ### Other
15
- - revert: restore auth middleware for /api/workspace security
16
-
17
-
18
- **Full Changelog**: https://github.com/aiwatching/forge/compare/v0.5.4...v0.5.5
8
+ **Full Changelog**: https://github.com/aiwatching/forge/compare/v0.5.5...v0.5.6
@@ -730,21 +730,47 @@ function RunPromptDialog({ agentLabel, onRun, onCancel }: {
730
730
 
731
731
  // ─── Log Panel (overlay) ─────────────────────────────────
732
732
 
733
- /** Format log content: handle \n, truncate long text, detect JSON */
734
- function LogContent({ content }: { content: string }) {
733
+ /** Format log content: extract readable text from JSON, format nicely */
734
+ function LogContent({ content, subtype }: { content: string; subtype?: string }) {
735
735
  if (!content) return null;
736
- const MAX_LINES = 30;
737
- const MAX_CHARS = 3000;
736
+ const MAX_LINES = 40;
737
+ const MAX_CHARS = 4000;
738
738
 
739
739
  let text = content;
740
740
 
741
- // Try to parse JSON and extract readable content
741
+ // Try to parse JSON and extract human-readable content
742
742
  if (text.startsWith('{') || text.startsWith('[')) {
743
743
  try {
744
744
  const parsed = JSON.parse(text);
745
- // Tool result with content field
746
- if (parsed.content) text = String(parsed.content);
747
- else text = JSON.stringify(parsed, null, 2);
745
+ if (typeof parsed === 'string') {
746
+ text = parsed;
747
+ } else if (parsed.content) {
748
+ text = String(parsed.content);
749
+ } else if (parsed.text) {
750
+ text = String(parsed.text);
751
+ } else if (parsed.result) {
752
+ text = typeof parsed.result === 'string' ? parsed.result : JSON.stringify(parsed.result, null, 2);
753
+ } else if (parsed.message?.content) {
754
+ // Claude stream-json format
755
+ const blocks = Array.isArray(parsed.message.content) ? parsed.message.content : [parsed.message.content];
756
+ text = blocks.map((b: any) => {
757
+ if (typeof b === 'string') return b;
758
+ if (b.type === 'text') return b.text;
759
+ if (b.type === 'tool_use') return `🔧 ${b.name}(${typeof b.input === 'string' ? b.input : JSON.stringify(b.input).slice(0, 100)})`;
760
+ if (b.type === 'tool_result') return `→ ${typeof b.content === 'string' ? b.content.slice(0, 200) : JSON.stringify(b.content).slice(0, 200)}`;
761
+ return JSON.stringify(b).slice(0, 100);
762
+ }).join('\n');
763
+ } else if (Array.isArray(parsed)) {
764
+ text = parsed.map((item: any) => typeof item === 'string' ? item : JSON.stringify(item)).join('\n');
765
+ } else {
766
+ // Generic object — show key fields only
767
+ const keys = Object.keys(parsed);
768
+ if (keys.length <= 5) {
769
+ text = keys.map(k => `${k}: ${typeof parsed[k] === 'string' ? parsed[k] : JSON.stringify(parsed[k]).slice(0, 80)}`).join('\n');
770
+ } else {
771
+ text = JSON.stringify(parsed, null, 2);
772
+ }
773
+ }
748
774
  } catch {
749
775
  // Not valid JSON, keep as-is
750
776
  }
@@ -843,8 +869,14 @@ function LogPanel({ agentId, agentLabel, workspaceId, onClose }: {
843
869
  ) : (
844
870
  <>
845
871
  <span className="text-[8px] text-gray-600 shrink-0 w-16">{entry.timestamp ? new Date(entry.timestamp).toLocaleTimeString() : ''}</span>
846
- {entry.tool && <span className="text-yellow-500 shrink-0">[{entry.tool}]</span>}
847
- <LogContent content={entry.content} />
872
+ {entry.subtype === 'tool_use' && <span className="text-yellow-500 shrink-0">🔧 {entry.tool || 'tool'}</span>}
873
+ {entry.subtype === 'tool_result' && <span className="text-cyan-500 shrink-0">→</span>}
874
+ {entry.subtype === 'init' && <span className="text-blue-400 shrink-0">⚡</span>}
875
+ {entry.subtype === 'daemon' && <span className="text-purple-400 shrink-0">👁</span>}
876
+ {entry.subtype === 'watch_detected' && <span className="text-orange-400 shrink-0">🔍</span>}
877
+ {entry.subtype === 'error' && <span className="text-red-400 shrink-0">❌</span>}
878
+ {!entry.tool && entry.subtype === 'text' && <span className="text-gray-500 shrink-0">💬</span>}
879
+ <LogContent content={entry.content} subtype={entry.subtype} />
848
880
  </>
849
881
  )}
850
882
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aion0/forge",
3
- "version": "0.5.5",
3
+ "version": "0.5.6",
4
4
  "description": "Unified AI workflow platform — multi-model task orchestration, persistent sessions, web terminal, remote access",
5
5
  "type": "module",
6
6
  "scripts": {