pinokiod 7.2.16 → 7.2.18

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 (51) hide show
  1. package/kernel/agent_instructions.js +166 -0
  2. package/kernel/api/index.js +137 -12
  3. package/kernel/bin/huggingface.js +1 -1
  4. package/kernel/environment.js +23 -9
  5. package/kernel/plugin_sources.js +57 -4
  6. package/kernel/prototype.js +4 -0
  7. package/kernel/shell.js +2 -0
  8. package/kernel/watch/index.js +31 -4
  9. package/package.json +1 -1
  10. package/server/features/index.js +4 -4
  11. package/server/features/{drafts → notes}/index.js +9 -9
  12. package/server/features/{drafts → notes}/parser.js +12 -7
  13. package/server/features/notes/public/notes.css +955 -0
  14. package/server/features/notes/public/notes.js +1149 -0
  15. package/server/features/{drafts → notes}/registry_import.js +59 -74
  16. package/server/features/notes/routes.js +156 -0
  17. package/server/features/notes/service.js +326 -0
  18. package/server/features/{drafts → notes}/watcher.js +14 -16
  19. package/server/index.js +61 -30
  20. package/server/lib/content_validation.js +19 -8
  21. package/server/lib/workspace_catalog.js +18 -18
  22. package/server/public/task-launcher.css +11 -3
  23. package/server/public/tasker.css +336 -0
  24. package/server/public/tasker.js +407 -0
  25. package/server/views/d.ejs +33 -2
  26. package/server/views/partials/menu.ejs +1 -1
  27. package/server/views/partials/workspace_row.ejs +11 -11
  28. package/server/views/pre.ejs +1 -1
  29. package/server/views/task_launch.ejs +10 -10
  30. package/server/views/tasker.ejs +40 -0
  31. package/server/views/terminal.ejs +15 -6
  32. package/server/views/terminals.ejs +0 -1
  33. package/server/views/workspaces.ejs +2 -1
  34. package/system/plugin/antigravity/pinokio.js +2 -4
  35. package/system/plugin/claude/pinokio.js +2 -4
  36. package/system/plugin/claude-auto/pinokio.js +2 -4
  37. package/system/plugin/claude-desktop/pinokio.js +2 -4
  38. package/system/plugin/codex/pinokio.js +2 -4
  39. package/system/plugin/codex-auto/pinokio.js +2 -4
  40. package/system/plugin/codex-desktop/pinokio.js +2 -4
  41. package/system/plugin/crush/pinokio.js +2 -4
  42. package/system/plugin/cursor/pinokio.js +2 -4
  43. package/system/plugin/gemini/pinokio.js +2 -4
  44. package/system/plugin/gemini-auto/pinokio.js +2 -4
  45. package/system/plugin/qwen/pinokio.js +2 -4
  46. package/system/plugin/vscode/pinokio.js +2 -4
  47. package/system/plugin/windsurf/pinokio.js +2 -4
  48. package/test/plugin-sources.test.js +45 -0
  49. package/server/features/drafts/public/drafts.js +0 -1569
  50. package/server/features/drafts/routes.js +0 -68
  51. package/server/features/drafts/service.js +0 -261
@@ -52,13 +52,13 @@ function sortWorkspaces(items, sort) {
52
52
  return sorted
53
53
  }
54
54
 
55
- function newestDraft(drafts) {
56
- return [...drafts].sort((a, b) => {
55
+ function newestNote(notes) {
56
+ return [...notes].sort((a, b) => {
57
57
  return (new Date(b.updatedAt || 0).getTime() || 0) - (new Date(a.updatedAt || 0).getTime() || 0)
58
58
  })[0] || null
59
59
  }
60
60
 
61
- function createWorkspaceCatalogService({ kernel, workspaceRuntime, drafts }) {
61
+ function createWorkspaceCatalogService({ kernel, workspaceRuntime, notes }) {
62
62
  async function list(options = {}) {
63
63
  const sort = normalizeSortMode(options.sort)
64
64
  const root = path.resolve(kernel.path("workspaces"))
@@ -71,14 +71,14 @@ function createWorkspaceCatalogService({ kernel, workspaceRuntime, drafts }) {
71
71
  liveByPath.set(normalizePathKey(group.cwd), group)
72
72
  }
73
73
 
74
- const draftByPath = new Map()
75
- const pendingDrafts = drafts ? await drafts.listPending({}).catch(() => []) : []
76
- for (const draft of pendingDrafts) {
77
- if (!draft.cwd) continue
78
- const key = normalizePathKey(draft.cwd)
79
- const list = draftByPath.get(key) || []
80
- list.push(draft)
81
- draftByPath.set(key, list)
74
+ const noteByPath = new Map()
75
+ const pendingNotes = notes ? await notes.listPending({}).catch(() => []) : []
76
+ for (const note of pendingNotes) {
77
+ if (!note.cwd) continue
78
+ const key = normalizePathKey(note.cwd)
79
+ const list = noteByPath.get(key) || []
80
+ list.push(note)
81
+ noteByPath.set(key, list)
82
82
  }
83
83
 
84
84
  const folders = entries.filter((entry) => entry.isDirectory())
@@ -91,13 +91,13 @@ function createWorkspaceCatalogService({ kernel, workspaceRuntime, drafts }) {
91
91
  const live = liveByPath.get(key)
92
92
  const shells = live?.shells || []
93
93
  const scripts = live?.scripts || []
94
- const workspaceDrafts = draftByPath.get(key) || []
95
- const draft = newestDraft(workspaceDrafts)
94
+ const workspaceNotes = noteByPath.get(key) || []
95
+ const note = newestNote(workspaceNotes)
96
96
  const modifiedAtMs = stats?.mtimeMs || 0
97
97
  const lastOpenedAtMs = latestTimestamp([
98
98
  modifiedAtMs,
99
99
  ...shells.map((shell) => shell.start_time),
100
- ...workspaceDrafts.map((item) => item.updatedAt),
100
+ ...workspaceNotes.map((item) => item.updatedAt),
101
101
  ])
102
102
  const primaryShell = shells.length === 1 ? shells[0] : null
103
103
  const primaryScript = scripts.length === 1 ? scripts[0] : null
@@ -116,12 +116,12 @@ function createWorkspaceCatalogService({ kernel, workspaceRuntime, drafts }) {
116
116
  counts: {
117
117
  shells: shells.length,
118
118
  scripts: scripts.length,
119
- drafts: workspaceDrafts.length,
119
+ notes: workspaceNotes.length,
120
120
  },
121
121
  shells,
122
122
  scripts,
123
- draft,
124
- draftReady: Boolean(draft),
123
+ note,
124
+ noteReady: Boolean(note),
125
125
  primaryUrl: primaryScript?.url || primaryShell?.url || null,
126
126
  launchUrl: toRoutePath(cwd),
127
127
  })
@@ -140,7 +140,7 @@ function createWorkspaceCatalogService({ kernel, workspaceRuntime, drafts }) {
140
140
  total: items.length,
141
141
  running: running.length,
142
142
  offline: offline.length,
143
- drafts: items.filter((item) => item.draftReady).length,
143
+ notes: items.filter((item) => item.noteReady).length,
144
144
  },
145
145
  }
146
146
  }
@@ -1575,11 +1575,19 @@ body.dark .task-link-button.danger {
1575
1575
  }
1576
1576
 
1577
1577
  .task-run-footer {
1578
- margin-top: 14px;
1578
+ display: grid;
1579
+ gap: 8px;
1580
+ margin-top: 2px;
1581
+ padding-top: 14px;
1582
+ border-top: 1px solid var(--task-border);
1579
1583
  }
1580
1584
 
1581
- .task-run-actions {
1585
+ .task-run-actions,
1586
+ .task-run-footer .task-run-button {
1582
1587
  margin: 0;
1588
+ width: 100%;
1589
+ min-height: 38px;
1590
+ font-size: 12px;
1583
1591
  }
1584
1592
 
1585
1593
  .task-submit-feedback {
@@ -1856,7 +1864,7 @@ body.dark .task-link-button.danger {
1856
1864
  opacity: 0.55;
1857
1865
  }
1858
1866
 
1859
- .task-prompt-actions .task-submit-feedback {
1867
+ .task-run-footer .task-submit-feedback {
1860
1868
  margin-top: 2px;
1861
1869
  }
1862
1870
 
@@ -0,0 +1,336 @@
1
+ body.tasker-page {
2
+ --tasker-bg: #f5f6f8;
3
+ --tasker-panel: #ffffff;
4
+ --tasker-row: #f8fafc;
5
+ --tasker-row-hover: #f1f5f9;
6
+ --tasker-row-selected: #e8edf4;
7
+ --tasker-control: #ffffff;
8
+ --tasker-icon-bg: #ffffff;
9
+ --tasker-icon-selected-bg: #f8fafc;
10
+ --tasker-border: rgba(15, 23, 42, 0.1);
11
+ --tasker-border-strong: rgba(15, 23, 42, 0.18);
12
+ --tasker-text: rgba(15, 23, 42, 0.9);
13
+ --tasker-text-strong: rgba(15, 23, 42, 0.98);
14
+ --tasker-muted: rgba(71, 85, 105, 0.78);
15
+ --tasker-muted-strong: rgba(51, 65, 85, 0.82);
16
+ --tasker-focus: rgba(15, 23, 42, 0.1);
17
+ --tasker-focus-border: rgba(15, 23, 42, 0.28);
18
+ --tasker-clear-hover: rgba(15, 23, 42, 0.06);
19
+ --tasker-selection-bar: rgba(15, 23, 42, 0.48);
20
+ --tasker-shadow: 0 28px 80px rgba(15, 23, 42, 0.12);
21
+ min-height: 100vh;
22
+ margin: 0;
23
+ background: var(--tasker-bg);
24
+ color: var(--tasker-text);
25
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
26
+ font-size: 14px;
27
+ display: block;
28
+ }
29
+
30
+ body.dark.tasker-page {
31
+ --tasker-bg: #050607;
32
+ --tasker-panel: #0d0d0f;
33
+ --tasker-row: #141416;
34
+ --tasker-row-hover: #18181b;
35
+ --tasker-row-selected: #202024;
36
+ --tasker-control: #111114;
37
+ --tasker-icon-bg: #08090b;
38
+ --tasker-icon-selected-bg: #0c0d10;
39
+ --tasker-border: rgba(255, 255, 255, 0.09);
40
+ --tasker-border-strong: rgba(255, 255, 255, 0.18);
41
+ --tasker-text: rgba(255, 255, 255, 0.88);
42
+ --tasker-text-strong: rgba(255, 255, 255, 0.96);
43
+ --tasker-muted: rgba(255, 255, 255, 0.48);
44
+ --tasker-muted-strong: rgba(255, 255, 255, 0.62);
45
+ --tasker-focus: rgba(255, 255, 255, 0.14);
46
+ --tasker-focus-border: rgba(255, 255, 255, 0.24);
47
+ --tasker-clear-hover: rgba(255, 255, 255, 0.06);
48
+ --tasker-selection-bar: rgba(255, 255, 255, 0.64);
49
+ --tasker-shadow: 0 32px 90px rgba(0, 0, 0, 0.42);
50
+ }
51
+
52
+ body.tasker-page .tasker-main {
53
+ min-height: calc(100vh - 44px);
54
+ box-sizing: border-box;
55
+ display: grid;
56
+ place-items: center;
57
+ padding: 32px 16px;
58
+ }
59
+
60
+ .tasker-panel {
61
+ width: min(760px, calc(100vw - 32px));
62
+ max-height: min(660px, calc(100vh - 96px));
63
+ box-sizing: border-box;
64
+ display: grid;
65
+ grid-template-rows: auto auto minmax(0, 1fr);
66
+ overflow: hidden;
67
+ padding: 14px;
68
+ border: 1px solid var(--tasker-border);
69
+ border-radius: 8px;
70
+ background: var(--tasker-panel);
71
+ box-shadow: var(--tasker-shadow);
72
+ }
73
+
74
+ .tasker-search-wrap {
75
+ padding: 0 0 14px;
76
+ }
77
+
78
+ .tasker-search-field {
79
+ min-height: 42px;
80
+ box-sizing: border-box;
81
+ display: grid;
82
+ grid-template-columns: auto minmax(0, 1fr) auto;
83
+ align-items: center;
84
+ gap: 10px;
85
+ padding: 0 12px;
86
+ border: 1px solid var(--tasker-border-strong);
87
+ border-radius: 7px;
88
+ background: var(--tasker-control);
89
+ }
90
+
91
+ .tasker-search-field:focus-within {
92
+ border-color: var(--tasker-focus-border);
93
+ box-shadow: 0 0 0 3px var(--tasker-focus);
94
+ }
95
+
96
+ .tasker-search-field > i {
97
+ color: var(--tasker-muted);
98
+ font-size: 13px;
99
+ }
100
+
101
+ .tasker-search-input {
102
+ width: 100%;
103
+ min-width: 0;
104
+ min-height: 40px;
105
+ padding: 0;
106
+ border: 0;
107
+ outline: 0;
108
+ background: transparent;
109
+ color: var(--tasker-text);
110
+ font: inherit;
111
+ font-size: 14px;
112
+ line-height: 1.4;
113
+ }
114
+
115
+ .tasker-search-input::placeholder {
116
+ color: var(--tasker-muted);
117
+ }
118
+
119
+ .tasker-search-input::-webkit-search-cancel-button {
120
+ appearance: none;
121
+ -webkit-appearance: none;
122
+ }
123
+
124
+ .tasker-search-clear {
125
+ appearance: none;
126
+ width: 28px;
127
+ height: 28px;
128
+ display: inline-flex;
129
+ align-items: center;
130
+ justify-content: center;
131
+ border: 0;
132
+ border-radius: 6px;
133
+ background: transparent;
134
+ color: var(--tasker-muted);
135
+ cursor: pointer;
136
+ }
137
+
138
+ .tasker-search-clear:hover,
139
+ .tasker-search-clear:focus-visible {
140
+ background: var(--tasker-clear-hover);
141
+ color: var(--tasker-text);
142
+ outline: none;
143
+ }
144
+
145
+ .tasker-search-clear[hidden] {
146
+ display: none !important;
147
+ }
148
+
149
+ .tasker-status {
150
+ padding: 0 2px 12px;
151
+ color: var(--tasker-muted-strong);
152
+ font-size: 12px;
153
+ font-weight: 750;
154
+ line-height: 1.2;
155
+ letter-spacing: 0;
156
+ text-transform: uppercase;
157
+ }
158
+
159
+ .tasker-status[hidden] {
160
+ display: none !important;
161
+ }
162
+
163
+ .tasker-list {
164
+ min-height: 0;
165
+ display: grid;
166
+ gap: 0;
167
+ overflow: auto;
168
+ border: 1px solid var(--tasker-border);
169
+ border-radius: 7px;
170
+ background: var(--tasker-row);
171
+ }
172
+
173
+ .tasker-list[hidden] {
174
+ display: none !important;
175
+ }
176
+
177
+ .tasker-row {
178
+ position: relative;
179
+ width: 100%;
180
+ min-width: 0;
181
+ box-sizing: border-box;
182
+ display: grid;
183
+ grid-template-columns: auto minmax(0, 1fr) auto;
184
+ align-items: center;
185
+ gap: 13px;
186
+ padding: 15px 14px;
187
+ border-bottom: 1px solid var(--tasker-border);
188
+ background: var(--tasker-row);
189
+ color: var(--tasker-text);
190
+ text-align: left;
191
+ text-decoration: none;
192
+ }
193
+
194
+ .tasker-row:last-child {
195
+ border-bottom: 0;
196
+ }
197
+
198
+ .tasker-row:hover,
199
+ .tasker-row:focus-visible {
200
+ background: var(--tasker-row-hover);
201
+ color: var(--tasker-text);
202
+ outline: none;
203
+ }
204
+
205
+ .tasker-row.selected {
206
+ background: var(--tasker-row-selected);
207
+ color: var(--tasker-text);
208
+ outline: none;
209
+ }
210
+
211
+ .tasker-row.selected::before {
212
+ content: "";
213
+ position: absolute;
214
+ top: 12px;
215
+ bottom: 12px;
216
+ left: 0;
217
+ width: 3px;
218
+ border-radius: 0 3px 3px 0;
219
+ background: var(--tasker-selection-bar);
220
+ }
221
+
222
+ .tasker-row.selected .tasker-row-icon {
223
+ border-color: var(--tasker-border-strong);
224
+ background: var(--tasker-icon-selected-bg);
225
+ color: var(--tasker-text-strong);
226
+ }
227
+
228
+ .tasker-row.selected .tasker-row-label {
229
+ color: var(--tasker-text-strong);
230
+ }
231
+
232
+ .tasker-row.selected .tasker-row-meta {
233
+ color: var(--tasker-muted-strong);
234
+ }
235
+
236
+ .tasker-row-icon {
237
+ width: 29px;
238
+ height: 29px;
239
+ display: inline-flex;
240
+ align-items: center;
241
+ justify-content: center;
242
+ border: 1px solid var(--tasker-border);
243
+ border-radius: 7px;
244
+ background: var(--tasker-icon-bg);
245
+ color: var(--tasker-muted-strong);
246
+ font-size: 12px;
247
+ }
248
+
249
+ .tasker-row-copy {
250
+ min-width: 0;
251
+ display: grid;
252
+ gap: 3px;
253
+ }
254
+
255
+ .tasker-row-label {
256
+ min-width: 0;
257
+ overflow: hidden;
258
+ color: var(--tasker-text);
259
+ font-size: 15px;
260
+ font-weight: 750;
261
+ line-height: 1.25;
262
+ letter-spacing: 0;
263
+ text-overflow: ellipsis;
264
+ white-space: nowrap;
265
+ }
266
+
267
+ .tasker-row-meta {
268
+ min-width: 0;
269
+ overflow: hidden;
270
+ display: -webkit-box;
271
+ -webkit-box-orient: vertical;
272
+ -webkit-line-clamp: 2;
273
+ color: var(--tasker-muted);
274
+ font-size: 13px;
275
+ font-weight: 600;
276
+ line-height: 1.38;
277
+ }
278
+
279
+ .tasker-row-hint {
280
+ color: var(--tasker-muted);
281
+ font-size: 11px;
282
+ opacity: 0;
283
+ }
284
+
285
+ .tasker-row:hover .tasker-row-hint,
286
+ .tasker-row:focus-visible .tasker-row-hint,
287
+ .tasker-row.selected .tasker-row-hint {
288
+ opacity: 1;
289
+ }
290
+
291
+ .tasker-empty {
292
+ padding: 18px 14px;
293
+ border: 1px solid var(--tasker-border);
294
+ border-radius: 7px;
295
+ background: var(--tasker-row);
296
+ color: var(--tasker-muted);
297
+ font-size: 13px;
298
+ line-height: 1.45;
299
+ text-align: center;
300
+ }
301
+
302
+ .tasker-empty[hidden] {
303
+ display: none !important;
304
+ }
305
+
306
+ @media (max-width: 768px) {
307
+ body.tasker-page {
308
+ display: block !important;
309
+ }
310
+
311
+ body.tasker-page .tasker-main {
312
+ align-items: start;
313
+ padding: 16px 10px 24px;
314
+ }
315
+
316
+ .tasker-panel {
317
+ width: min(100%, calc(100vw - 20px));
318
+ max-height: none;
319
+ }
320
+ }
321
+
322
+ @media (max-width: 520px) {
323
+ .tasker-panel {
324
+ padding: 10px;
325
+ }
326
+
327
+ .tasker-row {
328
+ grid-template-columns: minmax(0, 1fr) auto;
329
+ gap: 8px;
330
+ padding: 13px 12px;
331
+ }
332
+
333
+ .tasker-row-icon {
334
+ display: none;
335
+ }
336
+ }