pinokiod 7.3.0 → 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.
- package/kernel/api/github/index.js +444 -0
- package/kernel/api/index.js +199 -11
- package/kernel/api/process/index.js +124 -44
- package/kernel/api/shell_run_template.js +273 -0
- package/kernel/api/uri/index.js +51 -0
- package/kernel/bin/{conda-python.js → conda-pins.js} +23 -0
- package/kernel/bin/conda.js +15 -5
- package/kernel/bin/git.js +9 -10
- package/kernel/bin/huggingface.js +1 -1
- package/kernel/bin/index.js +5 -2
- package/kernel/bin/zip.js +9 -1
- package/kernel/connect/providers/github/README.md +5 -4
- package/kernel/environment.js +195 -92
- package/kernel/git.js +98 -19
- package/kernel/gitconfig_template +7 -0
- package/kernel/gpu/amd.js +72 -0
- package/kernel/gpu/apple.js +8 -0
- package/kernel/gpu/common.js +12 -0
- package/kernel/gpu/intel.js +47 -0
- package/kernel/gpu/nvidia.js +8 -0
- package/kernel/index.js +11 -1
- package/kernel/managed_skills.js +871 -0
- package/kernel/plugin.js +6 -58
- package/kernel/plugin_sources.js +316 -0
- package/kernel/resource_usage/gpu.js +349 -0
- package/kernel/resource_usage/index.js +322 -0
- package/kernel/resource_usage/macos_footprint.js +197 -0
- package/kernel/resource_usage/preferences.js +92 -0
- package/kernel/resource_usage/process_tree.js +303 -0
- package/kernel/scripts/git/create +4 -4
- package/kernel/scripts/git/fork +7 -8
- package/kernel/shell.js +23 -2
- package/kernel/shells.js +41 -0
- package/kernel/sysinfo.js +62 -9
- package/kernel/util.js +60 -0
- package/package.json +1 -1
- package/server/index.js +984 -156
- package/server/lib/app_log_report.js +543 -0
- package/server/lib/content_validation.js +55 -33
- package/server/lib/launcher_instruction_bootstrap.js +4 -96
- package/server/lib/terminal_session_helpers.js +0 -3
- package/server/public/common.js +77 -31
- package/server/public/create-launcher.js +4 -32
- package/server/public/logs.js +1428 -0
- package/server/public/nav.js +7 -0
- package/server/public/plugin-detail.js +93 -10
- package/server/public/privacy_filter_worker.js +391 -0
- package/server/public/style.css +1104 -154
- package/server/public/task-launcher.js +8 -29
- package/server/public/universal-launcher.css +8 -6
- package/server/public/universal-launcher.js +3 -27
- package/server/routes/apps.js +195 -1
- package/server/views/app.ejs +3041 -717
- package/server/views/autolaunch.ejs +917 -0
- package/server/views/bootstrap.ejs +7 -1
- package/server/views/d.ejs +408 -65
- package/server/views/editor.ejs +85 -19
- package/server/views/index.ejs +661 -111
- package/server/views/init/index.ejs +1 -1
- package/server/views/install.ejs +1 -1
- package/server/views/logs.ejs +164 -86
- package/server/views/net.ejs +7 -1
- package/server/views/partials/d_terminal_column.ejs +2 -2
- package/server/views/partials/d_terminal_options.ejs +0 -8
- package/server/views/partials/fs_status.ejs +47 -0
- package/server/views/partials/home_action_modal.ejs +86 -0
- package/server/views/partials/home_run_menu.ejs +87 -0
- package/server/views/partials/main_sidebar.ejs +2 -0
- package/server/views/partials/menu.ejs +1 -1
- package/server/views/plugin_detail.ejs +19 -4
- package/server/views/plugins.ejs +201 -3
- package/server/views/pre.ejs +1 -1
- package/server/views/pro.ejs +1 -1
- package/server/views/shell.ejs +40 -18
- package/server/views/skills.ejs +506 -0
- package/server/views/terminal.ejs +45 -19
- package/spec/INSTRUCTION_SYNC.md +20 -10
- package/system/plugin/antigravity-cli/antigravity.png +0 -0
- package/system/plugin/antigravity-cli/common.js +155 -0
- package/system/plugin/antigravity-cli/install.js +272 -0
- package/system/plugin/antigravity-cli/pinokio.js +13 -0
- package/system/plugin/antigravity-cli-auto/antigravity.png +0 -0
- package/system/plugin/antigravity-cli-auto/pinokio.js +13 -0
- package/system/plugin/claude/claude.png +0 -0
- package/system/plugin/claude/pinokio.js +47 -0
- package/system/plugin/claude-auto/claude.png +0 -0
- package/system/plugin/claude-auto/pinokio.js +58 -0
- package/system/plugin/claude-desktop/icon.jpeg +0 -0
- package/system/plugin/claude-desktop/pinokio.js +23 -0
- package/system/plugin/codex/openai.webp +0 -0
- package/system/plugin/codex/pinokio.js +42 -0
- package/system/plugin/codex-auto/openai.webp +0 -0
- package/system/plugin/codex-auto/pinokio.js +49 -0
- package/system/plugin/codex-desktop/icon.png +0 -0
- package/system/plugin/codex-desktop/pinokio.js +23 -0
- package/system/plugin/crush/crush.png +0 -0
- package/system/plugin/crush/pinokio.js +15 -0
- package/system/plugin/cursor/cursor.jpeg +0 -0
- package/system/plugin/cursor/pinokio.js +23 -0
- package/system/plugin/qwen/pinokio.js +34 -0
- package/system/plugin/qwen/qwen.png +0 -0
- package/system/plugin/vscode/pinokio.js +20 -0
- package/system/plugin/vscode/vscode.png +0 -0
- package/system/plugin/windsurf/pinokio.js +23 -0
- package/system/plugin/windsurf/windsurf.png +0 -0
- package/test/antigravity-cli-plugin.test.js +185 -0
- package/test/app-api.test.js +239 -0
- package/test/app-log-report.test.js +67 -0
- package/test/environment-cache-preflight.test.js +98 -0
- package/test/git-bin.test.js +59 -0
- package/test/git-defaults.test.js +97 -0
- package/test/github-api.test.js +158 -0
- package/test/github-connection.test.js +117 -0
- package/test/huggingface-bin.test.js +25 -0
- package/test/managed-skills.test.js +351 -0
- package/test/plugin-action-functions.test.js +337 -0
- package/test/plugin-dev-iframe.test.js +17 -0
- package/test/plugin-sources.test.js +203 -0
- package/test/privacy-filter-worker-heuristics.test.js +69 -0
- package/test/process-wait.test.js +169 -0
- package/test/script-api.test.js +97 -0
- package/test/shell-api.test.js +134 -0
- package/test/shell-run-template.test.js +209 -0
- package/test/storage-api.test.js +137 -0
- package/test/uri-api.test.js +100 -0
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Skills</title>
|
|
7
|
+
<link href="/css/fontawesome.min.css" rel="stylesheet">
|
|
8
|
+
<link href="/css/solid.min.css" rel="stylesheet">
|
|
9
|
+
<link href="/css/brands.min.css" rel="stylesheet">
|
|
10
|
+
<link href="/noty.css" rel="stylesheet">
|
|
11
|
+
<link href="/style.css" rel="stylesheet">
|
|
12
|
+
<link href="/task-launcher.css" rel="stylesheet">
|
|
13
|
+
<% if (agent === "electron") { %>
|
|
14
|
+
<link href="/electron.css" rel="stylesheet"/>
|
|
15
|
+
<% } %>
|
|
16
|
+
<style>
|
|
17
|
+
body.skills-page .skills-overview {
|
|
18
|
+
display: grid;
|
|
19
|
+
grid-template-columns: minmax(0, 1.3fr) minmax(280px, 0.7fr);
|
|
20
|
+
gap: 16px;
|
|
21
|
+
align-items: start;
|
|
22
|
+
}
|
|
23
|
+
body.skills-page .skills-explainer {
|
|
24
|
+
display: grid;
|
|
25
|
+
gap: 8px;
|
|
26
|
+
max-width: 82ch;
|
|
27
|
+
}
|
|
28
|
+
body.skills-page .skills-explainer-title {
|
|
29
|
+
margin: 0;
|
|
30
|
+
font-size: 14px;
|
|
31
|
+
line-height: 1.25;
|
|
32
|
+
font-weight: 650;
|
|
33
|
+
color: var(--task-text);
|
|
34
|
+
}
|
|
35
|
+
body.skills-page .skills-explainer-copy {
|
|
36
|
+
margin: 0;
|
|
37
|
+
font-size: 13px;
|
|
38
|
+
line-height: 1.5;
|
|
39
|
+
color: var(--task-muted);
|
|
40
|
+
}
|
|
41
|
+
body.skills-page .skills-explainer-list {
|
|
42
|
+
display: grid;
|
|
43
|
+
gap: 5px;
|
|
44
|
+
margin: 0;
|
|
45
|
+
padding: 0;
|
|
46
|
+
list-style: none;
|
|
47
|
+
font-size: 12px;
|
|
48
|
+
line-height: 1.45;
|
|
49
|
+
color: var(--task-muted);
|
|
50
|
+
}
|
|
51
|
+
body.skills-page .skills-explainer-list li {
|
|
52
|
+
position: relative;
|
|
53
|
+
padding-left: 14px;
|
|
54
|
+
}
|
|
55
|
+
body.skills-page .skills-explainer-list li::before {
|
|
56
|
+
content: "";
|
|
57
|
+
position: absolute;
|
|
58
|
+
top: 0.72em;
|
|
59
|
+
left: 0;
|
|
60
|
+
width: 4px;
|
|
61
|
+
height: 4px;
|
|
62
|
+
border-radius: 999px;
|
|
63
|
+
background: currentColor;
|
|
64
|
+
opacity: 0.56;
|
|
65
|
+
}
|
|
66
|
+
body.skills-page .skills-path-stack {
|
|
67
|
+
display: grid;
|
|
68
|
+
gap: 8px;
|
|
69
|
+
align-content: start;
|
|
70
|
+
font-size: 12px;
|
|
71
|
+
color: var(--task-muted);
|
|
72
|
+
}
|
|
73
|
+
body.skills-page .skills-path-stack code {
|
|
74
|
+
overflow-wrap: anywhere;
|
|
75
|
+
}
|
|
76
|
+
body.skills-page .skills-install-form {
|
|
77
|
+
display: grid;
|
|
78
|
+
grid-template-columns: minmax(240px, 1fr) auto;
|
|
79
|
+
gap: 10px;
|
|
80
|
+
align-items: end;
|
|
81
|
+
}
|
|
82
|
+
body.skills-page .skills-install-submit {
|
|
83
|
+
min-width: 132px;
|
|
84
|
+
min-height: 38px;
|
|
85
|
+
padding: 0 16px;
|
|
86
|
+
gap: 7px;
|
|
87
|
+
font-size: 13px;
|
|
88
|
+
font-weight: 650;
|
|
89
|
+
}
|
|
90
|
+
body.skills-page .skills-list {
|
|
91
|
+
display: grid;
|
|
92
|
+
gap: 10px;
|
|
93
|
+
}
|
|
94
|
+
body.skills-page .skill-row {
|
|
95
|
+
display: grid;
|
|
96
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
97
|
+
gap: 14px;
|
|
98
|
+
align-items: start;
|
|
99
|
+
border: 1px solid rgba(0, 0, 0, 0.09);
|
|
100
|
+
border-radius: 8px;
|
|
101
|
+
padding: 14px;
|
|
102
|
+
background: rgba(0, 0, 0, 0.025);
|
|
103
|
+
}
|
|
104
|
+
body.dark.skills-page .skill-row {
|
|
105
|
+
border-color: rgba(255, 255, 255, 0.12);
|
|
106
|
+
background: rgba(255, 255, 255, 0.04);
|
|
107
|
+
}
|
|
108
|
+
body.skills-page .skill-row.has-conflict {
|
|
109
|
+
border-color: rgba(190, 72, 20, 0.55);
|
|
110
|
+
background: rgba(190, 72, 20, 0.06);
|
|
111
|
+
}
|
|
112
|
+
body.dark.skills-page .skill-row.has-conflict {
|
|
113
|
+
border-color: rgba(251, 146, 60, 0.5);
|
|
114
|
+
background: rgba(251, 146, 60, 0.1);
|
|
115
|
+
}
|
|
116
|
+
body.skills-page .skill-main {
|
|
117
|
+
display: grid;
|
|
118
|
+
gap: 10px;
|
|
119
|
+
min-width: 0;
|
|
120
|
+
}
|
|
121
|
+
body.skills-page .skill-title-line {
|
|
122
|
+
display: flex;
|
|
123
|
+
align-items: center;
|
|
124
|
+
gap: 8px;
|
|
125
|
+
min-width: 0;
|
|
126
|
+
flex-wrap: wrap;
|
|
127
|
+
}
|
|
128
|
+
body.skills-page .skill-title {
|
|
129
|
+
margin: 0;
|
|
130
|
+
font-size: 16px;
|
|
131
|
+
line-height: 1.2;
|
|
132
|
+
font-weight: 650;
|
|
133
|
+
}
|
|
134
|
+
body.skills-page .skill-description {
|
|
135
|
+
margin: 0;
|
|
136
|
+
max-width: 72ch;
|
|
137
|
+
font-size: 13px;
|
|
138
|
+
line-height: 1.45;
|
|
139
|
+
opacity: 0.72;
|
|
140
|
+
}
|
|
141
|
+
body.skills-page .skill-status {
|
|
142
|
+
display: inline-flex;
|
|
143
|
+
align-items: center;
|
|
144
|
+
font-size: 12px;
|
|
145
|
+
line-height: 1.2;
|
|
146
|
+
font-weight: 500;
|
|
147
|
+
color: var(--task-muted);
|
|
148
|
+
white-space: nowrap;
|
|
149
|
+
}
|
|
150
|
+
body.skills-page .skill-status.good {
|
|
151
|
+
color: #166534;
|
|
152
|
+
}
|
|
153
|
+
body.skills-page .skill-status.warn {
|
|
154
|
+
color: #9a3412;
|
|
155
|
+
}
|
|
156
|
+
body.dark.skills-page .skill-status.good {
|
|
157
|
+
color: #86efac;
|
|
158
|
+
}
|
|
159
|
+
body.dark.skills-page .skill-status.warn {
|
|
160
|
+
color: #fdba74;
|
|
161
|
+
}
|
|
162
|
+
body.skills-page .skill-details {
|
|
163
|
+
display: grid;
|
|
164
|
+
gap: 7px;
|
|
165
|
+
font-size: 12px;
|
|
166
|
+
}
|
|
167
|
+
body.skills-page .skill-detail-line {
|
|
168
|
+
display: flex;
|
|
169
|
+
gap: 8px;
|
|
170
|
+
align-items: baseline;
|
|
171
|
+
min-width: 0;
|
|
172
|
+
}
|
|
173
|
+
body.skills-page .skill-detail-label {
|
|
174
|
+
flex: 0 0 auto;
|
|
175
|
+
width: 88px;
|
|
176
|
+
opacity: 0.58;
|
|
177
|
+
}
|
|
178
|
+
body.skills-page .skill-detail-value {
|
|
179
|
+
min-width: 0;
|
|
180
|
+
overflow-wrap: anywhere;
|
|
181
|
+
}
|
|
182
|
+
body.skills-page .skill-targets {
|
|
183
|
+
display: grid;
|
|
184
|
+
gap: 4px;
|
|
185
|
+
margin: 0;
|
|
186
|
+
padding: 0;
|
|
187
|
+
list-style: none;
|
|
188
|
+
}
|
|
189
|
+
body.skills-page .skill-target {
|
|
190
|
+
display: flex;
|
|
191
|
+
align-items: center;
|
|
192
|
+
gap: 7px;
|
|
193
|
+
min-width: 0;
|
|
194
|
+
opacity: 0.72;
|
|
195
|
+
}
|
|
196
|
+
body.skills-page .skill-target i {
|
|
197
|
+
width: 13px;
|
|
198
|
+
text-align: center;
|
|
199
|
+
}
|
|
200
|
+
body.skills-page .skill-target.conflict {
|
|
201
|
+
color: rgb(154, 52, 18);
|
|
202
|
+
opacity: 1;
|
|
203
|
+
}
|
|
204
|
+
body.dark.skills-page .skill-target.conflict {
|
|
205
|
+
color: rgb(253, 186, 116);
|
|
206
|
+
}
|
|
207
|
+
body.skills-page .skill-actions {
|
|
208
|
+
display: grid;
|
|
209
|
+
gap: 8px;
|
|
210
|
+
justify-items: end;
|
|
211
|
+
min-width: 230px;
|
|
212
|
+
}
|
|
213
|
+
body.skills-page .skill-toggle-form {
|
|
214
|
+
margin: 0;
|
|
215
|
+
}
|
|
216
|
+
body.skills-page .skill-switch {
|
|
217
|
+
display: inline-flex;
|
|
218
|
+
align-items: center;
|
|
219
|
+
justify-content: center;
|
|
220
|
+
gap: 7px;
|
|
221
|
+
min-width: 78px;
|
|
222
|
+
min-height: 28px;
|
|
223
|
+
box-sizing: border-box;
|
|
224
|
+
padding: 0 8px;
|
|
225
|
+
border: 1px solid var(--task-border);
|
|
226
|
+
border-radius: 999px;
|
|
227
|
+
background: color-mix(in srgb, var(--task-panel) 96%, var(--task-soft));
|
|
228
|
+
color: var(--task-muted);
|
|
229
|
+
cursor: pointer;
|
|
230
|
+
font-size: 11px;
|
|
231
|
+
font-weight: 650;
|
|
232
|
+
line-height: 1;
|
|
233
|
+
transition: background 140ms ease, border-color 140ms ease, color 140ms ease;
|
|
234
|
+
}
|
|
235
|
+
body.skills-page .skill-switch:hover {
|
|
236
|
+
background: color-mix(in srgb, var(--task-soft) 76%, var(--task-panel));
|
|
237
|
+
color: var(--task-text);
|
|
238
|
+
}
|
|
239
|
+
body.skills-page .skill-switch[aria-checked="true"] {
|
|
240
|
+
border-color: color-mix(in srgb, #22c55e 30%, transparent);
|
|
241
|
+
background: color-mix(in srgb, #22c55e 12%, var(--task-panel));
|
|
242
|
+
color: #166534;
|
|
243
|
+
}
|
|
244
|
+
body.dark.skills-page .skill-switch[aria-checked="true"] {
|
|
245
|
+
color: #86efac;
|
|
246
|
+
}
|
|
247
|
+
body.skills-page .skill-switch:disabled {
|
|
248
|
+
cursor: not-allowed;
|
|
249
|
+
opacity: 0.62;
|
|
250
|
+
}
|
|
251
|
+
body.skills-page .skill-switch-track {
|
|
252
|
+
position: relative;
|
|
253
|
+
width: 30px;
|
|
254
|
+
height: 16px;
|
|
255
|
+
border-radius: 999px;
|
|
256
|
+
background: color-mix(in srgb, var(--task-muted) 24%, transparent);
|
|
257
|
+
transition: background 140ms ease;
|
|
258
|
+
}
|
|
259
|
+
body.skills-page .skill-switch[aria-checked="true"] .skill-switch-track {
|
|
260
|
+
background: color-mix(in srgb, #22c55e 52%, transparent);
|
|
261
|
+
}
|
|
262
|
+
body.skills-page .skill-switch-thumb {
|
|
263
|
+
position: absolute;
|
|
264
|
+
top: 2px;
|
|
265
|
+
left: 2px;
|
|
266
|
+
width: 12px;
|
|
267
|
+
height: 12px;
|
|
268
|
+
border-radius: 999px;
|
|
269
|
+
background: var(--task-panel);
|
|
270
|
+
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.18);
|
|
271
|
+
transition: transform 140ms ease;
|
|
272
|
+
}
|
|
273
|
+
body.skills-page .skill-switch[aria-checked="true"] .skill-switch-thumb {
|
|
274
|
+
transform: translateX(14px);
|
|
275
|
+
}
|
|
276
|
+
body.skills-page .skill-switch-label {
|
|
277
|
+
min-width: 18px;
|
|
278
|
+
text-align: left;
|
|
279
|
+
}
|
|
280
|
+
body.skills-page .skill-publish-form {
|
|
281
|
+
display: grid;
|
|
282
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
283
|
+
gap: 6px;
|
|
284
|
+
width: 230px;
|
|
285
|
+
}
|
|
286
|
+
body.skills-page .skill-remove-form {
|
|
287
|
+
margin: 0;
|
|
288
|
+
}
|
|
289
|
+
body.skills-page .skills-message {
|
|
290
|
+
margin-bottom: 12px;
|
|
291
|
+
}
|
|
292
|
+
@media (max-width: 980px) {
|
|
293
|
+
body.skills-page .skills-overview,
|
|
294
|
+
body.skills-page .skill-row {
|
|
295
|
+
grid-template-columns: 1fr;
|
|
296
|
+
}
|
|
297
|
+
body.skills-page .skill-actions {
|
|
298
|
+
justify-items: stretch;
|
|
299
|
+
min-width: 0;
|
|
300
|
+
}
|
|
301
|
+
body.skills-page .skill-publish-form,
|
|
302
|
+
body.skills-page .skill-switch {
|
|
303
|
+
width: 100%;
|
|
304
|
+
}
|
|
305
|
+
body.skills-page .skills-install-form {
|
|
306
|
+
grid-template-columns: 1fr;
|
|
307
|
+
}
|
|
308
|
+
body.skills-page .skills-install-submit {
|
|
309
|
+
width: 100%;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
</style>
|
|
313
|
+
</head>
|
|
314
|
+
<%
|
|
315
|
+
const validCount = skills.filter((skill) => skill.valid).length;
|
|
316
|
+
const hasIndexError = Boolean(indexError);
|
|
317
|
+
const targetIcon = (status) => {
|
|
318
|
+
if (status === "published" || status === "legacy-managed") return "fa-solid fa-circle-check";
|
|
319
|
+
if (status === "conflict") return "fa-solid fa-triangle-exclamation";
|
|
320
|
+
if (status === "missing") return "fa-regular fa-circle";
|
|
321
|
+
return "fa-regular fa-circle";
|
|
322
|
+
};
|
|
323
|
+
const targetClass = (status) => status === "conflict" ? "conflict" : "";
|
|
324
|
+
%>
|
|
325
|
+
<body class="<%= theme %> task-launcher-page task-page skills-page" data-agent="<%= agent %>">
|
|
326
|
+
<%- include('partials/app_navheader', { agent }) %>
|
|
327
|
+
<main>
|
|
328
|
+
<div class="task-container">
|
|
329
|
+
<section class="task-shell">
|
|
330
|
+
<header class="task-shell-header">
|
|
331
|
+
<div class="task-shell-header-main">
|
|
332
|
+
<p class="task-eyebrow">Skills</p>
|
|
333
|
+
<h1 class="task-title">Skills</h1>
|
|
334
|
+
<p class="task-description">Stored in <code><%= skillsRootPath %></code>.</p>
|
|
335
|
+
</div>
|
|
336
|
+
</header>
|
|
337
|
+
|
|
338
|
+
<div class="task-shell-body">
|
|
339
|
+
<% if (notice) { %>
|
|
340
|
+
<div class="task-status skills-message"><%= notice %></div>
|
|
341
|
+
<% } %>
|
|
342
|
+
<% if (error) { %>
|
|
343
|
+
<div class="task-status error skills-message"><%= error %></div>
|
|
344
|
+
<% } %>
|
|
345
|
+
<% if (hasIndexError) { %>
|
|
346
|
+
<div class="task-status error skills-message">
|
|
347
|
+
Managed skills are not being synced because <code><%= indexPath %></code> could not be read. Fix the JSON file, then reload this page. <%= indexError %>
|
|
348
|
+
</div>
|
|
349
|
+
<% } %>
|
|
350
|
+
|
|
351
|
+
<section class="task-section skills-overview" aria-label="How managed skills work">
|
|
352
|
+
<div class="skills-explainer">
|
|
353
|
+
<h2 class="skills-explainer-title">How this works</h2>
|
|
354
|
+
<p class="skills-explainer-copy">
|
|
355
|
+
Pinokio keeps the source copy of each managed skill in <code><%= skillsRootPath %></code>. When a skill is ON, Pinokio syncs its <code>SKILL.md</code> into the target skill folders used by agent tools.
|
|
356
|
+
</p>
|
|
357
|
+
<ul class="skills-explainer-list">
|
|
358
|
+
<li>Sync runs when Pinokio starts and after changes made on this page.</li>
|
|
359
|
+
<li>Turning a skill OFF removes only Pinokio-managed synced copies from the target folders.</li>
|
|
360
|
+
<li>The source skill stays in the managed library, so it can be turned on again later.</li>
|
|
361
|
+
<li>If a target folder already contains a non-Pinokio skill, Pinokio leaves it untouched and marks a conflict.</li>
|
|
362
|
+
<li>Downloaded repositories must contain a root <code>SKILL.md</code> before they can be turned on.</li>
|
|
363
|
+
</ul>
|
|
364
|
+
</div>
|
|
365
|
+
<div class="skills-path-stack">
|
|
366
|
+
<div><strong>Index</strong> <code><%= indexPath %></code></div>
|
|
367
|
+
<div><strong>Sync targets</strong></div>
|
|
368
|
+
<% publishRoots.forEach((root) => { %>
|
|
369
|
+
<code><%= root %></code>
|
|
370
|
+
<% }) %>
|
|
371
|
+
</div>
|
|
372
|
+
</section>
|
|
373
|
+
|
|
374
|
+
<% if (!hasIndexError) { %>
|
|
375
|
+
<section class="task-section" aria-label="Download skill">
|
|
376
|
+
<form class="skills-install-form" method="post" action="/skills/install">
|
|
377
|
+
<label class="task-field">
|
|
378
|
+
<span class="task-label">Git URL</span>
|
|
379
|
+
<input class="task-input" type="url" name="ref" placeholder="https://github.com/org/skill.git" required>
|
|
380
|
+
</label>
|
|
381
|
+
<button class="task-button primary skills-install-submit" type="submit">
|
|
382
|
+
<i class="fa-solid fa-download" aria-hidden="true"></i>
|
|
383
|
+
<span>Download</span>
|
|
384
|
+
</button>
|
|
385
|
+
</form>
|
|
386
|
+
</section>
|
|
387
|
+
<% } %>
|
|
388
|
+
|
|
389
|
+
<section class="task-section" aria-label="Installed skills">
|
|
390
|
+
<div class="task-section-head">
|
|
391
|
+
<div>
|
|
392
|
+
<h2 class="task-section-title">Library</h2>
|
|
393
|
+
<p class="task-section-subcopy"><%= hasIndexError ? 'Unavailable until the index is readable.' : `${validCount} valid, ${skills.length - validCount} invalid.` %></p>
|
|
394
|
+
</div>
|
|
395
|
+
</div>
|
|
396
|
+
<% if (hasIndexError) { %>
|
|
397
|
+
<div class="task-empty-state">
|
|
398
|
+
<p class="task-empty-copy">No managed skill changes were applied.</p>
|
|
399
|
+
</div>
|
|
400
|
+
<% } else if (!skills.length) { %>
|
|
401
|
+
<div class="task-empty-state">
|
|
402
|
+
<p class="task-empty-copy">No managed skills installed.</p>
|
|
403
|
+
</div>
|
|
404
|
+
<% } else { %>
|
|
405
|
+
<div class="skills-list">
|
|
406
|
+
<% skills.forEach((skill) => { %>
|
|
407
|
+
<% const canRenamePublishName = !skill.builtin && skill.hasConflict; %>
|
|
408
|
+
<article class="skill-row <%= skill.hasConflict ? 'has-conflict' : '' %>">
|
|
409
|
+
<div class="skill-main">
|
|
410
|
+
<div>
|
|
411
|
+
<div class="skill-title-line">
|
|
412
|
+
<h2 class="skill-title"><%= skill.label || skill.id %></h2>
|
|
413
|
+
<% if (skill.builtin) { %><span class="skill-status">Built-in</span><% } %>
|
|
414
|
+
<% if (skill.enabled) { %><span class="skill-status good">On</span><% } else { %><span class="skill-status">Off</span><% } %>
|
|
415
|
+
<% if (skill.valid) { %><span class="skill-status good">Valid</span><% } else { %><span class="skill-status warn">Invalid</span><% } %>
|
|
416
|
+
<% if (skill.hasConflict) { %><span class="skill-status warn">Conflict</span><% } %>
|
|
417
|
+
</div>
|
|
418
|
+
<% if (skill.description) { %>
|
|
419
|
+
<p class="skill-description"><%= skill.description %></p>
|
|
420
|
+
<% } %>
|
|
421
|
+
</div>
|
|
422
|
+
<div class="skill-details">
|
|
423
|
+
<div class="skill-detail-line">
|
|
424
|
+
<span class="skill-detail-label">Skill ID</span>
|
|
425
|
+
<span class="skill-detail-value"><code><%= skill.id %></code></span>
|
|
426
|
+
</div>
|
|
427
|
+
<div class="skill-detail-line">
|
|
428
|
+
<span class="skill-detail-label">Synced as</span>
|
|
429
|
+
<span class="skill-detail-value"><code><%= skill.publishName %></code></span>
|
|
430
|
+
</div>
|
|
431
|
+
<div class="skill-detail-line">
|
|
432
|
+
<span class="skill-detail-label">Source</span>
|
|
433
|
+
<span class="skill-detail-value"><code><%= skill.path %></code></span>
|
|
434
|
+
</div>
|
|
435
|
+
<% if (skill.ref) { %>
|
|
436
|
+
<div class="skill-detail-line">
|
|
437
|
+
<span class="skill-detail-label">Remote</span>
|
|
438
|
+
<span class="skill-detail-value"><code><%= skill.ref %></code></span>
|
|
439
|
+
</div>
|
|
440
|
+
<% } %>
|
|
441
|
+
<% if (!skill.valid && skill.errors.length) { %>
|
|
442
|
+
<div class="skill-detail-line">
|
|
443
|
+
<span class="skill-detail-label">Error</span>
|
|
444
|
+
<span class="skill-detail-value"><%= skill.errors.join(" ") %></span>
|
|
445
|
+
</div>
|
|
446
|
+
<% } %>
|
|
447
|
+
<div class="skill-detail-line">
|
|
448
|
+
<span class="skill-detail-label">Synced to</span>
|
|
449
|
+
<ul class="skill-targets">
|
|
450
|
+
<% skill.targets.forEach((target) => { %>
|
|
451
|
+
<li class="skill-target <%= targetClass(target.status) %>">
|
|
452
|
+
<i class="<%= targetIcon(target.status) %>" aria-hidden="true"></i>
|
|
453
|
+
<span><code><%= target.path %></code><%= target.message ? ` - ${target.message}` : '' %></span>
|
|
454
|
+
</li>
|
|
455
|
+
<% }) %>
|
|
456
|
+
</ul>
|
|
457
|
+
</div>
|
|
458
|
+
</div>
|
|
459
|
+
</div>
|
|
460
|
+
<div class="skill-actions">
|
|
461
|
+
<form class="skill-toggle-form" method="post" action="/skills/<%= encodeURIComponent(skill.id) %>/toggle">
|
|
462
|
+
<input type="hidden" name="enabled" value="<%= skill.enabled ? '0' : '1' %>">
|
|
463
|
+
<button class="skill-switch" type="submit" role="switch" aria-checked="<%= skill.enabled ? 'true' : 'false' %>" aria-label="<%= skill.enabled ? 'Turn skill off' : 'Turn skill on' %>" title="<%= skill.enabled ? 'Turn skill off' : 'Turn skill on' %>" <%= !skill.enabled && !skill.valid ? 'disabled' : '' %>>
|
|
464
|
+
<span class="skill-switch-track" aria-hidden="true"><span class="skill-switch-thumb"></span></span>
|
|
465
|
+
<span class="skill-switch-label"><%= skill.enabled ? 'ON' : 'OFF' %></span>
|
|
466
|
+
</button>
|
|
467
|
+
</form>
|
|
468
|
+
<% if (canRenamePublishName) { %>
|
|
469
|
+
<form class="skill-publish-form" method="post" action="/skills/<%= encodeURIComponent(skill.id) %>/publish-name">
|
|
470
|
+
<input class="task-input" type="text" name="publishName" value="<%= skill.publishName %>" aria-label="Sync folder name">
|
|
471
|
+
<button class="task-link-button" type="submit" aria-label="Save sync folder name">
|
|
472
|
+
<i class="fa-solid fa-check" aria-hidden="true"></i>
|
|
473
|
+
</button>
|
|
474
|
+
</form>
|
|
475
|
+
<% } %>
|
|
476
|
+
<% if (skill.removable) { %>
|
|
477
|
+
<form class="skill-remove-form" method="post" action="/skills/<%= encodeURIComponent(skill.id) %>/remove" data-skill-remove>
|
|
478
|
+
<button class="task-link-button" type="submit">
|
|
479
|
+
<i class="fa-solid fa-trash-can" aria-hidden="true"></i>
|
|
480
|
+
<span>Remove</span>
|
|
481
|
+
</button>
|
|
482
|
+
</form>
|
|
483
|
+
<% } %>
|
|
484
|
+
</div>
|
|
485
|
+
</article>
|
|
486
|
+
<% }) %>
|
|
487
|
+
</div>
|
|
488
|
+
<% } %>
|
|
489
|
+
</section>
|
|
490
|
+
</div>
|
|
491
|
+
</section>
|
|
492
|
+
</div>
|
|
493
|
+
<%- include('partials/main_sidebar', { selected: 'skills' }) %>
|
|
494
|
+
</main>
|
|
495
|
+
<%- include('partials/app_common_scripts') %>
|
|
496
|
+
<script>
|
|
497
|
+
document.querySelectorAll("[data-skill-remove]").forEach((form) => {
|
|
498
|
+
form.addEventListener("submit", (event) => {
|
|
499
|
+
if (!window.confirm("Remove this downloaded skill?")) {
|
|
500
|
+
event.preventDefault()
|
|
501
|
+
}
|
|
502
|
+
})
|
|
503
|
+
})
|
|
504
|
+
</script>
|
|
505
|
+
</body>
|
|
506
|
+
</html>
|
|
@@ -713,6 +713,35 @@ function postMessageToAncestors(payload) {
|
|
|
713
713
|
})
|
|
714
714
|
return dispatched
|
|
715
715
|
}
|
|
716
|
+
function openAppLogsForError(packet) {
|
|
717
|
+
return postMessageToAncestors({
|
|
718
|
+
e: "pinokio:logs-new",
|
|
719
|
+
type: "pinokio:logs-new",
|
|
720
|
+
reason: "error",
|
|
721
|
+
frame: window.name || null,
|
|
722
|
+
source: "terminal"
|
|
723
|
+
})
|
|
724
|
+
}
|
|
725
|
+
function showErrorScreen(packet) {
|
|
726
|
+
const errorScreen = document.querySelector("#error-screen")
|
|
727
|
+
const errorOutput = errorScreen ? errorScreen.querySelector("pre") : null
|
|
728
|
+
if (!errorScreen || !errorOutput) {
|
|
729
|
+
return
|
|
730
|
+
}
|
|
731
|
+
errorScreen.classList.remove("hidden")
|
|
732
|
+
errorOutput.textContent = packet && packet.data ? packet.data : ""
|
|
733
|
+
let instance = new Mark(errorOutput, {
|
|
734
|
+
separateWordSearch: false,
|
|
735
|
+
accuracy: "exactly"
|
|
736
|
+
})
|
|
737
|
+
if (packet && packet.event) {
|
|
738
|
+
instance.mark(packet.event)
|
|
739
|
+
let element = errorScreen.querySelector("mark")
|
|
740
|
+
if (element) {
|
|
741
|
+
element.scrollIntoView({ behavior: "smooth", block: "center" })
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
}
|
|
716
745
|
|
|
717
746
|
function buildBinaryRpcPayload(rpc, fileEntries) {
|
|
718
747
|
const metadata = {
|
|
@@ -895,6 +924,7 @@ const createPluginTerminalDiscoveryRefresher = (context = {}) => {
|
|
|
895
924
|
const enabled = (() => {
|
|
896
925
|
try {
|
|
897
926
|
return window.location.pathname.startsWith("/run/plugin/")
|
|
927
|
+
|| window.location.pathname.startsWith("/pinokio/run/plugin/")
|
|
898
928
|
|| (window.location.pathname.startsWith("/run/api/") && /\/pinokio\.js$/i.test(window.location.pathname))
|
|
899
929
|
} catch (_) {
|
|
900
930
|
return false
|
|
@@ -1232,6 +1262,10 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
1232
1262
|
const scriptAction = <% if (typeof action !== 'undefined') { %><%- JSON.stringify(action) %><% } else { %>null<% } %>
|
|
1233
1263
|
const protectionAppId = <% if (typeof protection_app_id !== 'undefined' && protection_app_id) { %><%- JSON.stringify(protection_app_id) %><% } else { %>""<% } %>
|
|
1234
1264
|
const initialProtectionEnabled = <% if (typeof protection_enabled !== 'undefined') { %><%- JSON.stringify(protection_enabled === true) %><% } else { %>false<% } %>
|
|
1265
|
+
const activeProcessWait = <% if (typeof active_process_wait !== 'undefined' && active_process_wait) { %><%- JSON.stringify(active_process_wait) %><% } else { %>null<% } %>
|
|
1266
|
+
if (activeProcessWait && (activeProcessWait.title || activeProcessWait.description || activeProcessWait.message) && window.PinokioWaitFooterStatus) {
|
|
1267
|
+
window.PinokioWaitFooterStatus.show(activeProcessWait)
|
|
1268
|
+
}
|
|
1235
1269
|
const shouldBypassAiConsent = () => {
|
|
1236
1270
|
const normalize = (value) => (typeof value === "string" ? value.replace(/\\/g, "/") : "")
|
|
1237
1271
|
const uri = normalize(scriptUri || "")
|
|
@@ -1678,6 +1712,14 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
1678
1712
|
// uri: "~" + location.pathname,
|
|
1679
1713
|
uri: packet.id
|
|
1680
1714
|
})
|
|
1715
|
+
} else if (packet.type === "process.wait.start") {
|
|
1716
|
+
if (window.PinokioWaitFooterStatus) {
|
|
1717
|
+
window.PinokioWaitFooterStatus.show(packet.data)
|
|
1718
|
+
}
|
|
1719
|
+
} else if (packet.type === "process.wait.end") {
|
|
1720
|
+
if (window.PinokioWaitFooterStatus) {
|
|
1721
|
+
window.PinokioWaitFooterStatus.hide()
|
|
1722
|
+
}
|
|
1681
1723
|
} else if (packet.type === 'wait') {
|
|
1682
1724
|
await WaitModal(packet.data)
|
|
1683
1725
|
} else if (packet.type === "htmlmodal") {
|
|
@@ -1890,24 +1932,8 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
1890
1932
|
} else if (packet.type === "error") {
|
|
1891
1933
|
pluginTerminalDiscoveryRefresher.clear()
|
|
1892
1934
|
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
document.querySelector("#error-screen pre").textContent = packet.data
|
|
1896
|
-
let instance = new Mark(document.querySelector("#error-screen pre"), {
|
|
1897
|
-
separateWordSearch: false,
|
|
1898
|
-
accuracy: "exactly"
|
|
1899
|
-
})
|
|
1900
|
-
/*
|
|
1901
|
-
document.querySelector("#error-screen").addEventListener("click", (e) => {
|
|
1902
|
-
document.querySelector("#error-screen").classList.add("hidden")
|
|
1903
|
-
})
|
|
1904
|
-
*/
|
|
1905
|
-
if (packet.event) {
|
|
1906
|
-
instance.mark(packet.event)
|
|
1907
|
-
let element = document.querySelector("#error-screen mark")
|
|
1908
|
-
if (element) {
|
|
1909
|
-
element.scrollIntoView({ behavior: "smooth", block: "center" })
|
|
1910
|
-
}
|
|
1935
|
+
if (!openAppLogsForError(packet)) {
|
|
1936
|
+
showErrorScreen(packet)
|
|
1911
1937
|
}
|
|
1912
1938
|
|
|
1913
1939
|
this.error = true
|
|
@@ -2750,7 +2776,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
2750
2776
|
term.loadAddon(fitAddon);
|
|
2751
2777
|
<% if (agent === "electron") { %>
|
|
2752
2778
|
term.loadAddon(new WebLinksAddon.WebLinksAddon((event, uri) => {
|
|
2753
|
-
window.open(uri, "_blank")
|
|
2779
|
+
window.open(uri, "_blank", "browser")
|
|
2754
2780
|
}))
|
|
2755
2781
|
<% } else { %>
|
|
2756
2782
|
term.loadAddon(new WebLinksAddon.WebLinksAddon());
|
package/spec/INSTRUCTION_SYNC.md
CHANGED
|
@@ -83,10 +83,13 @@ Policy:
|
|
|
83
83
|
- write each generated output only if its content differs from the desired content
|
|
84
84
|
- `.geminiignore` remains a write-if-changed generated file.
|
|
85
85
|
|
|
86
|
-
### 4.
|
|
86
|
+
### 4. Managed skills and mirrored instruction outputs
|
|
87
87
|
|
|
88
88
|
Paths:
|
|
89
89
|
|
|
90
|
+
- `PINOKIO_HOME/skills/index.json`
|
|
91
|
+
- `PINOKIO_HOME/skills/gepeto/SKILL.md`
|
|
92
|
+
- `PINOKIO_HOME/skills/pinokio/SKILL.md`
|
|
90
93
|
- `~/.agents/skills/gepeto/SKILL.md`
|
|
91
94
|
- `~/.claude/skills/gepeto/SKILL.md`
|
|
92
95
|
- `~/.hermes/skills/gepeto/SKILL.md`
|
|
@@ -96,14 +99,20 @@ Paths:
|
|
|
96
99
|
|
|
97
100
|
Population:
|
|
98
101
|
|
|
99
|
-
-
|
|
102
|
+
- `PINOKIO_HOME/skills/gepeto/SKILL.md` is generated from the current effective `PINOKIO_HOME/AGENTS.md`
|
|
103
|
+
- `PINOKIO_HOME/skills/pinokio/SKILL.md` is generated from the source-controlled file in this repo at `prototype/system/SKILL_PINOKIO.md`
|
|
104
|
+
- enabled managed skills are published into external agent roots during managed skill sync
|
|
100
105
|
|
|
101
106
|
Policy:
|
|
102
107
|
|
|
103
|
-
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
-
|
|
108
|
+
- `PINOKIO_HOME/skills/index.json` is the managed skill source of truth.
|
|
109
|
+
- Built-in skills `pinokio` and `gepeto` are present by default and may be disabled but not removed.
|
|
110
|
+
- Downloaded skills are cloned into `PINOKIO_HOME/skills/<id>` and publish as `pinokio-<id>` by default.
|
|
111
|
+
- Enabled managed skills are published to `~/.agents/skills`, `~/.claude/skills`, and `~/.hermes/skills`.
|
|
112
|
+
- Published copies include a `.pinokio-managed.json` marker.
|
|
113
|
+
- Pinokio may update or remove published copies only when they are marked Pinokio-owned, or when migrating a legacy copy whose `SKILL.md` content matches the generated desired content.
|
|
114
|
+
- If a publish target already contains a non-Pinokio skill, sync must report a conflict and not overwrite it.
|
|
115
|
+
- If a published copy is manually deleted while the skill remains enabled, sync treats that as drift and recreates it.
|
|
107
116
|
|
|
108
117
|
### 5. Out-of-scope user installs
|
|
109
118
|
|
|
@@ -347,7 +356,7 @@ Changes:
|
|
|
347
356
|
- do not apply `SOUL.md` logic to app-root generated files in v1
|
|
348
357
|
- leave app-root `AGENTS.md` / `CLAUDE.md` / `GEMINI.md` / `QWEN.md` / rule generation on current behavior unless required by a concrete bug
|
|
349
358
|
|
|
350
|
-
### 5.
|
|
359
|
+
### 5. Move mirror sync behind managed skills
|
|
351
360
|
|
|
352
361
|
File:
|
|
353
362
|
|
|
@@ -355,9 +364,10 @@ File:
|
|
|
355
364
|
|
|
356
365
|
Changes:
|
|
357
366
|
|
|
358
|
-
-
|
|
359
|
-
-
|
|
360
|
-
-
|
|
367
|
+
- generate built-in managed skill sources under `PINOKIO_HOME/skills`
|
|
368
|
+
- publish only enabled managed skills to external agent roots
|
|
369
|
+
- remove disabled Pinokio-owned published copies
|
|
370
|
+
- preserve user-owned publish target conflicts without overwriting
|
|
361
371
|
|
|
362
372
|
### 6. Add targeted missing-path Git repair helpers
|
|
363
373
|
|
|
Binary file
|