pterm 0.0.24 → 0.0.25

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
@@ -10,6 +10,8 @@ npm install -g pterm
10
10
 
11
11
  # Usage
12
12
 
13
+ This README documents the stable public CLI surface.
14
+
13
15
  ## version
14
16
 
15
17
  prints the current version
@@ -20,10 +22,10 @@ prints the current version
20
22
  pterm version <type>
21
23
  ```
22
24
 
23
- - `type`: may be `terminal`, `pinokiod`, or `pinokio`
25
+ - `type`: may be `terminal`, `pinokiod`, `pinokio`, or `script`
24
26
  - `terminal`: returns the pterm version
25
27
  - `pinokiod`: returns the pinokiod version
26
- - `pinokio`: returns the pinokio version
28
+ - `pinokio`: returns the Pinokio app wrapper version
27
29
  - `script`: returns the valid script version for the current client. used for including in `pinokio.js`
28
30
 
29
31
  ### example
@@ -32,16 +34,88 @@ pterm version <type>
32
34
  pterm version terminal
33
35
  ```
34
36
 
37
+ ## refs
38
+
39
+ Pinokio resource references use this syntax:
40
+
41
+ ```
42
+ pinokio://<host>:<port>/<scope>/<id>
43
+ ```
44
+
45
+ Examples:
46
+
47
+ ```
48
+ pinokio://127.0.0.1:42000/api/cropper.git
49
+ pinokio://192.168.86.26:42000/api/facefusion-pinokio.git
50
+ ```
51
+
52
+ Currently documented scope:
53
+
54
+ - `api`: an installed Pinokio app under `PINOKIO_HOME/api`
55
+
56
+ How refs are used:
57
+
58
+ - the `host:port` in a ref identifies the target Pinokio control plane, not the app's `ready_url`
59
+ - `pterm` does not connect directly to the app endpoint described by the ref
60
+ - `pterm` talks to the local Pinokio control plane, and the local control plane resolves or forwards the ref to the target Pinokio node as needed
61
+
62
+ ## open
63
+
64
+ Open a URL on the local Pinokio node or on a connected peer node.
65
+
66
+ ### syntax
67
+
68
+ ```
69
+ pterm open <url> [--peer <peer>] [--surface browser|popup] [--preset center-small|center-medium|center-large|fullscreen]
70
+ ```
71
+
72
+ - `--peer`: optional target Pinokio node. May be a peer host, `host:port`, or peer name.
73
+ - `--surface`: optional UI surface. `popup` requests a Pinokio popup window. `browser` forces the system browser. Default is popup-preferred.
74
+ - `--preset`: optional popup size preset. Only applies when popup is used.
75
+
76
+ Behavior:
77
+
78
+ - `pterm` still talks to the local Pinokio control plane first
79
+ - if `--peer` is set, the local node forwards the open request to that peer
80
+ - if `--peer` is set, the URL is opened from that peer node's point of view, so `http://127.0.0.1:7860` means the peer's loopback
81
+ - by default, `pterm open` prefers a Pinokio popup window
82
+ - on a full Pinokio desktop node, the default opens a desktop popup
83
+ - on a server-only or minimal node, the default automatically falls back to opening the system browser
84
+ - default popup preset is `center-medium`
85
+ - `center-medium` opens centered on the active display using roughly 64% of screen width and 72% of screen height, with minimum size `900x700`
86
+
87
+ ### examples
88
+
89
+ Open a URL locally with the default popup-preferred behavior:
90
+
91
+ ```
92
+ pterm open http://127.0.0.1:7860
93
+ ```
94
+
95
+ Force the system browser instead of the default popup-preferred behavior:
96
+
97
+ ```
98
+ pterm open http://127.0.0.1:7860 --surface browser
99
+ ```
100
+
101
+ Open a URL on a peer node:
102
+
103
+ ```
104
+ pterm open http://127.0.0.1:7860 --peer 192.168.86.26
105
+ ```
106
+
35
107
  ## start
36
108
 
37
- Start a pinokio script. Arguments can be passed into the script
109
+ Start a pinokio script. `pterm` options go before `--`. Script args go after `--`.
38
110
 
39
111
  ### syntax
40
112
 
41
113
  ```
42
- pterm start <script_path> [<arg1>, <arg2>, ...]
114
+ pterm start <script_path> [--ref <pinokio_ref>] [-- --<key>=<value> ...]
43
115
  ```
44
116
 
117
+ With `--ref`, prefer relative script paths like `start.js`. `~/...` expansion is only local.
118
+
45
119
  ### examples
46
120
 
47
121
  Starting a script named `install.js`:
@@ -53,7 +127,7 @@ pterm start install.js
53
127
  Starting a script named `start.js` with parameters:
54
128
 
55
129
  ```
56
- pterm start start.js --port=3000 --model=google/gemma-3n-E4B-it
130
+ pterm start start.js -- --port=3000 --model=google/gemma-3n-E4B-it
57
131
  ```
58
132
 
59
133
  Above command starts the script `start.js` with the following args:
@@ -65,6 +139,24 @@ Above command starts the script `start.js` with the following args:
65
139
  }
66
140
  ```
67
141
 
142
+ Query parameters in the script path are also passed through as script input automatically:
143
+
144
+ ```
145
+ pterm start 'run.js?mode=Default'
146
+ ```
147
+
148
+ Starting a relative script inside a selected app:
149
+
150
+ ```
151
+ pterm start start.js --ref pinokio://127.0.0.1:42000/api/metube-pinokio.git
152
+ ```
153
+
154
+ Passing a script argument named `app` without conflicting with `pterm --ref`:
155
+
156
+ ```
157
+ pterm start start.js --ref pinokio://127.0.0.1:42000/api/metube-pinokio.git -- --app=my-script-value
158
+ ```
159
+
68
160
  Which can be accessed in the `start.js` script, for example:
69
161
 
70
162
  ```json
@@ -90,8 +182,12 @@ Stops a script if running:
90
182
 
91
183
  ```
92
184
  pterm stop <script_path>
185
+ pterm stop <script_path> --ref <pinokio_ref>
186
+ pterm stop <pinokio_ref>
93
187
  ```
94
188
 
189
+ With `--ref`, prefer relative script paths like `start.js`. `~/...` expansion is only local.
190
+
95
191
 
96
192
  ### example
97
193
 
@@ -101,6 +197,18 @@ Stop the `start.js` script if it's running:
101
197
  pterm stop start.js
102
198
  ```
103
199
 
200
+ Stop a relative script inside a selected app:
201
+
202
+ ```
203
+ pterm stop start.js --ref pinokio://127.0.0.1:42000/api/metube-pinokio.git
204
+ ```
205
+
206
+ Stop all running scripts for an app:
207
+
208
+ ```
209
+ pterm stop pinokio://127.0.0.1:42000/api/metube-pinokio.git
210
+ ```
211
+
104
212
  ## run
105
213
 
106
214
  Run a launcher. Equivalent to the user visiting a launcher page. By default it will run whichever script is the current launcher default. If the launcher exposes no explicit default, you can provide repeated `--default` selectors and Pinokio will match the first selector that exists in the launcher's current menu state.
@@ -109,6 +217,7 @@ Run a launcher. Equivalent to the user visiting a launcher page. By default it w
109
217
 
110
218
  ```
111
219
  pterm run <launcher_path_or_uri> [--default <selector>]... [--open]
220
+ pterm run <pinokio_ref> [--default <selector>]... [--open]
112
221
  ```
113
222
 
114
223
  - `--open`: (optional) open URL results in the browser. Default behavior is to print the URL to stdout without opening a browser.
@@ -143,7 +252,16 @@ pterm run ~/pinokio/api/facefusion-pinokio.git \
143
252
  --default install.js
144
253
  ```
145
254
 
146
- Launch a script directly with query parameters. Query parameters are passed through as script input automatically.
255
+ Run an installed app by Pinokio ref:
256
+
257
+ ```
258
+ pterm run pinokio://192.168.86.26:42000/api/facefusion-pinokio.git \
259
+ --default 'run.js?mode=Default' \
260
+ --default run.js \
261
+ --default install.js
262
+ ```
263
+
264
+ For direct script execution with query parameters, use `pterm start`. Query parameters are passed through as script input automatically.
147
265
 
148
266
  ```
149
267
  pterm start 'run.js?mode=Default'
@@ -272,14 +390,37 @@ pterm which node
272
390
  pterm which git --json
273
391
  ```
274
392
 
393
+ ## home
394
+
395
+ Get `PINOKIO_HOME`.
396
+
397
+ ### syntax
398
+
399
+ ```
400
+ pterm home [--json]
401
+ ```
402
+
403
+ - `--json`: (optional) print the raw JSON response instead of only the path.
404
+
405
+ ### examples
406
+
407
+ ```
408
+ pterm home
409
+ ```
410
+
411
+ ```
412
+ pterm home --json
413
+ ```
414
+
275
415
  ## status
276
416
 
277
- Get app status by app id.
417
+ Get app status by app id or Pinokio ref.
278
418
 
279
419
  ### syntax
280
420
 
281
421
  ```
282
422
  pterm status <app_id> [--probe] [--timeout=<ms>]
423
+ pterm status <pinokio_ref> [--probe] [--timeout=<ms>]
283
424
  ```
284
425
 
285
426
  - `--probe`: (optional) actively probe app health.
@@ -295,6 +436,10 @@ pterm status comfyanonymous-comfyui
295
436
  pterm status comfyanonymous-comfyui --probe --timeout=5000
296
437
  ```
297
438
 
439
+ ```
440
+ pterm status pinokio://192.168.86.26:42000/api/comfyanonymous-comfyui --probe --timeout=5000
441
+ ```
442
+
298
443
  ## stars
299
444
 
300
445
  List starred apps.
@@ -350,12 +495,13 @@ pterm unstar comfyanonymous-comfyui
350
495
 
351
496
  ## logs
352
497
 
353
- Get app logs by app id.
498
+ Get app logs by app id or Pinokio ref.
354
499
 
355
500
  ### syntax
356
501
 
357
502
  ```
358
503
  pterm logs <app_id> [--script=<name>] [--tail=<lines>]
504
+ pterm logs <pinokio_ref> [--script=<name>] [--tail=<lines>]
359
505
  ```
360
506
 
361
507
  - `--script`: (optional) filter to a script.
@@ -371,11 +517,15 @@ pterm logs comfyanonymous-comfyui
371
517
  pterm logs comfyanonymous-comfyui --script=start --tail=200
372
518
  ```
373
519
 
520
+ ```
521
+ pterm logs pinokio://192.168.86.26:42000/api/comfyanonymous-comfyui --script=start --tail=200
522
+ ```
523
+
374
524
  ## filepicker
375
525
 
376
526
  Display a file picker dialog, which lets the user select one or more file or folder paths, powered by tkinter.
377
527
 
378
- This API is NOT for uploading the actual files but for submitting file paths.
528
+ This API is NOT for uploading the actual files but for submitting file paths. Use `pterm upload <pinokio_ref> <file...>` when a remote app needs real files staged onto its machine.
379
529
 
380
530
  ### syntax
381
531
 
@@ -408,12 +558,6 @@ The most basic command lets users select a single file:
408
558
  pterm filepicker
409
559
  ```
410
560
 
411
- which is equivalent to:
412
-
413
- ```
414
- pterm filepicker --type=file
415
- ```
416
-
417
561
  #### Select multiple files
418
562
 
419
563
  ```
@@ -438,6 +582,28 @@ pterm filepicker --filetype='images/*.png,*.jpg,*.jpeg'
438
582
  pterm filepicker --filetype='images/*.png,*.jpg,*.jpeg' --filetype='docs/*.pdf'
439
583
  ```
440
584
 
585
+ ## upload
586
+
587
+ Stage one or more local files onto the selected app's machine and return remote filesystem paths that can be passed to path-based tasks.
588
+
589
+ ### syntax
590
+
591
+ ```
592
+ pterm upload <app_id|pinokio_ref> <file...>
593
+ ```
594
+
595
+ Quoted `~/...` file paths are expanded locally before upload.
596
+
597
+ ### examples
598
+
599
+ ```
600
+ pterm upload facefusion-pinokio.git ./face.jpg ./video.mp4
601
+ ```
602
+
603
+ ```
604
+ pterm upload pinokio://192.168.86.26:42000/api/facefusion-pinokio.git ./face.jpg ./video.mp4
605
+ ```
606
+
441
607
  ## clipboard
442
608
 
443
609
  write to or read from clipboard
package/endpoint.js ADDED
@@ -0,0 +1,163 @@
1
+ const fs = require('fs')
2
+ const os = require('os')
3
+ const path = require('path')
4
+ const axios = require('axios')
5
+
6
+ const DEFAULT_PROTOCOL = 'http'
7
+ const DEFAULT_HOST = '127.0.0.1'
8
+ const DEFAULT_PORT = 42000
9
+ const DEFAULT_BASE_URL = `${DEFAULT_PROTOCOL}://${DEFAULT_HOST}:${DEFAULT_PORT}`
10
+ const CONFIG_PATH = path.resolve(os.homedir(), '.pinokio', 'config.json')
11
+
12
+ let resolvedHttpBaseUrlPromise = null
13
+
14
+ function formatHostForUrl(host) {
15
+ if (!host) {
16
+ return ''
17
+ }
18
+ const normalized = String(host).trim().replace(/^\[|\]$/g, '')
19
+ if (!normalized) {
20
+ return ''
21
+ }
22
+ return normalized.includes(':') ? `[${normalized}]` : normalized
23
+ }
24
+
25
+ function normalizeBaseUrl(value) {
26
+ if (typeof value !== 'string') {
27
+ return null
28
+ }
29
+ const trimmed = value.trim()
30
+ if (!trimmed) {
31
+ return null
32
+ }
33
+ try {
34
+ const url = new URL(trimmed)
35
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
36
+ return null
37
+ }
38
+ return `${url.protocol}//${url.host}`
39
+ } catch (error) {
40
+ return null
41
+ }
42
+ }
43
+
44
+ function buildExplicitHttpBaseUrl(target) {
45
+ if (!target) {
46
+ return null
47
+ }
48
+ if (typeof target === 'string') {
49
+ const normalized = normalizeBaseUrl(target)
50
+ if (normalized) {
51
+ return normalized
52
+ }
53
+ const host = formatHostForUrl(target)
54
+ if (!host) {
55
+ return null
56
+ }
57
+ return normalizeBaseUrl(`${DEFAULT_PROTOCOL}://${host}:${DEFAULT_PORT}`)
58
+ }
59
+ if (typeof target !== 'object') {
60
+ return null
61
+ }
62
+ const protocol = target.protocol === 'https' ? 'https' : DEFAULT_PROTOCOL
63
+ const host = formatHostForUrl(target.host)
64
+ if (!host) {
65
+ return null
66
+ }
67
+ const rawPort = Number.parseInt(String(target.port), 10)
68
+ const port = Number.isFinite(rawPort) && rawPort > 0 ? rawPort : DEFAULT_PORT
69
+ return normalizeBaseUrl(`${protocol}://${host}:${port}`)
70
+ }
71
+
72
+ function readStoredAccessBaseUrl() {
73
+ try {
74
+ const raw = fs.readFileSync(CONFIG_PATH, 'utf8')
75
+ const parsed = JSON.parse(raw)
76
+ const access = parsed && parsed.access
77
+ if (!access) {
78
+ return null
79
+ }
80
+ if (typeof access === 'string') {
81
+ const value = access.trim()
82
+ if (!value) {
83
+ return null
84
+ }
85
+ if (/^https?:\/\//i.test(value)) {
86
+ return normalizeBaseUrl(value)
87
+ }
88
+ if (/^\[.*\](?::\d+)?$/.test(value) || /:\d+$/.test(value)) {
89
+ return normalizeBaseUrl(`${DEFAULT_PROTOCOL}://${value}`)
90
+ }
91
+ return normalizeBaseUrl(`${DEFAULT_PROTOCOL}://${formatHostForUrl(value)}:${DEFAULT_PORT}`)
92
+ }
93
+ if (typeof access !== 'object') {
94
+ return null
95
+ }
96
+ const protocol = access.protocol === 'https' ? 'https' : DEFAULT_PROTOCOL
97
+ const host = formatHostForUrl(access.host)
98
+ if (!host) {
99
+ return null
100
+ }
101
+ const rawPort = Number.parseInt(String(access.port), 10)
102
+ const port = Number.isFinite(rawPort) && rawPort > 0 ? rawPort : DEFAULT_PORT
103
+ return normalizeBaseUrl(`${protocol}://${host}:${port}`)
104
+ } catch (error) {
105
+ return null
106
+ }
107
+ }
108
+
109
+ async function canReachControlPlane(baseUrl) {
110
+ try {
111
+ await axios.get(`${baseUrl}/pinokio/version`, {
112
+ timeout: 1000,
113
+ headers: {
114
+ 'x-pinokio-client': 'pterm'
115
+ },
116
+ validateStatus: () => true
117
+ })
118
+ return true
119
+ } catch (error) {
120
+ return false
121
+ }
122
+ }
123
+
124
+ async function resolveHttpBaseUrl(target) {
125
+ const explicitBaseUrl = buildExplicitHttpBaseUrl(target)
126
+ if (explicitBaseUrl) {
127
+ return explicitBaseUrl
128
+ }
129
+ if (!resolvedHttpBaseUrlPromise) {
130
+ resolvedHttpBaseUrlPromise = (async () => {
131
+ if (await canReachControlPlane(DEFAULT_BASE_URL)) {
132
+ return DEFAULT_BASE_URL
133
+ }
134
+ return readStoredAccessBaseUrl() || DEFAULT_BASE_URL
135
+ })()
136
+ }
137
+ try {
138
+ return await resolvedHttpBaseUrlPromise
139
+ } catch (error) {
140
+ resolvedHttpBaseUrlPromise = null
141
+ throw error
142
+ }
143
+ }
144
+
145
+ async function resolveWsBaseUrl(target) {
146
+ const httpBaseUrl = await resolveHttpBaseUrl(target)
147
+ const normalized = normalizeBaseUrl(httpBaseUrl)
148
+ if (!normalized) {
149
+ return `ws://${DEFAULT_HOST}:${DEFAULT_PORT}`
150
+ }
151
+ const url = new URL(normalized)
152
+ url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:'
153
+ return `${url.protocol}//${url.host}`
154
+ }
155
+
156
+ module.exports = {
157
+ DEFAULT_BASE_URL,
158
+ DEFAULT_PORT,
159
+ buildExplicitHttpBaseUrl,
160
+ readStoredAccessBaseUrl,
161
+ resolveHttpBaseUrl,
162
+ resolveWsBaseUrl,
163
+ }
package/index.js CHANGED
@@ -1,18 +1,64 @@
1
1
  #!/usr/bin/env node
2
2
  const path = require('path')
3
+ const axios = require('axios')
3
4
  const yargs = require('yargs/yargs')
4
5
  const { hideBin } = require('yargs/helpers')
6
+ const { resolveHttpBaseUrl } = require('./endpoint')
7
+ const { isHttpUri, resolveAppControlTarget, resolveStartTarget } = require('./target')
8
+ const extractStartInput = (parsedArgv) => {
9
+ const rawScriptArgs = Array.isArray(parsedArgv && parsedArgv["--"]) ? parsedArgv["--"] : []
10
+ if (!rawScriptArgs.length) {
11
+ return undefined
12
+ }
13
+ const scriptArgv = yargs(rawScriptArgs)
14
+ .parserConfiguration({
15
+ 'camel-case-expansion': false,
16
+ 'dot-notation': false,
17
+ 'duplicate-arguments-array': true,
18
+ 'populate--': false
19
+ })
20
+ .help(false)
21
+ .version(false)
22
+ .parse()
23
+ const input = {}
24
+ for (const [key, value] of Object.entries(scriptArgv || {})) {
25
+ if (key === '_' || key === '$0' || value === undefined) {
26
+ continue
27
+ }
28
+ input[key] = value
29
+ }
30
+ return Object.keys(input).length > 0 ? input : undefined
31
+ }
5
32
  const argv = yargs(hideBin(process.argv))
6
33
  .option('default', {
7
34
  type: 'string',
8
35
  array: true
9
36
  })
37
+ .option('peer', {
38
+ type: 'string'
39
+ })
40
+ .option('surface', {
41
+ type: 'string'
42
+ })
43
+ .option('preset', {
44
+ type: 'string'
45
+ })
46
+ .option('ref', {
47
+ type: 'string'
48
+ })
49
+ .parserConfiguration({
50
+ 'populate--': true
51
+ })
10
52
  .parse();
11
53
  const Script = require('./script')
12
54
  const Util = require('./util')
13
55
  const script = new Script();
14
56
  const util = new Util();
15
- const isHttpUri = (value) => typeof value === "string" && /^https?:\/\//i.test(value);
57
+ const fetchPinokioVersion = async () => {
58
+ const baseUrl = await resolveHttpBaseUrl()
59
+ const response = await axios.get(`${baseUrl}/pinokio/version`)
60
+ return response.data
61
+ }
16
62
  (async () => {
17
63
  if (argv._.length > 0) {
18
64
  let cmd = argv._[0].toLowerCase()
@@ -27,27 +73,21 @@ const isHttpUri = (value) => typeof value === "string" && /^https?:\/\//i.test(v
27
73
  console.log("pterm@" + require('./package.json').version)
28
74
  } else if (app === "pinokiod") {
29
75
  try {
30
- let r = await fetch("http://localhost:42000/pinokio/version").then((res) => {
31
- return res.json()
32
- })
76
+ let r = await fetchPinokioVersion()
33
77
  console.log(`pinokiod@${r.pinokiod}`)
34
78
  } catch (e) {
35
79
  }
36
80
  } else if (app === "pinokio") {
37
81
  try {
38
- let r = await fetch("http://localhost:42000/pinokio/version").then((res) => {
39
- return res.json()
40
- })
82
+ let r = await fetchPinokioVersion()
41
83
  if (r.pinokio) {
42
- console.log(`pinokiod@${r.pinokio}`)
84
+ console.log(`pinokio@${r.pinokio}`)
43
85
  }
44
86
  } catch (e) {
45
87
  }
46
88
  } else if (app === "script") {
47
89
  try {
48
- let r = await fetch("http://localhost:42000/pinokio/version").then((res) => {
49
- return res.json()
50
- })
90
+ let r = await fetchPinokioVersion()
51
91
  if (r.script) {
52
92
  console.log(`${r.script}`)
53
93
  }
@@ -57,6 +97,8 @@ const isHttpUri = (value) => typeof value === "string" && /^https?:\/\//i.test(v
57
97
  }
58
98
  } else if (cmd === "filepicker") {
59
99
  await util.filepicker(argv)
100
+ } else if (cmd === "upload") {
101
+ await util.upload(argv)
60
102
  } else if (cmd === "download") {
61
103
  await util.appDownload(argv)
62
104
  } else if (cmd === "registry") {
@@ -82,19 +124,27 @@ const isHttpUri = (value) => typeof value === "string" && /^https?:\/\//i.test(v
82
124
  await util.status(argv)
83
125
  } else if (cmd === "logs") {
84
126
  await util.logs(argv)
127
+ } else if (cmd === "open") {
128
+ await util.open(argv)
85
129
  } else if (cmd === "stop") {
86
130
  await script.stop(argv)
87
131
  } else if (cmd === "start") {
88
132
  if (argv._.length > 1) {
89
133
  let uri = argv._[1]
90
- await script.start(uri, true)
134
+ const startTarget = await resolveStartTarget(uri, argv.ref)
135
+ const startInput = extractStartInput(argv)
136
+ const startPayload = startInput
137
+ ? { uri: startTarget.uri, input: startInput }
138
+ : startTarget.uri
139
+ await script.start(startPayload, true, null, startTarget.controlPlane)
91
140
  } else {
92
141
  console.error("required argument: <uri>")
93
142
  }
94
143
  } else if (cmd === "run") {
95
144
  if (argv._.length > 1) {
96
145
  let _uri = argv._[1]
97
- const uri = isHttpUri(_uri) ? _uri : path.resolve(process.cwd(), _uri)
146
+ const runTarget = await resolveAppControlTarget(_uri)
147
+ const uri = runTarget.uri
98
148
  // try downloading first
99
149
  if (isHttpUri(uri)) {
100
150
  await util.download({
@@ -102,16 +152,18 @@ const isHttpUri = (value) => typeof value === "string" && /^https?:\/\//i.test(v
102
152
  no_exit: true
103
153
  })
104
154
  }
155
+ let launched = false
105
156
  while(true) {
106
- let default_target = await script.default_script(uri, argv.default)
157
+ let default_target = await script.default_script(uri, argv.default, runTarget.controlPlane)
107
158
  if (default_target) {
159
+ launched = true
108
160
  if (path.isAbsolute(default_target.uri)) {
109
161
  await new Promise((resolve, reject) => {
110
162
  script.start(default_target, false, (packet) => {
111
163
  if (packet.type === "result") {
112
164
  resolve()
113
165
  }
114
- })
166
+ }, runTarget.controlPlane)
115
167
  })
116
168
  if (script.killed) {
117
169
  break
@@ -133,6 +185,9 @@ const isHttpUri = (value) => typeof value === "string" && /^https?:\/\//i.test(v
133
185
  if (script.killed) {
134
186
  process.exit()
135
187
  }
188
+ if (!launched) {
189
+ process.exit(0)
190
+ }
136
191
  } else {
137
192
  console.error("required argument: <uri>")
138
193
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pterm",
3
- "version": "0.0.24",
3
+ "version": "0.0.25",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {