pinokiod 7.3.1 → 7.3.3

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 (122) hide show
  1. package/kernel/api/github/index.js +444 -0
  2. package/kernel/api/index.js +199 -11
  3. package/kernel/api/process/index.js +124 -44
  4. package/kernel/api/shell_run_template.js +273 -0
  5. package/kernel/api/uri/index.js +51 -0
  6. package/kernel/bin/git.js +9 -10
  7. package/kernel/bin/huggingface.js +1 -1
  8. package/kernel/bin/zip.js +9 -1
  9. package/kernel/connect/providers/github/README.md +5 -4
  10. package/kernel/environment.js +195 -92
  11. package/kernel/git.js +98 -19
  12. package/kernel/gitconfig_template +7 -0
  13. package/kernel/gpu/amd.js +72 -0
  14. package/kernel/gpu/apple.js +8 -0
  15. package/kernel/gpu/common.js +12 -0
  16. package/kernel/gpu/intel.js +47 -0
  17. package/kernel/gpu/nvidia.js +8 -0
  18. package/kernel/index.js +11 -1
  19. package/kernel/managed_skills.js +871 -0
  20. package/kernel/plugin.js +6 -58
  21. package/kernel/plugin_sources.js +316 -0
  22. package/kernel/resource_usage/gpu.js +349 -0
  23. package/kernel/resource_usage/index.js +322 -0
  24. package/kernel/resource_usage/macos_footprint.js +197 -0
  25. package/kernel/resource_usage/preferences.js +92 -0
  26. package/kernel/resource_usage/process_tree.js +303 -0
  27. package/kernel/scripts/git/create +4 -4
  28. package/kernel/scripts/git/fork +7 -8
  29. package/kernel/shell.js +23 -2
  30. package/kernel/shells.js +41 -0
  31. package/kernel/sysinfo.js +62 -9
  32. package/kernel/util.js +60 -0
  33. package/package.json +1 -1
  34. package/server/index.js +984 -156
  35. package/server/lib/app_log_report.js +543 -0
  36. package/server/lib/content_validation.js +55 -33
  37. package/server/lib/launcher_instruction_bootstrap.js +4 -96
  38. package/server/lib/terminal_session_helpers.js +0 -3
  39. package/server/public/common.js +77 -31
  40. package/server/public/create-launcher.js +4 -32
  41. package/server/public/logs.js +1428 -0
  42. package/server/public/nav.js +7 -0
  43. package/server/public/plugin-detail.js +93 -10
  44. package/server/public/privacy_filter_worker.js +391 -0
  45. package/server/public/style.css +1104 -154
  46. package/server/public/task-launcher.js +8 -29
  47. package/server/public/universal-launcher.css +8 -6
  48. package/server/public/universal-launcher.js +3 -27
  49. package/server/routes/apps.js +195 -1
  50. package/server/views/app.ejs +3041 -717
  51. package/server/views/autolaunch.ejs +917 -0
  52. package/server/views/bootstrap.ejs +7 -1
  53. package/server/views/d.ejs +408 -65
  54. package/server/views/editor.ejs +85 -19
  55. package/server/views/index.ejs +661 -111
  56. package/server/views/init/index.ejs +1 -1
  57. package/server/views/install.ejs +1 -1
  58. package/server/views/logs.ejs +164 -86
  59. package/server/views/net.ejs +7 -1
  60. package/server/views/partials/d_terminal_column.ejs +2 -2
  61. package/server/views/partials/d_terminal_options.ejs +0 -8
  62. package/server/views/partials/fs_status.ejs +47 -0
  63. package/server/views/partials/home_action_modal.ejs +86 -0
  64. package/server/views/partials/home_run_menu.ejs +87 -0
  65. package/server/views/partials/main_sidebar.ejs +2 -0
  66. package/server/views/partials/menu.ejs +1 -1
  67. package/server/views/plugin_detail.ejs +19 -4
  68. package/server/views/plugins.ejs +201 -3
  69. package/server/views/pre.ejs +1 -1
  70. package/server/views/pro.ejs +1 -1
  71. package/server/views/shell.ejs +40 -18
  72. package/server/views/skills.ejs +506 -0
  73. package/server/views/terminal.ejs +45 -19
  74. package/spec/INSTRUCTION_SYNC.md +20 -10
  75. package/system/plugin/antigravity-cli/antigravity.png +0 -0
  76. package/system/plugin/antigravity-cli/common.js +155 -0
  77. package/system/plugin/antigravity-cli/install.js +272 -0
  78. package/system/plugin/antigravity-cli/pinokio.js +13 -0
  79. package/system/plugin/antigravity-cli-auto/antigravity.png +0 -0
  80. package/system/plugin/antigravity-cli-auto/pinokio.js +13 -0
  81. package/system/plugin/claude/claude.png +0 -0
  82. package/system/plugin/claude/pinokio.js +47 -0
  83. package/system/plugin/claude-auto/claude.png +0 -0
  84. package/system/plugin/claude-auto/pinokio.js +58 -0
  85. package/system/plugin/claude-desktop/icon.jpeg +0 -0
  86. package/system/plugin/claude-desktop/pinokio.js +23 -0
  87. package/system/plugin/codex/openai.webp +0 -0
  88. package/system/plugin/codex/pinokio.js +42 -0
  89. package/system/plugin/codex-auto/openai.webp +0 -0
  90. package/system/plugin/codex-auto/pinokio.js +49 -0
  91. package/system/plugin/codex-desktop/icon.png +0 -0
  92. package/system/plugin/codex-desktop/pinokio.js +23 -0
  93. package/system/plugin/crush/crush.png +0 -0
  94. package/system/plugin/crush/pinokio.js +15 -0
  95. package/system/plugin/cursor/cursor.jpeg +0 -0
  96. package/system/plugin/cursor/pinokio.js +23 -0
  97. package/system/plugin/qwen/pinokio.js +34 -0
  98. package/system/plugin/qwen/qwen.png +0 -0
  99. package/system/plugin/vscode/pinokio.js +20 -0
  100. package/system/plugin/vscode/vscode.png +0 -0
  101. package/system/plugin/windsurf/pinokio.js +23 -0
  102. package/system/plugin/windsurf/windsurf.png +0 -0
  103. package/test/antigravity-cli-plugin.test.js +185 -0
  104. package/test/app-api.test.js +239 -0
  105. package/test/app-log-report.test.js +67 -0
  106. package/test/environment-cache-preflight.test.js +98 -0
  107. package/test/git-bin.test.js +59 -0
  108. package/test/git-defaults.test.js +97 -0
  109. package/test/github-api.test.js +158 -0
  110. package/test/github-connection.test.js +117 -0
  111. package/test/huggingface-bin.test.js +25 -0
  112. package/test/managed-skills.test.js +351 -0
  113. package/test/plugin-action-functions.test.js +337 -0
  114. package/test/plugin-dev-iframe.test.js +17 -0
  115. package/test/plugin-sources.test.js +203 -0
  116. package/test/privacy-filter-worker-heuristics.test.js +69 -0
  117. package/test/process-wait.test.js +169 -0
  118. package/test/script-api.test.js +97 -0
  119. package/test/shell-api.test.js +134 -0
  120. package/test/shell-run-template.test.js +209 -0
  121. package/test/storage-api.test.js +137 -0
  122. package/test/uri-api.test.js +100 -0
@@ -2663,7 +2663,7 @@ const createTerm = async (_theme) => {
2663
2663
  term.loadAddon(fitAddon);
2664
2664
  <% if (agent === "electron") { %>
2665
2665
  term.loadAddon(new WebLinksAddon.WebLinksAddon((event, uri) => {
2666
- window.open(uri, "_blank")
2666
+ window.open(uri, "_blank", "browser")
2667
2667
  }))
2668
2668
  <% } else { %>
2669
2669
  term.loadAddon(new WebLinksAddon.WebLinksAddon());
@@ -698,7 +698,7 @@ const createTerm = async (_theme) => {
698
698
  term.loadAddon(fitAddon);
699
699
  <% if (agent === "electron") { %>
700
700
  term.loadAddon(new WebLinksAddon.WebLinksAddon((event, uri) => {
701
- window.open(uri, "_blank")
701
+ window.open(uri, "_blank", "browser")
702
702
  }))
703
703
  <% } else { %>
704
704
  term.loadAddon(new WebLinksAddon.WebLinksAddon());
@@ -32,103 +32,181 @@
32
32
  <script src="/nav.js"></script>
33
33
  <script src="/report.js"></script>
34
34
  </head>
35
- <body class='<%=theme%>' data-agent="<%=agent%>">
36
- <header class='navheader grabbable'>
37
- <h1>
38
- <a class='home' href="/home"><img class='icon' src="/pinokio-black.png"></a>
39
- <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
40
- <div><i class="fa-solid fa-expand"></i></div>
41
- </button>
42
- <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
43
- <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
44
- <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
45
- <button class='btn2' id='screenshot' data-tippy-content="screen capture"><i class="fa-solid fa-camera"></i></button>
46
- <button class='btn2' id='inspector' data-tippy-content="X-ray mode"><i class="fa-solid fa-eye"></i></button>
47
- <div class='mobile-flexible'></div>
48
- <a class='btn2' href="/columns" data-tippy-content="split into 2 columns">
49
- <div><i class="fa-solid fa-table-columns"></i></div>
50
- </a>
51
- <a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
52
- <div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
53
- </a>
54
- <button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
55
- <div><i class="fa-solid fa-plus"></i></div>
56
- </button>
57
- <button class='btn2 hidden' id='close-window' data-tippy-content='close this section'>
58
- <div><i class="fa-solid fa-xmark"></i></div>
59
- </button>
60
- </h1>
61
- </header>
35
+ <body class='<%=theme%> <%= logsEmbedded ? "logs-embedded" : "" %>' data-agent="<%=agent%>">
36
+ <% if (!logsEmbedded) { %>
37
+ <header class='navheader grabbable'>
38
+ <h1>
39
+ <a class='home' href="/home"><img class='icon' src="/pinokio-black.png"></a>
40
+ <button class='btn2' id='minimize-header' data-tippy-content="fullscreen" title='fullscreen'>
41
+ <div><i class="fa-solid fa-expand"></i></div>
42
+ </button>
43
+ <button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
44
+ <button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
45
+ <button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
46
+ <button class='btn2' id='screenshot' data-tippy-content="screen capture"><i class="fa-solid fa-camera"></i></button>
47
+ <button class='btn2' id='inspector' data-tippy-content="X-ray mode"><i class="fa-solid fa-eye"></i></button>
48
+ <div class='mobile-flexible'></div>
49
+ <a class='btn2' href="/columns" data-tippy-content="split into 2 columns">
50
+ <div><i class="fa-solid fa-table-columns"></i></div>
51
+ </a>
52
+ <a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
53
+ <div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
54
+ </a>
55
+ <button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
56
+ <div><i class="fa-solid fa-plus"></i></div>
57
+ </button>
58
+ <button class='btn2 hidden' id='close-window' data-tippy-content='close this section'>
59
+ <div><i class="fa-solid fa-xmark"></i></div>
60
+ </button>
61
+ </h1>
62
+ </header>
63
+ <% } %>
62
64
  <main>
63
65
  <div class='container'>
64
66
  <% if (!logsError) { %>
65
- <section class="logs-page" id="logs-root" data-workspace="<%= logsWorkspace ? logsWorkspace : '' %>">
66
- <div class="logs-sidebar" aria-label="Log folders">
67
- <div class="logs-sidebar-header">
68
- <div>
69
- <p class="logs-sidebar-eyebrow">Logs directory</p>
70
- <h2>Logs</h2>
71
- <% if (logsTitle) { %>
72
- <div class="logs-workspace-chip" title="<%= logsTitle %>">
73
- <i class="fa-solid fa-box"></i>
74
- <span><%= logsTitle %></span>
75
- </div>
76
- <% } %>
67
+ <section class="logs-page" id="logs-root" data-workspace="<%= logsWorkspace ? logsWorkspace : '' %>" data-report-url="<%= logsReportUrl || '' %>" data-initial-view="<%= logsInitialView || 'raw' %>">
68
+ <div class="logs-page-header">
69
+ <div class="logs-page-switch">
70
+ <% if (logsReportUrl) { %>
71
+ <div class="logs-view-switch" role="tablist" aria-label="Log views">
72
+ <button type="button" class="logs-view-tab" data-logs-view="latest" role="tab" aria-controls="logs-latest-panel">Latest</button>
73
+ <button type="button" class="logs-view-tab" data-logs-view="raw" role="tab" aria-controls="logs-raw-panel">Raw logs</button>
74
+ </div>
75
+ <% } else { %>
76
+ <div class="logs-raw-only-title"><i class="fa-solid fa-laptop-code" aria-hidden="true"></i><span>Logs</span></div>
77
+ <% } %>
78
+ </div>
79
+ <div class="logs-page-controls">
80
+ <div class="logs-action-group" data-logs-actions="latest">
81
+ <button type="button" class="logs-flat-button" id="logs-copy-report" disabled><i class="fa-solid fa-copy"></i><span>Copy</span></button>
82
+ <button type="button" class="logs-flat-button" id="logs-refresh-report"><i class="fa-solid fa-arrows-rotate"></i><span>Refresh</span></button>
77
83
  </div>
78
- <div class="logs-root-path" title="<%= logsRootDisplay %>">
79
- <i class="fa-solid fa-folder-tree"></i>
80
- <span><%= logsRootDisplay %></span>
84
+ <div class="logs-action-group" data-logs-actions="raw">
85
+ <button type="button" class="logs-primary-button" id="logs-generate-archive"><i class="fa-solid fa-file-zipper"></i><span>Generate zip</span></button>
86
+ <a id="logs-download-archive" class="logs-secondary-button hidden" href="<%= typeof logsDownloadUrl !== 'undefined' ? logsDownloadUrl : '/pinokio/logs.zip' %>" download><i class="fa-solid fa-download"></i><span>Download</span></a>
87
+ <button type="button" class="logs-flat-button" id="logs-refresh-tree"><i class="fa-solid fa-arrows-rotate"></i><span>Refresh tree</span></button>
81
88
  </div>
82
- </div>
83
- <div class="logs-zip-actions">
84
- <button type="button" class="logs-primary-button" id="logs-generate-archive">
85
- <i class="fa-solid fa-file-zipper"></i>
86
- <span>Generate a zip archive</span>
87
- </button>
88
- <a id="logs-download-archive" class="logs-secondary-button hidden" href="<%= typeof logsDownloadUrl !== 'undefined' ? logsDownloadUrl : '/pinokio/logs.zip' %>" download>
89
- <i class="fa-solid fa-download"></i>
90
- <span>Download latest archive</span>
91
- </a>
92
- <div class="logs-zip-status" id="logs-zip-status" role="status" aria-live="polite"></div>
93
- </div>
94
- <div class="logs-tree-toolbar">
95
- <button type="button" class="logs-flat-button" id="logs-refresh-tree">
96
- <i class="fa-solid fa-arrows-rotate"></i>
97
- <span>Refresh tree</span>
98
- </button>
99
- <p class="logs-tree-hint">Streaming works for every file inside this folder.</p>
100
- </div>
101
- <div class="logs-tree-wrapper">
102
- <div class="logs-tree" id="logs-tree" role="tree" aria-label="Pinokio logs"></div>
89
+ <% if (logsEmbedded) { %>
90
+ <button type="button" class="logs-icon-button logs-close-button" id="logs-close-view" aria-label="Close logs" title="Close logs"><i class="fa-solid fa-xmark"></i></button>
91
+ <% } %>
103
92
  </div>
104
93
  </div>
105
- <div class="logs-resizer" id="logs-resizer" role="separator" aria-orientation="vertical" aria-valuemin="220" aria-valuemax="560" aria-valuenow="320" tabindex="0" aria-label="Resize or collapse log navigation">
106
- <button type="button" class="logs-resizer-toggle" aria-label="Collapse log navigation">
107
- <i class="fa-solid fa-chevron-left" aria-hidden="true"></i>
108
- </button>
109
- </div>
110
- <div class="logs-main" aria-live="polite">
111
- <div class="logs-viewer-panel">
112
- <div class="logs-viewer-header">
94
+
95
+ <section class="logs-latest-view" id="logs-latest-panel" data-logs-panel="latest" role="tabpanel">
96
+ <div class="logs-latest-workspace">
97
+ <section class="logs-report-pane" aria-label="Issue report preview">
98
+ <div class="logs-latest-pane-header">
99
+ <div>
100
+ <p class="logs-latest-pane-eyebrow">Report preview</p>
101
+ <div class="logs-latest-pane-title">Markdown draft</div>
102
+ </div>
103
+ </div>
104
+ <pre class="logs-report-output" id="logs-report-output" tabindex="0"></pre>
105
+ </section>
106
+ <aside class="logs-redaction-pane" aria-label="Report details and redaction review">
107
+ <div class="logs-latest-pane-header">
108
+ <div>
109
+ <p class="logs-latest-pane-eyebrow">Review</p>
110
+ <div class="logs-latest-pane-title">Before copy</div>
111
+ </div>
112
+ </div>
113
+ <div class="logs-review-content">
114
+ <section class="logs-review-section" aria-label="Latest report details">
115
+ <div class="logs-review-section-title">Snapshot</div>
116
+ <div class="logs-review-meta">
117
+ <div>
118
+ <span>Generated</span>
119
+ <strong id="logs-report-generated">--</strong>
120
+ </div>
121
+ <div>
122
+ <span>Sections</span>
123
+ <strong id="logs-report-sections">--</strong>
124
+ </div>
125
+ </div>
126
+ <div class="logs-review-file-list" id="logs-report-files" aria-label="Included log files"></div>
127
+ </section>
128
+ <section class="logs-review-section" aria-label="Registry draft size">
129
+ <div class="logs-review-section-row">
130
+ <div class="logs-review-section-title">Registry draft</div>
131
+ <div class="logs-review-badge" id="logs-draft-size-badge">--</div>
132
+ </div>
133
+ <div class="logs-draft-meter" aria-hidden="true">
134
+ <div class="logs-draft-meter-fill" id="logs-draft-meter-fill"></div>
135
+ </div>
136
+ <div class="logs-draft-status" id="logs-draft-status">Waiting for latest log snapshot.</div>
137
+ </section>
138
+ <section class="logs-review-section" aria-label="Privacy filter status">
139
+ <div class="logs-review-section-row">
140
+ <div class="logs-review-section-title">Privacy filter</div>
141
+ <div class="logs-review-badge" id="logs-redaction-count">Not run</div>
142
+ </div>
143
+ <div class="logs-report-status" id="logs-report-status" role="status" aria-live="polite">Building latest log snapshot…</div>
144
+ <button type="button" class="logs-primary-button logs-review-filter-button" id="logs-run-filter" disabled><i class="fa-solid fa-shield-halved"></i><span>Run privacy filter</span></button>
145
+ </section>
146
+ <section class="logs-review-section logs-review-section--redactions" aria-label="Redaction review">
147
+ <div class="logs-review-section-title">Redactions</div>
148
+ <div class="logs-redaction-filters" id="logs-redaction-filters" aria-label="Filter redactions"></div>
149
+ <div class="logs-redaction-list" id="logs-redaction-list"></div>
150
+ </section>
151
+ </div>
152
+ </aside>
153
+ <footer class="logs-community-footer" aria-label="Ask Community">
154
+ <div class="logs-community-copy">
155
+ <div class="logs-community-heading"><i class="fa-solid fa-comments" aria-hidden="true"></i><span>Ask Community</span></div>
156
+ <div class="logs-community-subtitle">Opens a draft question on pinokio.co with this report attached.</div>
157
+ </div>
158
+ <div class="logs-community-title-field">
159
+ <label class="logs-community-title-label" for="logs-draft-title">Title</label>
160
+ <input class="logs-community-title-input" id="logs-draft-title" type="text" maxlength="120" autocomplete="off" spellcheck="true" placeholder="Issue title" disabled>
161
+ <span class="logs-community-title-note" id="logs-draft-title-note" aria-live="polite"></span>
162
+ </div>
163
+ <button type="button" class="logs-primary-button logs-community-submit" id="logs-create-draft" disabled><i class="fa-solid fa-paper-plane"></i><span>Ask Community</span></button>
164
+ </footer>
165
+ </div>
166
+ </section>
167
+
168
+ <section class="logs-raw-view" id="logs-raw-panel" data-logs-panel="raw" role="tabpanel">
169
+ <div class="logs-sidebar" aria-label="Log folders">
170
+ <div class="logs-sidebar-header">
113
171
  <div>
114
- <p class="logs-viewer-eyebrow">Live log viewer</p>
115
- <div class="logs-viewer-path" id="logs-viewer-path">Select a log file to start streaming.</div>
172
+ <p class="logs-sidebar-eyebrow">Raw log files</p>
173
+ <h2>Files</h2>
174
+ <div class="logs-tree-hint">Select a file to stream live output.</div>
116
175
  </div>
117
- <div class="logs-viewer-controls">
118
- <label class="logs-autoscroll-toggle">
119
- <input type="checkbox" id="logs-autoscroll" checked>
120
- <span>Auto-scroll</span>
121
- </label>
122
- <button type="button" class="logs-flat-button" id="logs-clear-viewer" disabled>
123
- <i class="fa-solid fa-eraser"></i>
124
- <span>Clear</span>
125
- </button>
176
+ <div class="logs-zip-status" id="logs-zip-status" role="status" aria-live="polite"></div>
177
+ </div>
178
+ <div class="logs-tree-wrapper">
179
+ <div class="logs-tree" id="logs-tree" role="tree" aria-label="Pinokio logs"></div>
180
+ </div>
181
+ </div>
182
+ <div class="logs-resizer" id="logs-resizer" role="separator" aria-orientation="vertical" aria-valuemin="220" aria-valuemax="560" aria-valuenow="320" tabindex="0" aria-label="Resize or collapse log navigation">
183
+ <button type="button" class="logs-resizer-toggle" aria-label="Collapse log navigation">
184
+ <i class="fa-solid fa-chevron-left" aria-hidden="true"></i>
185
+ </button>
186
+ </div>
187
+ <div class="logs-main" aria-live="polite">
188
+ <div class="logs-viewer-panel">
189
+ <div class="logs-viewer-header">
190
+ <div>
191
+ <p class="logs-viewer-eyebrow">Raw logs</p>
192
+ <div class="logs-viewer-path" id="logs-viewer-path">Select a log file to start streaming.</div>
193
+ </div>
194
+ <div class="logs-viewer-controls">
195
+ <label class="logs-autoscroll-toggle">
196
+ <input type="checkbox" id="logs-autoscroll" checked>
197
+ <span>Auto-scroll</span>
198
+ </label>
199
+ <button type="button" class="logs-flat-button" id="logs-clear-viewer" disabled>
200
+ <i class="fa-solid fa-eraser"></i>
201
+ <span>Clear</span>
202
+ </button>
203
+ </div>
126
204
  </div>
205
+ <div class="logs-viewer-status" id="logs-viewer-status">Waiting for selection…</div>
206
+ <pre class="logs-viewer-output" id="logs-viewer-output" role="log" aria-live="polite" tabindex="0"></pre>
127
207
  </div>
128
- <div class="logs-viewer-status" id="logs-viewer-status">Waiting for selection…</div>
129
- <pre class="logs-viewer-output" id="logs-viewer-output" role="log" aria-live="polite" tabindex="0"></pre>
130
208
  </div>
131
- </div>
209
+ </section>
132
210
  </section>
133
211
  <% } else { %>
134
212
  <section class="logs-page logs-page--error" id="logs-root-error">
@@ -148,7 +226,7 @@
148
226
  </div>
149
227
  </main>
150
228
  <script>
151
- window.LOGS_PAGE_DATA = <%- JSON.stringify({ rootDisplay: logsRootDisplay || '', downloadUrl: logsDownloadUrl || '/pinokio/logs.zip', workspace: logsWorkspace || '', workspaceTitle: logsTitle || '' }) %>
229
+ window.LOGS_PAGE_DATA = <%- JSON.stringify({ rootDisplay: logsRootDisplay || '', downloadUrl: logsDownloadUrl || '/pinokio/logs.zip', workspace: logsWorkspace || '', workspaceTitle: logsTitle || '', reportUrl: logsReportUrl || '', draftUrl: typeof logsDraftUrl !== 'undefined' ? logsDraftUrl : '', registryBase: 'https://pinokio.co', initialView: logsInitialView || 'raw', embedded: !!logsEmbedded }) %>
152
230
  </script>
153
231
  <script src="/logs.js"></script>
154
232
  </body>
@@ -1545,7 +1545,13 @@ const createDnsTerminal = async (container) => {
1545
1545
  const fitAddon = new FitAddon.FitAddon()
1546
1546
  term.loadAddon(fitAddon)
1547
1547
  if (typeof WebLinksAddon !== 'undefined' && WebLinksAddon.WebLinksAddon) {
1548
- term.loadAddon(new WebLinksAddon.WebLinksAddon())
1548
+ <% if (agent === "electron") { %>
1549
+ term.loadAddon(new WebLinksAddon.WebLinksAddon((event, uri) => {
1550
+ window.open(uri, "_blank", "browser")
1551
+ }))
1552
+ <% } else { %>
1553
+ term.loadAddon(new WebLinksAddon.WebLinksAddon())
1554
+ <% } %>
1549
1555
  }
1550
1556
  container.innerHTML = ''
1551
1557
  term.open(container)
@@ -1,6 +1,6 @@
1
- <div class='menu-container menu-column user-terminal'>
1
+ <div class='menu-container menu-column user-terminal <%= userTerminal.menu.length === 1 ? "user-terminal--single" : "" %>'>
2
2
  <div class='tab-header'>
3
- <h3><i class='<%= userTerminal.icon %>'></i> <%= userTerminal.title %></h3>
3
+ <h3><i class='<%= userTerminal.icon %>'></i> <%= userTerminal.title === "Terminals" ? "Project Shell" : userTerminal.title %></h3>
4
4
  </div>
5
5
  <% if (userTerminal.subtitle || userTerminal.subtitle_link_href) { %>
6
6
  <div class='column-subtitle'>
@@ -12,14 +12,6 @@
12
12
  <% } %>
13
13
  </div>
14
14
  <div class='tab-actions'>
15
- <% if (i.link) { %>
16
- <button class="tab-action-link" type="button" data-doc-link="true" data-href="<%= i.link %>" title="Open docs" data-tippy-content="Open docs" aria-label="Open docs">
17
- <i class="fa-solid fa-circle-info"></i>
18
- </button>
19
- <% } %>
20
- <button class="ai-perm-link" type="button" data-ai-consent="<%= i.href %>" title="AI permissions" data-tippy-content="AI permissions" aria-label="AI permissions">
21
- <i class="fa-solid fa-shield-halved"></i>
22
- </button>
23
15
  <div class='disclosure-indicator' aria-hidden="true">
24
16
  <i class="fa-solid fa-chevron-right"></i>
25
17
  </div>
@@ -0,0 +1,47 @@
1
+ <div id='fs-status' data-workspace="<%=name%>" data-create-uri="<%=git_create_url%>" data-history-uri="<%=git_history_url%>" data-status-uri="<%=git_status_url%>" data-uri="<%=git_monitor_url%>" data-push-uri="<%=git_push_url%>" data-fork-uri="<%=git_fork_url%>">
2
+ <!--
3
+ <div class='fs-status-dropdown nested-menu git blue'>
4
+ <button type='button' class='fs-status-btn frame-link reveal'>
5
+ <span class='fs-status-label'>
6
+ <i class="fa-brands fa-git-alt"></i>
7
+ Git
8
+ </span>
9
+ </button>
10
+ <div class='fs-dropdown-menu submenu hidden' id='git-repos'>
11
+ </div>
12
+ </div>
13
+ -->
14
+ <div class='fs-status-dropdown fs-open-explorer'>
15
+ <button class='fs-status-btn' data-filepath="<%=path%>" type='button'>
16
+ <span class='fs-status-label'>
17
+ <i class="fa-solid fa-folder-open"></i>
18
+ <span class='fs-status-title'>Open in File Explorer</span>
19
+ </span>
20
+ </button>
21
+ </div>
22
+ <div class='fs-status-dropdown git-changes'>
23
+ <button id='fs-changes-btn' class='fs-status-btn revealer' data-group='#fs-changes-menu' type='button'>
24
+ <span class='fs-status-label'><i class="fa-solid fa-code-compare"></i> Changes</span>
25
+ <div class='badge'></div>
26
+ </button>
27
+ <div class='fs-dropdown-menu submenu hidden' id='fs-changes-menu'></div>
28
+ </div>
29
+ <div class='fs-status-dropdown git-fork'>
30
+ <button id='fs-fork-btn' class='fs-status-btn revealer' type='button' data-group='#fs-fork-menu'>
31
+ <span class='fs-status-label'>
32
+ <i class="fa-solid fa-code-branch"></i>
33
+ <span class='fs-status-title'>Fork</span>
34
+ </span>
35
+ </button>
36
+ <div class='fs-dropdown-menu submenu hidden' id='fs-fork-menu'></div>
37
+ </div>
38
+ <div class='fs-status-dropdown git-publish'>
39
+ <button id='fs-push-btn' class='fs-status-btn revealer' type='button' data-group='#fs-push-menu'>
40
+ <span class='fs-status-label'>
41
+ <i class="fa-brands fa-github"></i>
42
+ <span class='fs-status-title'>Publish</span>
43
+ </span>
44
+ </button>
45
+ <div class='fs-dropdown-menu submenu hidden' id='fs-push-menu'></div>
46
+ </div>
47
+ </div>
@@ -0,0 +1,86 @@
1
+ <dialog id='<%= id %>' class='home-actions-dialog' aria-labelledby='<%= id %>-title'>
2
+ <div class='home-actions-shell'>
3
+ <div class='home-actions-header'>
4
+ <div class='home-actions-icon'>
5
+ <% if (item.icon) { %>
6
+ <img src='<%= item.icon %>' onerror="this.src='/pinokio-black.png'" alt='' />
7
+ <% } else { %>
8
+ <img src='/pinokio-black.png' alt='' />
9
+ <% } %>
10
+ </div>
11
+ <div class='home-actions-heading'>
12
+ <div class='home-actions-title-row'>
13
+ <h2 id='<%= id %>-title'><%= item.name %></h2>
14
+ <% if (item.running) { %>
15
+ <span class='home-actions-status'>Running</span>
16
+ <% } %>
17
+ </div>
18
+ <div class='home-actions-path'><%= item.filepath %></div>
19
+ </div>
20
+ <button type='button' class='home-actions-close' aria-label='Close'>
21
+ <i class='fa-solid fa-xmark' aria-hidden='true'></i>
22
+ </button>
23
+ </div>
24
+
25
+ <div class='home-actions-tabs' aria-label='App action modes'>
26
+ <button type='button' class='home-actions-tab is-active' role='tab' aria-selected='true' data-tab='run' aria-controls='<%= id %>-run'>
27
+ <i class='fa-solid fa-play' aria-hidden='true'></i>
28
+ <span>Run</span>
29
+ </button>
30
+ <button type='button' class='home-actions-tab home-browse' data-src='<%= item.dev_url %>' title='Open dev mode' aria-label='Open dev mode'>
31
+ <i class='fa-solid fa-code' aria-hidden='true'></i>
32
+ <span>Dev</span>
33
+ <% if (item.terminal_online_count > 0) { %>
34
+ <span class='home-actions-count'><%= item.terminal_online_count %> online</span>
35
+ <% } %>
36
+ </button>
37
+ <button type='button' class='home-actions-tab' role='tab' aria-selected='false' data-tab='files' aria-controls='<%= id %>-files'>
38
+ <i class='fa-solid fa-file-lines' aria-hidden='true'></i>
39
+ <span>Files</span>
40
+ </button>
41
+ </div>
42
+
43
+ <div class='home-actions-body'>
44
+ <section id='<%= id %>-run' class='home-actions-panel is-active' role='tabpanel' data-panel='run'>
45
+ <div class='home-run-menu-list'>
46
+ <button type='button' class='home-mode-command home-browse' data-src='<%= item.view_url %>'>
47
+ <i class='fa-regular fa-eye' aria-hidden='true'></i>
48
+ <span>Open without launching</span>
49
+ </button>
50
+ <% if (item.menu && item.menu.length > 0) { %>
51
+ <%- include('./home_run_menu', { menu: item.menu, app: item }) %>
52
+ <% } %>
53
+ </div>
54
+ </section>
55
+
56
+ <section id='<%= id %>-files' class='home-actions-panel' role='tabpanel' data-panel='files' hidden>
57
+ <div class='home-actions-command-list'>
58
+ <button type='button' class='home-mode-command home-browse' data-src='<%= item.files_url %>'>
59
+ <i class='fa-solid fa-file-lines' aria-hidden='true'></i>
60
+ <span>Open files mode</span>
61
+ </button>
62
+ <button type='button' class='home-mode-command' data-filepath='<%= item.filepath %>'>
63
+ <i class='fa-solid fa-folder-open' aria-hidden='true'></i>
64
+ <span>Open in file explorer</span>
65
+ </button>
66
+ <button type='button' class='home-mode-command edit-menu'>
67
+ <i class='fa-solid fa-pen-to-square' aria-hidden='true'></i>
68
+ <span>Edit launcher</span>
69
+ </button>
70
+ <button type='button' class='home-mode-command copy-menu'>
71
+ <i class='fa-solid fa-copy' aria-hidden='true'></i>
72
+ <span>Copy app</span>
73
+ </button>
74
+ <button type='button' class='home-mode-command move-menu' <% if (item.running) { %>data-disable='To move the folder, the app should not be running.'<% } %>>
75
+ <i class='fa-solid fa-right-to-bracket' aria-hidden='true'></i>
76
+ <span>Move app</span>
77
+ </button>
78
+ <button type='button' class='home-mode-command is-danger del' data-src='<%= item.url %>' <% if (item.running) { %>data-disable='To delete the folder, the app should not be running.'<% } %>>
79
+ <i class='fa-solid fa-trash-can' aria-hidden='true'></i>
80
+ <span>Delete app</span>
81
+ </button>
82
+ </div>
83
+ </section>
84
+ </div>
85
+ </div>
86
+ </dialog>
@@ -0,0 +1,87 @@
1
+ <%
2
+ const homeRunApp = typeof app !== "undefined" ? app : null
3
+ const escapeAttr = (value) => String(value ?? "")
4
+ .replace(/&/g, "&amp;")
5
+ .replace(/"/g, "&quot;")
6
+ .replace(/</g, "&lt;")
7
+ .replace(/>/g, "&gt;")
8
+ const stripHtml = (value) => String(value ?? "")
9
+ .replace(/<[^>]*>/g, " ")
10
+ .replace(/\s+/g, " ")
11
+ .trim()
12
+ const buildHomeSelectionPayload = (menuItem, index) => {
13
+ const dataFilepath = (menuItem.fs || menuItem.command) ? (menuItem.href || "") : ""
14
+ const payload = {
15
+ target: menuItem.target || "",
16
+ hrefAttr: menuItem.href || "",
17
+ dataIndex: String(index),
18
+ dataMode: menuItem.mode || "",
19
+ dataTargetFull: menuItem.target_full || "",
20
+ dataShell: menuItem.shell_id || "",
21
+ dataScript: menuItem.script_id || "",
22
+ dataAction: menuItem.action ? JSON.stringify(menuItem.action) : "",
23
+ dataRun: menuItem.run && typeof menuItem.run === "string" ? menuItem.run : "",
24
+ dataCommand: menuItem.command || "",
25
+ dataFilepath,
26
+ textValue: stripHtml(menuItem.btn)
27
+ }
28
+ Object.keys(payload).forEach((key) => {
29
+ if (!payload[key]) {
30
+ delete payload[key]
31
+ }
32
+ })
33
+ return payload
34
+ }
35
+ const buildHomeSelectionUrl = (menuItem, index) => {
36
+ const base = homeRunApp && homeRunApp.browser_url ? homeRunApp.browser_url : ""
37
+ if (!base) {
38
+ return menuItem.href || "#"
39
+ }
40
+ const hashIndex = base.indexOf("#")
41
+ const path = hashIndex >= 0 ? base.slice(0, hashIndex) : base
42
+ const hash = hashIndex >= 0 ? base.slice(hashIndex) : ""
43
+ const params = new URLSearchParams({
44
+ pinokio_home_select: JSON.stringify(buildHomeSelectionPayload(menuItem, index))
45
+ }).toString()
46
+ const separator = path.includes("?") ? "&" : "?"
47
+ return `${path}${separator}${params}${hash}`
48
+ }
49
+ %>
50
+ <% menu.forEach((item, index) => { %>
51
+ <% if (item && item.menu) { %>
52
+ <details class='home-run-menu-group' open>
53
+ <summary class='home-run-menu-summary'>
54
+ <span class='home-run-menu-label'><%- item.btn %></span>
55
+ <i class='fa-solid fa-chevron-down' aria-hidden='true'></i>
56
+ </summary>
57
+ <div class='home-run-menu-children'>
58
+ <%- include('./home_run_menu', { menu: item.menu, app: homeRunApp }) %>
59
+ </div>
60
+ </details>
61
+ <% } else if (item && item.btn) { %>
62
+ <% const openUrl = buildHomeSelectionUrl(item, index) %>
63
+ <div class='home-run-menu-row <%= item.running ? "is-running" : "" %>'>
64
+ <a
65
+ class='home-run-command'
66
+ href='<%= openUrl %>'
67
+ <% if (item.confirm) { %>data-confirm="<%- escapeAttr(item.confirm) %>"<% } %>
68
+ >
69
+ <span class='home-run-menu-label'><%- item.btn %></span>
70
+ <% if (item.running) { %><span class='home-run-menu-status'>Running</span><% } %>
71
+ <i class='fa-solid fa-chevron-right' aria-hidden='true'></i>
72
+ </a>
73
+ <% if (item.running) { %>
74
+ <button
75
+ type='button'
76
+ class='home-run-stop'
77
+ title='Stop'
78
+ <% if (item.shell_id) { %>data-shell-id='<%= item.shell_id %>'<% } %>
79
+ <% if (item.script_id) { %>data-script-id='<%= item.script_id %>'<% } %>
80
+ <% if (item.href) { %>data-href='<%= item.href %>'<% } %>
81
+ >
82
+ <i class='fa-solid fa-stop' aria-hidden='true'></i>
83
+ </button>
84
+ <% } %>
85
+ </div>
86
+ <% } %>
87
+ <% }) %>
@@ -37,11 +37,13 @@
37
37
  <a href="/connect" class="tab <%= sidebarSelected === 'connect' ? 'selected' : '' %>" data-tippy-content="Login"><i class="fa-solid fa-plug"></i><div class='caption'>Login</div></a>
38
38
  <a class='tab' href="<%=sidebarHelpUrl%>" target="_blank" data-tippy-content="Help"><i class="fa-solid fa-question"></i><div class='caption'>Help</div></a>
39
39
  <a class="tab <%= sidebarSelected === 'logs' ? 'selected' : '' %>" id='genlog' href="/logs" data-tippy-content="Logs"><i class="fa-solid fa-laptop-code"></i><div class='caption'>Logs</div></a>
40
+ <a class="tab <%= sidebarSelected === 'autolaunch' ? 'selected' : '' %>" href="/autolaunch" data-tippy-content="Autolaunch"><i class="fa-solid fa-power-off"></i><div class='caption'>Autolaunch</div></a>
40
41
  <a class="tab <%= sidebarSelected === 'checkpoints' ? 'selected' : '' %>" href="/checkpoints" data-tippy-content="Checkpoints"><i class="fa-solid fa-clock-rotate-left"></i><div class='caption'>Checkpoints</div></a>
41
42
  <a class="tab <%= sidebarSelected === 'screenshots' ? 'selected' : '' %>" href="/screenshots" data-tippy-content="Screenshots"><i class="fa-solid fa-camera"></i><div class='caption'>Screenshots</div></a>
42
43
  <a class="tab <%= sidebarSelected === 'tools' ? 'selected' : '' %>" href="/tools" data-tippy-content="Installed Tools"><i class="fa-solid fa-toolbox"></i><div class='caption'>Installed Tools</div></a>
43
44
  <a class="tab <%= sidebarSelected === 'plugins' ? 'selected' : '' %>" href="/plugins" data-tippy-content="Plugins"><i class="fa-solid fa-plug-circle-bolt"></i><div class='caption'>Plugins</div></a>
44
45
  <a class="tab <%= sidebarSelected === 'tasks' ? 'selected' : '' %>" href="/tasks" data-tippy-content="Tasks"><i class="fa-solid fa-list-check"></i><div class='caption'>Tasks</div></a>
46
+ <a class="tab <%= sidebarSelected === 'skills' ? 'selected' : '' %>" href="/skills" data-tippy-content="Skills"><i class="fa-solid fa-wand-magic-sparkles"></i><div class='caption'>Skills</div></a>
45
47
  <a class="tab <%= sidebarSelected === 'settings' ? 'selected' : '' %>" href="/home?mode=settings" data-tippy-content="Settings"><i class="fa-solid fa-gear"></i><div class='caption'>Settings</div></a>
46
48
  <% if (sidebarShowPeerAccess) { %>
47
49
  <%- include('peer_access_points', {
@@ -18,7 +18,7 @@
18
18
  <i class="fa-solid fa-angle-right"></i>
19
19
  <% } %>
20
20
  </div>
21
- <% } else if (item.run) { %>
21
+ <% } else if (item.run && typeof item.run === 'string') { %>
22
22
  <div data-run="<%=item.run%>" data-cwd="<%=item.cwd%>" class='btn header-item frame-link <%=item.display || ""%>'>
23
23
  <div class='tab'><%-item.btn%></div>
24
24
  <% if (item.arrow) { %>