pterm 0.0.16 → 0.0.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.
package/README.md CHANGED
@@ -163,6 +163,28 @@ pterm search --q="text generation"
163
163
  pterm search "tts speech synthesis" --mode=balanced --min-match=2 --limit=8
164
164
  ```
165
165
 
166
+ ## which
167
+
168
+ Resolve the executable path for a command name through Pinokio's environment.
169
+
170
+ ### syntax
171
+
172
+ ```
173
+ pterm which <command> [--json]
174
+ ```
175
+
176
+ - `--json`: (optional) print the raw JSON response instead of only the path.
177
+
178
+ ### examples
179
+
180
+ ```
181
+ pterm which node
182
+ ```
183
+
184
+ ```
185
+ pterm which git --json
186
+ ```
187
+
166
188
  ## status
167
189
 
168
190
  Get app status by app id.
@@ -186,6 +208,59 @@ pterm status comfyanonymous-comfyui
186
208
  pterm status comfyanonymous-comfyui --probe --timeout=5000
187
209
  ```
188
210
 
211
+ ## stars
212
+
213
+ List starred apps.
214
+
215
+ ### syntax
216
+
217
+ ```
218
+ pterm stars [query words...]
219
+ pterm stars --q="<query>"
220
+ ```
221
+
222
+ ### examples
223
+
224
+ ```
225
+ pterm stars
226
+ ```
227
+
228
+ ```
229
+ pterm stars tts
230
+ ```
231
+
232
+ ## star
233
+
234
+ Star an app so it is preferred on Pinokio home/search ranking.
235
+
236
+ ### syntax
237
+
238
+ ```
239
+ pterm star <app_id>
240
+ ```
241
+
242
+ ### example
243
+
244
+ ```
245
+ pterm star comfyanonymous-comfyui
246
+ ```
247
+
248
+ ## unstar
249
+
250
+ Remove star from an app.
251
+
252
+ ### syntax
253
+
254
+ ```
255
+ pterm unstar <app_id>
256
+ ```
257
+
258
+ ### example
259
+
260
+ ```
261
+ pterm unstar comfyanonymous-comfyui
262
+ ```
263
+
189
264
  ## logs
190
265
 
191
266
  Get app logs by app id.
package/index.js CHANGED
@@ -56,6 +56,14 @@ const isHttpUri = (value) => typeof value === "string" && /^https?:\/\//i.test(v
56
56
  await util.download(argv)
57
57
  } else if (cmd === "search") {
58
58
  await util.search(argv)
59
+ } else if (cmd === "stars") {
60
+ await util.stars(argv)
61
+ } else if (cmd === "star") {
62
+ await util.setStar(argv, true)
63
+ } else if (cmd === "unstar") {
64
+ await util.setStar(argv, false)
65
+ } else if (cmd === "which") {
66
+ await util.which(argv)
59
67
  } else if (cmd === "status") {
60
68
  await util.status(argv)
61
69
  } else if (cmd === "logs") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pterm",
3
- "version": "0.0.16",
3
+ "version": "0.0.18",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
package/rpc.js CHANGED
@@ -2,6 +2,11 @@ const { WebSocket } = require('unws')
2
2
  class RPC {
3
3
  constructor(url) {
4
4
  this.url = url
5
+ this.wsOptions = {
6
+ headers: {
7
+ "x-pinokio-client": "pterm"
8
+ }
9
+ }
5
10
  }
6
11
  async status(rpc) {
7
12
  let res = await new Promise((resolve, reject) => {
@@ -38,7 +43,7 @@ class RPC {
38
43
  if (this.ws) {
39
44
  this.ws.send(JSON.stringify(rpc))
40
45
  } else {
41
- this.ws = new WebSocket(this.url)
46
+ this.ws = new WebSocket(this.url, this.wsOptions)
42
47
  this.ws.addEventListener('open', () => {
43
48
  this.ws.send(JSON.stringify(rpc))
44
49
  });
package/script.js CHANGED
@@ -52,7 +52,14 @@ class Script {
52
52
  stop()
53
53
  });
54
54
  let default_uri = await new Promise((resolve, reject) => {
55
- rpc.run({ uri, mode: "open" }, (packet) => {
55
+ rpc.run({
56
+ uri,
57
+ mode: "open",
58
+ source: "pterm",
59
+ client: {
60
+ source: "pterm"
61
+ }
62
+ }, (packet) => {
56
63
  if (packet.data && packet.data.uri) {
57
64
  // start
58
65
  //rpc.stop({ uri })
@@ -134,9 +141,11 @@ class Script {
134
141
  });
135
142
  await rpc.run({
136
143
  uri,
144
+ source: "pterm",
137
145
  client: {
138
146
  cols,
139
147
  rows,
148
+ source: "pterm"
140
149
  }
141
150
  }, (packet) => {
142
151
  if (packet.type === "stop") {
package/util.js CHANGED
@@ -71,6 +71,92 @@ class Util {
71
71
  const response = await axios.get(url)
72
72
  this.printJson(response.data)
73
73
  }
74
+ async stars(argv) {
75
+ const query = (argv._.slice(1).join(" ") || argv.q || "").trim().toLowerCase()
76
+ const [preferenceResponse, appResponse] = await Promise.all([
77
+ axios.get("http://localhost:42000/apps/preferences"),
78
+ axios.get("http://localhost:42000/info/apps")
79
+ ])
80
+ const preferenceItems = preferenceResponse && preferenceResponse.data && preferenceResponse.data.items
81
+ ? preferenceResponse.data.items
82
+ : {}
83
+ const apps = appResponse && appResponse.data && Array.isArray(appResponse.data.apps)
84
+ ? appResponse.data.apps
85
+ : []
86
+ const appsById = new Map()
87
+ for (const app of apps) {
88
+ if (!app || !app.name) continue
89
+ appsById.set(app.name, app)
90
+ }
91
+ const starredApps = Object.entries(preferenceItems)
92
+ .filter(([, preference]) => preference && preference.starred)
93
+ .map(([appId, preference]) => {
94
+ const app = appsById.get(appId) || {}
95
+ return {
96
+ app_id: appId,
97
+ title: app.title || appId,
98
+ description: app.description || "",
99
+ icon: app.icon || "/pinokio-black.png",
100
+ ...preference
101
+ }
102
+ })
103
+ .sort((a, b) => {
104
+ const aLast = typeof a.last_launch_at === "string" ? Date.parse(a.last_launch_at) || 0 : 0
105
+ const bLast = typeof b.last_launch_at === "string" ? Date.parse(b.last_launch_at) || 0 : 0
106
+ if (aLast !== bLast) {
107
+ return bLast - aLast
108
+ }
109
+ return String(a.title || a.app_id).localeCompare(String(b.title || b.app_id))
110
+ })
111
+ .filter((app) => {
112
+ if (!query) return true
113
+ const haystack = `${app.app_id || ""}\n${app.title || ""}\n${app.description || ""}`.toLowerCase()
114
+ return haystack.includes(query)
115
+ })
116
+ this.printJson({
117
+ q: query,
118
+ count: starredApps.length,
119
+ apps: starredApps
120
+ })
121
+ }
122
+ async setStar(argv, starred) {
123
+ if (argv._.length <= 1) {
124
+ console.error("required argument: <app_id>")
125
+ return
126
+ }
127
+ const appId = argv._[1]
128
+ const response = await axios.put(`http://localhost:42000/apps/preferences/${encodeURIComponent(appId)}`, {
129
+ starred: Boolean(starred)
130
+ })
131
+ this.printJson(response.data)
132
+ }
133
+ async which(argv) {
134
+ if (argv._.length <= 1) {
135
+ console.error("required argument: <command>")
136
+ return
137
+ }
138
+ const command = String(argv._[1]).trim()
139
+ if (!command) {
140
+ console.error("required argument: <command>")
141
+ return
142
+ }
143
+ try {
144
+ const response = await axios.get(`http://localhost:42000/pinokio/path/${encodeURIComponent(command)}`)
145
+ if (argv.json) {
146
+ this.printJson(response.data)
147
+ } else if (response.data && response.data.path) {
148
+ process.stdout.write(String(response.data.path))
149
+ process.stdout.write("\n")
150
+ }
151
+ } catch (error) {
152
+ if (error && error.response && error.response.status === 404) {
153
+ console.error(`command not found: ${command}`)
154
+ process.exitCode = 1
155
+ return
156
+ }
157
+ throw error
158
+ }
159
+ }
74
160
  async filepicker(argv) {
75
161
  const rpc = new RPC("ws://localhost:42000")
76
162
  if (argv.path) {