@phreshos/cli 0.1.62 → 0.1.64

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
@@ -14,8 +14,8 @@ It owns command parsing, terminal output, packaging presentation, System release
14
14
  acquisition, and native service management.
15
15
 
16
16
  The CLI owns its command contract. Runtime command executors use
17
- `@phreshos/node` and its shared System domain handles; the CLI does not define a
18
- second System interface or transport request language.
17
+ `@phreshos/node` and Core's shared Execute operation catalog; the CLI does not
18
+ define a second System interface or transport request language.
19
19
 
20
20
  ## Installation
21
21
 
@@ -34,6 +34,7 @@ phresh dev
34
34
  phresh install
35
35
  phresh system status
36
36
  phresh program list
37
+ phresh execute '{"$domain":"operation","$operation":"list"}'
37
38
  ```
38
39
 
39
40
  Use `phresh describe` to inspect a command, or `phresh describe --all --json`
@@ -41,9 +42,9 @@ to read the complete machine-discoverable contract. See the
41
42
  [CLI documentation](https://docs.phreshos.com/sdks/cli) for Program project,
42
43
  System, and runtime commands.
43
44
 
44
- Runtime commands render responsive tables or labeled fields for people by
45
- default. Add `--json` to receive the complete result as one JSON value for
46
- automation.
45
+ Runtime commands render direct lists or labeled fields for people by default.
46
+ Add `--json` to receive the complete result as one JSON value for automation.
47
+ `phresh execute` accepts and returns JSON directly.
47
48
 
48
49
  ## Development
49
50
 
@@ -3,8 +3,12 @@ import processCommands from "./process.js";
3
3
  import programCommands from "./program.js";
4
4
  import { connectSystem } from "./connection.js";
5
5
  import windowCommands from "./window.js";
6
+ import executeCommand from "./execute.js";
7
+ import operationCommands from "./operation.js";
6
8
  /** Expose the shared System domains through explicit Node SDK executors. */
7
9
  export default function accessCommands(program, connect = connectSystem) {
10
+ executeCommand(program, connect);
11
+ operationCommands(program, connect);
8
12
  programCommands(program, connect);
9
13
  processCommands(program, connect);
10
14
  endpointCommands(program, connect);
@@ -1,11 +1,11 @@
1
+ import { parseExecuteRequest } from "@phreshos/core";
1
2
  import { defineCommand } from "../contract/command.js";
2
3
  import { value } from "../contract/schema.js";
3
4
  import { clientOverrideOptions, endpointOptions, option, serverOverrideOptions, timeoutOption, withJson } from "./options.js";
4
5
  import { dataOutput, endpointActionPresentation, endpointOutput, endpointPresentation, eventOutput, eventPresentation, lifecyclePresentation, valuePresentation } from "./schemas.js";
5
- import { connected, requireProcess } from "./connection.js";
6
+ import { connected } from "./connection.js";
6
7
  import { bounded, clientLaunch, payload, serverLaunch } from "./input.js";
7
- import { wait } from "./observation.js";
8
- import { endpoint, endpointView } from "./projection.js";
8
+ import { executeDescription } from "./execution.js";
9
9
  export default function endpointCommands(root, connect) {
10
10
  const endpoints = defineCommand(root, {
11
11
  name: "endpoint",
@@ -14,63 +14,55 @@ export default function endpointCommands(root, connect) {
14
14
  });
15
15
  defineCommand(endpoints, {
16
16
  name: "inspect",
17
- description: "read whether one Endpoint is declared and running",
17
+ description: executeDescription("endpoint", "inspect"),
18
18
  requiresSystem: true,
19
19
  options: withJson(...endpointOptions),
20
20
  output: dataOutput(endpointOutput, "The selected Endpoint", endpointPresentation),
21
21
  examples: ["phresh endpoint inspect --process main --program terminal --endpoint server"]
22
- }, async ({ options }) => withEndpoint(connect, options, async (process, name) => {
23
- return await endpointView(process, name);
24
- }));
22
+ }, async ({ options }) => executeEndpoint(connect, options, { $operation: "inspect" }));
25
23
  defineCommand(endpoints, {
26
24
  name: "start",
27
- description: "start a fresh Endpoint incarnation",
25
+ description: executeDescription("endpoint", "start"),
28
26
  requiresSystem: true,
29
27
  options: withJson(...endpointOptions, ...clientOverrideOptions, ...serverOverrideOptions),
30
28
  output: dataOutput(endpointOutput, "The started Endpoint", endpointActionPresentation),
31
29
  examples: ["phresh endpoint start --process main --program terminal --endpoint server --server-service"]
32
- }, async ({ options }) => withEndpoint(connect, options, async (process, name) => {
30
+ }, async ({ options }) => {
33
31
  const client = clientLaunch(options);
34
32
  const server = serverLaunch(options);
35
- if (name === "server" && client !== undefined)
33
+ if (options.endpoint === "server" && client !== undefined)
36
34
  throw new Error("Client overrides require --endpoint client");
37
- if (name === "client" && server !== undefined)
35
+ if (options.endpoint === "client" && server !== undefined)
38
36
  throw new Error("Server overrides require --endpoint server");
39
- if (name === "client")
40
- await process.client.start(typeof client === "object" ? client : undefined);
41
- else
42
- await process.server.start(typeof server === "object" ? server : undefined);
43
- return await endpointView(process, name);
44
- }));
37
+ const launch = options.endpoint === "client"
38
+ ? typeof client === "object" ? client : undefined
39
+ : typeof server === "object" ? server : undefined;
40
+ return executeEndpoint(connect, options, { $operation: "start", ...(launch ? { launch } : {}) });
41
+ });
45
42
  defineCommand(endpoints, {
46
43
  name: "stop",
47
- description: "stop one Endpoint",
44
+ description: executeDescription("endpoint", "stop"),
48
45
  requiresSystem: true,
49
46
  options: withJson(...endpointOptions),
50
47
  output: dataOutput(endpointOutput, "The stopped Endpoint", endpointActionPresentation),
51
48
  examples: ["phresh endpoint stop --process main --program terminal --endpoint client"]
52
- }, async ({ options }) => withEndpoint(connect, options, async (process, name) => {
53
- await endpoint(process, name).stop();
54
- return await endpointView(process, name);
55
- }));
49
+ }, async ({ options }) => executeEndpoint(connect, options, { $operation: "stop" }));
56
50
  defineCommand(endpoints, {
57
51
  name: "waitReady",
58
52
  aliases: ["wait-ready"],
59
- description: "wait until the Server Endpoint reports readiness",
53
+ description: executeDescription("endpoint", "waitReady"),
60
54
  requiresSystem: true,
61
55
  options: withJson(...endpointOptions, timeoutOption),
62
56
  output: dataOutput(endpointOutput, "The ready Server Endpoint", endpointActionPresentation),
63
57
  examples: ["phresh endpoint wait-ready --process main --program terminal --endpoint server --timeout 30000"]
64
- }, async ({ options }) => withEndpoint(connect, options, async (process, name) => {
65
- if (name !== "server")
66
- throw new Error("waitReady requires --endpoint server");
67
- await process.server.waitReady(timeout(options.timeout));
68
- return await endpointView(process, "server");
58
+ }, async ({ options }) => executeEndpoint(connect, options, {
59
+ $operation: "waitReady",
60
+ ...(options.timeout === undefined ? {} : { timeout: timeout(options.timeout) })
69
61
  }));
70
62
  defineCommand(endpoints, {
71
63
  name: "waitLifecycle",
72
64
  aliases: ["wait-lifecycle"],
73
- description: "wait for one lifecycle transition of an exact Endpoint",
65
+ description: executeDescription("endpoint", "waitLifecycle"),
74
66
  requiresSystem: true,
75
67
  options: withJson(...endpointOptions, option("--event <event>", "Endpoint lifecycle event", { mandatory: true, choices: ["start", "stop"] }), timeoutOption),
76
68
  output: dataOutput(value.object({
@@ -78,56 +70,61 @@ export default function endpointCommands(root, connect) {
78
70
  event: value.enumeration(["start", "stop"], "observed lifecycle event")
79
71
  }, ["scope", "event"], "Endpoint lifecycle event"), "One Endpoint lifecycle event", lifecyclePresentation),
80
72
  examples: ["phresh endpoint wait-lifecycle --process main --program terminal --endpoint server --event start"]
81
- }, async ({ options }) => withEndpoint(connect, options, async (process, name) => {
82
- await wait(endpoint(process, name).lifecycle, options.event, timeout(options.timeout));
83
- return { scope: `endpoint:${process.identity}:${name}:lifecycle`, event: options.event };
73
+ }, async ({ options }) => executeEndpoint(connect, options, {
74
+ $operation: "waitLifecycle",
75
+ event: options.event,
76
+ ...(options.timeout === undefined ? {} : { timeout: timeout(options.timeout) })
84
77
  }));
85
78
  defineCommand(endpoints, {
86
79
  name: "ask",
87
- description: "ask a Server event and return its answer",
80
+ description: executeDescription("endpoint", "ask"),
88
81
  requiresSystem: true,
89
82
  options: withJson(...endpointOptions, option("--event <event>", "event name", { mandatory: true }), option("--payload <json>", "arbitrary event payload as JSON"), timeoutOption),
90
83
  output: dataOutput(value.any("answer returned by the Server event contract"), "The Server answer", valuePresentation),
91
84
  examples: ["phresh endpoint ask --process main --program terminal --endpoint server --event status --json"]
92
- }, async ({ options }) => withEndpoint(connect, options, async (process, name) => {
93
- if (name !== "server")
94
- throw new Error("ask requires --endpoint server");
85
+ }, async ({ options }) => {
95
86
  const input = payload(options.payload);
96
- const answer = options.timeout === undefined
97
- ? await process.server.ask(options.event, input)
98
- : await process.server.timeout(timeout(options.timeout)).ask(options.event, input);
99
- return answer;
100
- }));
87
+ return executeEndpoint(connect, options, {
88
+ $operation: "ask",
89
+ event: options.event,
90
+ ...(options.payload === undefined ? {} : { input }),
91
+ ...(options.timeout === undefined ? {} : { timeout: timeout(options.timeout) })
92
+ });
93
+ });
101
94
  defineCommand(endpoints, {
102
95
  name: "publish",
103
- description: "publish one event without waiting for an answer",
96
+ description: executeDescription("endpoint", "publish"),
104
97
  requiresSystem: true,
105
98
  options: withJson(...endpointOptions, option("--event <event>", "event name", { mandatory: true }), option("--payload <json>", "arbitrary event payload as JSON")),
106
99
  output: dataOutput(endpointOutput, "The Endpoint after publishing", endpointActionPresentation),
107
100
  examples: ["phresh endpoint publish --process main --program terminal --endpoint client --event changed --payload '{\"value\":1}'"]
108
- }, async ({ options }) => withEndpoint(connect, options, async (process, name) => {
109
- endpoint(process, name).publish(options.event, payload(options.payload));
110
- return await endpointView(process, name);
101
+ }, async ({ options }) => executeEndpoint(connect, options, {
102
+ $operation: "publish",
103
+ event: options.event,
104
+ ...(options.payload === undefined ? {} : { input: payload(options.payload) })
111
105
  }));
112
106
  defineCommand(endpoints, {
113
107
  name: "wait",
114
- description: "wait for the next event emitted by one live Endpoint",
108
+ description: executeDescription("endpoint", "wait"),
115
109
  requiresSystem: true,
116
110
  options: withJson(...endpointOptions, option("--event <event>", "event name", { mandatory: true }), timeoutOption),
117
111
  output: dataOutput(eventOutput("The observed Endpoint event"), "One Endpoint event", eventPresentation),
118
112
  examples: ["phresh endpoint wait --process main --program terminal --endpoint client --event changed --json"]
119
- }, async ({ options }) => withEndpoint(connect, options, async (process, name) => {
120
- return {
121
- scope: `endpoint:${process.identity}:${name}`,
122
- event: options.event,
123
- payload: await wait(endpoint(process, name), options.event, timeout(options.timeout))
124
- };
113
+ }, async ({ options }) => executeEndpoint(connect, options, {
114
+ $operation: "wait",
115
+ event: options.event,
116
+ ...(options.timeout === undefined ? {} : { timeout: timeout(options.timeout) })
125
117
  }));
126
118
  }
127
- async function withEndpoint(connect, options, action) {
128
- return await connected(connect, async (system) => {
129
- return await action(await requireProcess(system, options.process, options.program), options.endpoint);
119
+ async function executeEndpoint(connect, options, operation) {
120
+ const request = parseExecuteRequest({
121
+ $domain: "endpoint",
122
+ ...operation,
123
+ process: options.process,
124
+ ...(options.program ? { program: options.program } : {}),
125
+ endpoint: options.endpoint
130
126
  });
127
+ return connected(connect, system => system.execute(request));
131
128
  }
132
129
  function timeout(value) {
133
130
  return value === undefined ? undefined : bounded(value, "--timeout", 1);
@@ -0,0 +1,30 @@
1
+ import { parseExecuteRequest } from "@phreshos/core";
2
+ import { defineCommand } from "../contract/command.js";
3
+ import { value } from "../contract/schema.js";
4
+ import { connected } from "./connection.js";
5
+ import { dataOutput } from "./schemas.js";
6
+ /** Expose the shared SDK Execute adapter as an exact JSON interface. */
7
+ export default function executeCommand(root, connect) {
8
+ defineCommand(root, {
9
+ name: "execute",
10
+ description: "execute one raw JSON operation through the Node SDK",
11
+ arguments: [{ syntax: "<request>", description: "Execute request encoded as JSON" }],
12
+ guidance: ["Use operation.list and operation.describe to discover the available request contracts."],
13
+ examples: [
14
+ "phresh execute '{\"$domain\":\"operation\",\"$operation\":\"list\"}'",
15
+ "phresh execute '{\"$domain\":\"endpoint\",\"$operation\":\"ask\",\"program\":\"tilo\",\"process\":\"main\",\"endpoint\":\"server\",\"event\":\"board.list\",\"input\":null}'"
16
+ ],
17
+ output: dataOutput(value.any("JSON result returned by the selected Execute operation"), "Execute result", { format: "json" }),
18
+ requiresSystem: true
19
+ }, async ({ arguments: [source] }) => {
20
+ let value;
21
+ try {
22
+ value = JSON.parse(source);
23
+ }
24
+ catch {
25
+ throw new Error("The Execute request must be valid JSON");
26
+ }
27
+ const request = parseExecuteRequest(value);
28
+ return connected(connect, system => system.execute(request));
29
+ });
30
+ }
@@ -0,0 +1,44 @@
1
+ import { describeExecuteOperation } from "@phreshos/core";
2
+ /** Human-facing CLI path for every operation in Core's Execute catalog. */
3
+ export const executeCommandPaths = Object.freeze({
4
+ "operation.list": ["operation", "list"],
5
+ "operation.describe": ["operation", "describe"],
6
+ "program.list": ["program", "list"],
7
+ "program.find": ["program", "inspect"],
8
+ "program.agent": ["program", "agent"],
9
+ "program.getLaunch": ["program", "getLaunch"],
10
+ "program.setLaunch": ["program", "setLaunch"],
11
+ "program.logs": ["program", "logs"],
12
+ "program.wait": ["program", "wait"],
13
+ "process.list": ["process", "list"],
14
+ "process.find": ["process", "inspect"],
15
+ "process.create": ["process", "create"],
16
+ "process.findOrCreate": ["process", "findOrCreate"],
17
+ "process.exit": ["process", "exit"],
18
+ "process.wait": ["process", "wait"],
19
+ "endpoint.inspect": ["endpoint", "inspect"],
20
+ "endpoint.start": ["endpoint", "start"],
21
+ "endpoint.stop": ["endpoint", "stop"],
22
+ "endpoint.waitReady": ["endpoint", "waitReady"],
23
+ "endpoint.ask": ["endpoint", "ask"],
24
+ "endpoint.publish": ["endpoint", "publish"],
25
+ "endpoint.wait": ["endpoint", "wait"],
26
+ "endpoint.waitLifecycle": ["endpoint", "waitLifecycle"],
27
+ "window.inspect": ["window", "inspect"],
28
+ "window.move": ["window", "move"],
29
+ "window.resize": ["window", "resize"],
30
+ "window.setGeometry": ["window", "setGeometry"],
31
+ "window.minimize": ["window", "minimize"],
32
+ "window.maximize": ["window", "maximize"],
33
+ "window.changeTitle": ["window", "changeTitle"],
34
+ "window.changeHeader": ["window", "changeHeader"],
35
+ "window.raise": ["window", "raise"],
36
+ "window.wait": ["window", "wait"]
37
+ });
38
+ /** Read command language from the same catalog that defines raw execution. */
39
+ export function executeDescription(domain, operation) {
40
+ const description = describeExecuteOperation(domain, operation);
41
+ if (!description)
42
+ throw new Error(`Unknown Execute operation ${domain}.${operation}`);
43
+ return description.description;
44
+ }
@@ -2,11 +2,14 @@ import { parseLaunch } from "@phreshos/core";
2
2
  export function payload(value) {
3
3
  if (value === undefined)
4
4
  return undefined;
5
+ return json(value, "--payload");
6
+ }
7
+ export function json(value, name) {
5
8
  try {
6
9
  return JSON.parse(value);
7
10
  }
8
11
  catch {
9
- throw new Error("--payload must be valid JSON");
12
+ throw new Error(`${name} must be valid JSON`);
10
13
  }
11
14
  }
12
15
  export function metric(value) {
@@ -0,0 +1,65 @@
1
+ import { defineCommand } from "../contract/command.js";
2
+ import { value } from "../contract/schema.js";
3
+ import { connected } from "./connection.js";
4
+ import { executeDescription } from "./execution.js";
5
+ import { option, withJson } from "./options.js";
6
+ import { dataOutput, valuePresentation } from "./schemas.js";
7
+ const summary = value.object({
8
+ domain: value.string("operation domain"),
9
+ operation: value.string("operation name"),
10
+ description: value.string("operation meaning")
11
+ }, ["domain", "operation", "description"], "Execute operation");
12
+ const description = value.object({
13
+ domain: value.string("operation domain"),
14
+ operation: value.string("operation name"),
15
+ description: value.string("operation meaning"),
16
+ request: value.any("request JSON Schema"),
17
+ result: value.any("successful result JSON Schema")
18
+ }, ["domain", "operation", "description", "request", "result"], "Execute operation contract");
19
+ export default function operationCommands(root, connect) {
20
+ const operations = defineCommand(root, {
21
+ name: "operation",
22
+ description: "discover operations available through Execute"
23
+ });
24
+ defineCommand(operations, {
25
+ name: "list",
26
+ description: executeDescription("operation", "list"),
27
+ requiresSystem: true,
28
+ options: withJson(option("--domain <domain>", "restrict results to one operation domain")),
29
+ output: dataOutput(value.array(summary, "Execute operations"), "Available Execute operations", {
30
+ format: "list",
31
+ rows: "",
32
+ fields: [
33
+ { label: "Domain", path: "domain" },
34
+ { label: "Operation", path: "operation" },
35
+ { label: "Description", path: "description" }
36
+ ],
37
+ item: "Operation",
38
+ items: "Operations",
39
+ empty: "No matching operations"
40
+ }),
41
+ examples: ["phresh operation list", "phresh operation list --domain endpoint --json"]
42
+ }, ({ options }) => connected(connect, system => system.execute({
43
+ $domain: "operation",
44
+ $operation: "list",
45
+ ...(options.domain ? { domain: options.domain } : {})
46
+ })));
47
+ defineCommand(operations, {
48
+ name: "describe",
49
+ description: executeDescription("operation", "describe"),
50
+ requiresSystem: true,
51
+ options: withJson(option("--domain <domain>", "operation domain", { mandatory: true }), option("--operation <operation>", "operation name", { mandatory: true })),
52
+ output: dataOutput(description, "Execute operation contract", valuePresentation),
53
+ examples: ["phresh operation describe --domain endpoint --operation ask --json"]
54
+ }, ({ options }) => connected(connect, async (system) => {
55
+ const result = await system.execute({
56
+ $domain: "operation",
57
+ $operation: "describe",
58
+ domain: options.domain,
59
+ operation: options.operation
60
+ });
61
+ if (!result)
62
+ throw new Error(`Unknown Execute operation ${options.domain}.${options.operation}`);
63
+ return result;
64
+ }));
65
+ }
@@ -2,10 +2,9 @@ import { defineCommand } from "../contract/command.js";
2
2
  import { value } from "../contract/schema.js";
3
3
  import { launchOptions, namedLaunchOptions, option, processOptions, timeoutOption, withJson } from "./options.js";
4
4
  import { dataOutput, eventOutput, eventPresentation, pageOutput, processActionPresentation, processIdentityPresentation, processListPresentation, processOutput, processPresentation } from "./schemas.js";
5
- import { connected, requireProcess, requireProgram } from "./connection.js";
5
+ import { connected } from "./connection.js";
6
6
  import { bounded, integer, launch, page } from "./input.js";
7
- import { wait } from "./observation.js";
8
- import { processView } from "./projection.js";
7
+ import { executeDescription } from "./execution.js";
9
8
  export default function processCommands(root, connect) {
10
9
  const processes = defineCommand(root, {
11
10
  name: "process",
@@ -14,99 +13,97 @@ export default function processCommands(root, connect) {
14
13
  });
15
14
  defineCommand(processes, {
16
15
  name: "list",
17
- description: "list live Processes with bounded filtering",
16
+ description: executeDescription("process", "list"),
18
17
  requiresSystem: true,
19
18
  options: withJson(option("--program <identity>", "restrict results to one Program"), option("--search <text>", "case-insensitive identity or name search"), option("--limit <count>", "maximum returned Processes", { parse: value => integer(value), default: 30 }), option("--offset <count>", "number of matching Processes to skip", { parse: value => integer(value), default: 0 })),
20
19
  output: dataOutput(pageOutput(processOutput, "matching Processes"), "A bounded page of Processes", processListPresentation),
21
20
  examples: ["phresh process list", "phresh process list --program terminal --json"]
22
21
  }, async ({ options }) => connected(connect, async (system) => {
23
- const processes = options.program
24
- ? await (await requireProgram(system, options.program)).processes()
25
- : await system.process.list();
22
+ const processes = await system.execute({
23
+ $domain: "process",
24
+ $operation: "list",
25
+ ...(options.program ? { program: options.program } : {})
26
+ });
26
27
  const selected = page(processes, options.search, bounded(options.offset, "--offset", 0), bounded(options.limit, "--limit", 1, 100), current => `${current.identity}\n${current.name ?? ""}`);
27
- return { ...selected, data: await Promise.all(selected.data.map(processView)) };
28
+ return selected;
28
29
  }));
29
30
  defineCommand(processes, {
30
31
  name: "inspect",
31
- description: "read one live Process and its Endpoint state",
32
+ description: executeDescription("process", "find"),
32
33
  requiresSystem: true,
33
34
  options: withJson(...processOptions),
34
35
  output: dataOutput(processOutput, "The selected Process", processPresentation),
35
36
  examples: ["phresh process inspect --process main --program terminal"]
36
37
  }, async ({ options }) => connected(connect, async (system) => {
37
- return await processView(await requireProcess(system, options.process, options.program));
38
+ const process = await system.execute({
39
+ $domain: "process",
40
+ $operation: "find",
41
+ process: options.process,
42
+ ...(options.program ? { program: options.program } : {})
43
+ });
44
+ if (!process)
45
+ throw new Error(`Unknown Process "${options.process}"`);
46
+ return process;
38
47
  }));
39
48
  defineCommand(processes, {
40
49
  name: "create",
41
- description: "create a Process",
50
+ description: executeDescription("process", "create"),
42
51
  requiresSystem: true,
43
52
  options: withJson(option("--program <identity>", "owning Program identity", { mandatory: true }), ...launchOptions),
44
53
  output: dataOutput(processOutput, "The created Process", processActionPresentation),
45
54
  examples: ["phresh process create --program terminal --server --client", "phresh process create --program terminal --name main --json"]
46
55
  }, async ({ options }) => connected(connect, async (system) => {
47
- const program = await requireProgram(system, options.program);
48
- return await processView(await program.createProcess(launch(options)));
56
+ return system.execute({
57
+ $domain: "process",
58
+ $operation: "create",
59
+ program: options.program,
60
+ launch: launch(options)
61
+ });
49
62
  }));
50
63
  defineCommand(processes, {
51
64
  name: "findOrCreate",
52
65
  aliases: ["find-or-create"],
53
- description: "find the named Process or create it atomically",
66
+ description: executeDescription("process", "findOrCreate"),
54
67
  requiresSystem: true,
55
68
  options: withJson(option("--program <identity>", "owning Program identity", { mandatory: true }), ...namedLaunchOptions),
56
69
  output: dataOutput(processOutput, "The existing or created Process", processActionPresentation),
57
70
  examples: ["phresh process find-or-create --program terminal --name main --json"]
58
71
  }, async ({ options }) => connected(connect, async (system) => {
59
- const program = await requireProgram(system, options.program);
60
- return await processView(await program.findOrCreateProcess(launch(options, true)));
72
+ return system.execute({
73
+ $domain: "process",
74
+ $operation: "findOrCreate",
75
+ program: options.program,
76
+ launch: launch(options, true)
77
+ });
61
78
  }));
62
79
  defineCommand(processes, {
63
80
  name: "exit",
64
- description: "exit one Process and all of its live Endpoints",
81
+ description: executeDescription("process", "exit"),
65
82
  requiresSystem: true,
66
83
  options: withJson(...processOptions),
67
84
  output: dataOutput(processOutput, "The Process state immediately before exit", processIdentityPresentation),
68
85
  examples: ["phresh process exit --process main --program terminal"]
69
86
  }, async ({ options }) => connected(connect, async (system) => {
70
- const process = await requireProcess(system, options.process, options.program);
71
- const snapshot = await processView(process);
72
- await process.exit();
73
- return snapshot;
87
+ return system.execute({
88
+ $domain: "process",
89
+ $operation: "exit",
90
+ process: options.process,
91
+ ...(options.program ? { program: options.program } : {})
92
+ });
74
93
  }));
75
94
  defineCommand(processes, {
76
95
  name: "wait",
77
- description: "wait for one Process lifecycle event",
96
+ description: executeDescription("process", "wait"),
78
97
  requiresSystem: true,
79
98
  options: withJson(option("--event <event>", "Process lifecycle event", { mandatory: true, choices: ["create", "exit"] }), option("--process <identity>", "scope the event to one Process"), option("--program <identity>", "scope the event to one Program"), timeoutOption),
80
99
  output: dataOutput(eventOutput("The observed Process event", value.any("Process state or exit result")), "One Process event", eventPresentation),
81
100
  examples: ["phresh process wait --event create", "phresh process wait --event exit --process main --program terminal --json"]
82
- }, async ({ options }) => connected(connect, async (system) => {
83
- if (options.process && options.event === "create")
84
- throw new Error("An individual Process does not emit create");
85
- const timeout = options.timeout === undefined ? undefined : bounded(options.timeout, "--timeout", 1);
86
- const target = options.process
87
- ? await requireProcess(system, options.process, options.program)
88
- : options.program
89
- ? await requireProgram(system, options.program)
90
- : system.process;
91
- const message = options.program && !options.process
92
- ? await wait(target, options.event === "create" ? "processCreate" : "processExit", timeout)
93
- : await wait(target, options.event, timeout);
94
- return {
95
- scope: options.process ? `process:${options.process}` : options.program ? `program:${options.program}` : "process",
96
- event: options.event,
97
- payload: await eventView(options.event, message, options.process ? target : undefined)
98
- };
99
- }));
100
- }
101
- async function eventView(event, message, scoped) {
102
- if (event === "create")
103
- return processView(message);
104
- const exit = message;
105
- const process = exit.process ?? scoped;
106
- return {
107
- ...(process ? { process: await processView(process) } : {}),
108
- status: exit.status,
109
- code: exit.code,
110
- signal: exit.signal
111
- };
101
+ }, async ({ options }) => connected(connect, system => system.execute({
102
+ $domain: "process",
103
+ $operation: "wait",
104
+ event: options.event,
105
+ ...(options.process ? { process: options.process } : {}),
106
+ ...(options.program ? { program: options.program } : {}),
107
+ ...(options.timeout === undefined ? {} : { timeout: bounded(options.timeout, "--timeout", 1) })
108
+ })));
112
109
  }