@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.
@@ -1,11 +1,10 @@
1
1
  import { defineCommand } from "../contract/command.js";
2
2
  import { value } from "../contract/schema.js";
3
- import { option, timeoutOption, withJson } from "./options.js";
3
+ import { launchOptions, option, timeoutOption, withJson } from "./options.js";
4
4
  import { dataOutput, eventOutput, eventPresentation, pageOutput, programListPresentation, programOutput, programPresentation } from "./schemas.js";
5
- import { connected, requireProgram } from "./connection.js";
6
- import { bounded, integer, page } from "./input.js";
7
- import { wait } from "./observation.js";
8
- import { processView, programView } from "./projection.js";
5
+ import { connected } from "./connection.js";
6
+ import { bounded, integer, json, launch, page } from "./input.js";
7
+ import { executeDescription } from "./execution.js";
9
8
  export default function programCommands(root, connect) {
10
9
  const programs = defineCommand(root, {
11
10
  name: "program",
@@ -14,29 +13,36 @@ export default function programCommands(root, connect) {
14
13
  });
15
14
  defineCommand(programs, {
16
15
  name: "list",
17
- description: "list Programs with bounded filtering",
16
+ description: executeDescription("program", "list"),
18
17
  requiresSystem: true,
19
18
  options: withJson(option("--installed-only", "return only installed Programs"), option("--search <text>", "case-insensitive identity, name, or description search"), option("--limit <count>", "maximum returned Programs", { parse: value => integer(value), default: 30 }), option("--offset <count>", "number of matching Programs to skip", { parse: value => integer(value), default: 0 })),
20
19
  output: dataOutput(pageOutput(programOutput, "matching Programs"), "A bounded page of Programs", programListPresentation),
21
20
  examples: ["phresh program list", "phresh program list --installed-only --json"]
22
21
  }, async ({ options }) => connected(connect, async (system) => {
23
- const programs = await system.program.list(options.installedOnly === true);
22
+ const programs = await system.execute({
23
+ $domain: "program",
24
+ $operation: "list",
25
+ installedOnly: options.installedOnly === true
26
+ });
24
27
  const selected = page(programs, options.search, bounded(options.offset, "--offset", 0), bounded(options.limit, "--limit", 1, 100), current => `${current.identity}\n${current.name}\n${current.description ?? ""}`);
25
- return { ...selected, data: await Promise.all(selected.data.map(programView)) };
28
+ return selected;
26
29
  }));
27
30
  defineCommand(programs, {
28
31
  name: "inspect",
29
- description: "read one Program declaration and installed state",
32
+ description: executeDescription("program", "find"),
30
33
  requiresSystem: true,
31
34
  options: withJson(option("--program <identity>", "Program identity", { mandatory: true })),
32
35
  output: dataOutput(programOutput, "The selected Program", programPresentation),
33
36
  examples: ["phresh program inspect --program terminal"]
34
37
  }, async ({ options }) => connected(connect, async (system) => {
35
- return await programView(await requireProgram(system, options.program));
38
+ const program = await system.execute({ $domain: "program", $operation: "find", identity: options.program });
39
+ if (!program)
40
+ throw new Error(`Unknown Program "${options.program}"`);
41
+ return program;
36
42
  }));
37
43
  defineCommand(programs, {
38
44
  name: "agent",
39
- description: "read a Program's own agent operating policy",
45
+ description: executeDescription("program", "agent"),
40
46
  requiresSystem: true,
41
47
  options: withJson(option("--program <identity>", "Program identity", { mandatory: true })),
42
48
  output: dataOutput(value.object({
@@ -48,15 +54,60 @@ export default function programCommands(root, connect) {
48
54
  }),
49
55
  examples: ["phresh program agent --program terminal --json"]
50
56
  }, async ({ options }) => connected(connect, async (system) => {
51
- const program = await requireProgram(system, options.program);
52
- const content = await program.agent();
53
- if (content === null)
54
- throw new Error(`Program "${program.identity}" has no agent documentation`);
55
- return { program: program.identity, content };
57
+ const result = await system.execute({ $domain: "program", $operation: "agent", identity: options.program });
58
+ if (result.content === null)
59
+ throw new Error(`Program "${result.program}" has no agent documentation`);
60
+ return result;
61
+ }));
62
+ defineCommand(programs, {
63
+ name: "getLaunch",
64
+ aliases: ["get-launch"],
65
+ description: executeDescription("program", "getLaunch"),
66
+ requiresSystem: true,
67
+ options: withJson(option("--program <identity>", "Program identity", { mandatory: true })),
68
+ output: dataOutput(value.any("Saved Process launch or null"), "The saved Program launch", { format: "value" }),
69
+ examples: ["phresh program get-launch --program terminal --json"]
70
+ }, ({ options }) => connected(connect, system => system.execute({
71
+ $domain: "program",
72
+ $operation: "getLaunch",
73
+ identity: options.program
74
+ })));
75
+ defineCommand(programs, {
76
+ name: "setLaunch",
77
+ aliases: ["set-launch"],
78
+ description: executeDescription("program", "setLaunch"),
79
+ requiresSystem: true,
80
+ options: withJson(option("--program <identity>", "Program identity", { mandatory: true }), ...launchOptions),
81
+ output: dataOutput(value.any("Saved Process launch"), "The saved Program launch", { format: "value" }),
82
+ examples: ["phresh program set-launch --program terminal --client --name main --json"]
83
+ }, ({ options }) => connected(connect, system => system.execute({
84
+ $domain: "program",
85
+ $operation: "setLaunch",
86
+ identity: options.program,
87
+ launch: launch(options)
88
+ })));
89
+ defineCommand(programs, {
90
+ name: "logs",
91
+ description: executeDescription("program", "logs"),
92
+ requiresSystem: true,
93
+ options: withJson(option("--program <identity>", "Program identity", { mandatory: true }), option("--statement <sql>", "read-only SQL statement", { mandatory: true }), option("--values <json>", "bound statement values encoded as a JSON array")),
94
+ output: dataOutput(value.array(value.any("log query row"), "log query rows"), "Program log query result", { format: "value" }),
95
+ examples: ["phresh program logs --program terminal --statement 'select createdAt, process, source, kind, content from logs order by createdAt desc limit 100' --json"]
96
+ }, ({ options }) => connected(connect, system => {
97
+ const parsed = options.values === undefined ? undefined : json(options.values, "--values");
98
+ if (parsed !== undefined && !Array.isArray(parsed))
99
+ throw new Error("--values must be a JSON array");
100
+ return system.execute({
101
+ $domain: "program",
102
+ $operation: "logs",
103
+ identity: options.program,
104
+ statement: options.statement,
105
+ ...(parsed === undefined ? {} : { values: parsed })
106
+ });
56
107
  }));
57
108
  defineCommand(programs, {
58
109
  name: "wait",
59
- description: "wait for one Program registry event",
110
+ description: executeDescription("program", "wait"),
60
111
  requiresSystem: true,
61
112
  options: withJson(option("--event <event>", "Program lifecycle event", {
62
113
  mandatory: true,
@@ -64,39 +115,11 @@ export default function programCommands(root, connect) {
64
115
  }), option("--program <identity>", "observe events belonging to one Program"), timeoutOption),
65
116
  output: dataOutput(eventOutput("The observed Program event", value.any("Program state or uninstall result")), "One Program event", eventPresentation),
66
117
  examples: ["phresh program wait --event create", "phresh program wait --event uninstall --program terminal --json"]
67
- }, async ({ options }) => connected(connect, async (system) => {
68
- if (options.program && (options.event === "create" || options.event === "install")) {
69
- throw new Error(`An individual Program does not emit ${options.event}`);
70
- }
71
- if (!options.program && (options.event === "processCreate" || options.event === "processExit")) {
72
- throw new Error(`${options.event} belongs to an individual Program`);
73
- }
74
- const target = options.program ? await requireProgram(system, options.program) : system.program;
75
- const message = await wait(target, options.event, timeout(options.timeout));
76
- return {
77
- scope: options.program ? `program:${options.program}` : "program",
78
- event: options.event,
79
- payload: await eventView(options.event, message, options.program ? target : undefined)
80
- };
81
- }));
82
- }
83
- async function eventView(event, message, scoped) {
84
- if (event === "uninstall") {
85
- if (scoped)
86
- return { program: await programView(scoped), purge: message.purge };
87
- const current = message;
88
- return { program: await programView(current.program), purge: current.purge };
89
- }
90
- if (event === "processCreate")
91
- return processView(message);
92
- if (event === "processExit") {
93
- const current = message;
94
- return { process: await processView(current.process), status: current.status, code: current.code, signal: current.signal };
95
- }
96
- if (scoped)
97
- return programView(scoped);
98
- return programView(message);
99
- }
100
- function timeout(value) {
101
- return value === undefined ? undefined : bounded(value, "--timeout", 1);
118
+ }, async ({ options }) => connected(connect, system => system.execute({
119
+ $domain: "program",
120
+ $operation: "wait",
121
+ event: options.event,
122
+ ...(options.program ? { program: options.program } : {}),
123
+ ...(options.timeout === undefined ? {} : { timeout: bounded(options.timeout, "--timeout", 1) })
124
+ })));
102
125
  }
@@ -36,14 +36,14 @@ export default function projectCommands(program, coreRange) {
36
36
  option("--build-command <command>", "prepare production files before use"),
37
37
  option("--server", "include a Server endpoint"),
38
38
  option("--server-location <path>", "production Server directory"),
39
- option("--server-start-command <command>", "production Server command"),
40
- option("--server-entry-file <path>", "production Server worker entry"),
41
- option("--server-development-start-command <command>", "development Server command"),
42
- option("--server-development-entry-file <path>", "development Server worker entry"),
39
+ option("--server-command <command>", "production Server host command"),
40
+ option("--server-worker <path>", "production Server Node Worker entry"),
41
+ option("--server-sandbox <path>", "production Server Sandbox entry"),
42
+ option("--server-dev-command <command>", "development Server command"),
43
43
  option("--client", "include a Client endpoint"),
44
44
  option("--client-location <path>", "production Client directory"),
45
- option("--client-development-url <url>", "fixed or external development Client URL"),
46
- option("--client-development-start-command <command>", "development Client command"),
45
+ option("--client-dev-url <url>", "fixed or external development Client URL"),
46
+ option("--client-dev-command <command>", "development Client command"),
47
47
  option("--force", "replace an existing phresh.config.ts")
48
48
  ],
49
49
  guidance: [
@@ -56,19 +56,19 @@ export default function projectCommands(program, coreRange) {
56
56
  await init({
57
57
  name: options.name,
58
58
  buildCommand: options.buildCommand,
59
- server: options.server === true || options.serverLocation !== undefined || options.serverStartCommand !== undefined || options.serverEntryFile !== undefined,
59
+ server: options.server === true || options.serverLocation !== undefined || options.serverCommand !== undefined || options.serverWorker !== undefined || options.serverSandbox !== undefined,
60
60
  serverLocation: options.serverLocation,
61
- serverStartCommand: options.serverStartCommand,
62
- serverEntryFile: options.serverEntryFile,
63
- serverDevelopmentStartCommand: options.serverDevelopmentStartCommand,
64
- serverDevelopmentEntryFile: options.serverDevelopmentEntryFile,
61
+ serverCommand: options.serverCommand,
62
+ serverWorker: options.serverWorker,
63
+ serverSandbox: options.serverSandbox,
64
+ serverDevCommand: options.serverDevCommand,
65
65
  client: options.client === true
66
66
  || options.clientLocation !== undefined
67
- || options.clientDevelopmentUrl !== undefined
68
- || options.clientDevelopmentStartCommand !== undefined,
67
+ || options.clientDevUrl !== undefined
68
+ || options.clientDevCommand !== undefined,
69
69
  clientLocation: options.clientLocation,
70
- clientDevelopmentUrl: options.clientDevelopmentUrl,
71
- clientDevelopmentStartCommand: options.clientDevelopmentStartCommand,
70
+ clientDevUrl: options.clientDevUrl,
71
+ clientDevCommand: options.clientDevCommand,
72
72
  force: options.force === true
73
73
  }, process.cwd(), coreRange);
74
74
  });
@@ -46,8 +46,9 @@ export async function endpointView(process, name) {
46
46
  }
47
47
  export async function windowView(process) {
48
48
  const window = process.client.window;
49
- const [title, position, size, minimized, maximized, front, layer] = await Promise.all([
49
+ const [title, header, position, size, minimized, maximized, front, layer] = await Promise.all([
50
50
  window.title(),
51
+ window.header(),
51
52
  window.position(),
52
53
  window.size(),
53
54
  window.minimized(),
@@ -55,5 +56,5 @@ export async function windowView(process) {
55
56
  window.front(),
56
57
  window.layer()
57
58
  ]);
58
- return { process: process.identity, title, position, size, minimized, maximized, front, layer };
59
+ return { process: process.identity, title, header, position, size, minimized, maximized, front, layer };
59
60
  }
@@ -55,31 +55,32 @@ export const windowOutput = value.object({
55
55
  layer: value.enumeration(layers, "Window layer")
56
56
  }, ["process", "title", "position", "size", "minimized", "maximized", "front", "layer"], "Window state");
57
57
  export const programPresentation = fields(["Identity", "identity"], ["Asset", "assetId"], ["Name", "name"], ["Version", "version"], ["Description", "description"], ["Installed", "installed"], ["Agent", "hasAgent"], ["Server", "server"], ["Client", "client"]);
58
- export const programListPresentation = table("data", "Program", "Programs", "No matching Programs", [
59
- { label: "Name", path: "name", width: 2 },
60
- { label: "Identity", path: "identity", width: 2 },
58
+ export const programListPresentation = list("data", "Program", "Programs", "No matching Programs", [
59
+ { label: "Name", path: "name" },
60
+ { label: "Identity", path: "identity" },
61
61
  { label: "Version", path: "version" },
62
62
  { label: "Installed", path: "installed" }
63
63
  ]);
64
64
  export const processPresentation = fields(["Identity", "identity"], ["Name", "name"], ["Program", "program"], ["Started", "startedAt"], ["Server declared", "server.declared"], ["Server running", "server.running"], ["Server service", "server.service"], ["Client declared", "client.declared"], ["Client running", "client.running"], ["Client service", "client.service"]);
65
65
  export const processActionPresentation = fields(["Process", "identity"], ["Name", "name"], ["Program", "program"], ["Server", "server.running"], ["Client", "client.running"]);
66
66
  export const processIdentityPresentation = fields(["Process", "identity"], ["Program", "program"]);
67
- export const processListPresentation = table("data", "Process", "Processes", "No matching Processes", [
68
- { label: "Name", path: "name", width: 2 },
69
- { label: "Identity", path: "identity", width: 2 },
70
- { label: "Program", path: "program", width: 2 },
67
+ export const processListPresentation = list("data", "Process", "Processes", "No matching Processes", [
68
+ { label: "Name", path: "name" },
69
+ { label: "Identity", path: "identity" },
70
+ { label: "Program", path: "program" },
71
71
  { label: "Server", path: "server.running" },
72
72
  { label: "Client", path: "client.running" }
73
73
  ]);
74
74
  export const endpointPresentation = fields(["Process", "process"], ["Program", "program"], ["Endpoint", "endpoint"], ["Declared", "declared"], ["Running", "running"], ["Service", "service"]);
75
75
  export const endpointActionPresentation = fields(["Process", "process"], ["Endpoint", "endpoint"], ["Running", "running"], ["Service", "service"]);
76
- export const windowPresentation = fields(["Process", "process"], ["Title", "title"], ["Position", "position"], ["Size", "size"], ["Minimized", "minimized"], ["Maximized", "maximized"], ["Front", "front"], ["Layer", "layer"], ["Location", "location"]);
76
+ export const windowPresentation = fields(["Process", "process"], ["Title", "title"], ["Header", "header"], ["Position", "position"], ["Size", "size"], ["Minimized", "minimized"], ["Maximized", "maximized"], ["Front", "front"], ["Layer", "layer"], ["Location", "location"]);
77
77
  export const windowPositionPresentation = fields(["Process", "process"], ["Position", "position"]);
78
78
  export const windowSizePresentation = fields(["Process", "process"], ["Size", "size"]);
79
79
  export const windowGeometryPresentation = fields(["Process", "process"], ["Position", "position"], ["Size", "size"]);
80
80
  export const windowMinimizePresentation = fields(["Process", "process"], ["Minimized", "minimized"]);
81
81
  export const windowMaximizePresentation = fields(["Process", "process"], ["Maximized", "maximized"]);
82
82
  export const windowTitlePresentation = fields(["Process", "process"], ["Title", "title"]);
83
+ export const windowHeaderPresentation = fields(["Process", "process"], ["Header", "header"]);
83
84
  export const windowRaisePresentation = fields(["Process", "process"], ["Front", "front"]);
84
85
  export const eventPresentation = fields(["Scope", "scope"], ["Event", "event"], ["Payload", "payload"]);
85
86
  export const lifecyclePresentation = fields(["Scope", "scope"], ["Event", "event"]);
@@ -118,6 +119,6 @@ function fields(...values) {
118
119
  fields: values.map(([label, path]) => ({ label, path }))
119
120
  };
120
121
  }
121
- function table(rows, item, items, empty, columns) {
122
- return { format: "table", rows, columns, item, items, empty, total: "total", truncated: "truncated" };
122
+ function list(rows, item, items, empty, fields) {
123
+ return { format: "list", rows, fields, item, items, empty, total: "total", truncated: "truncated" };
123
124
  }
@@ -1,110 +1,96 @@
1
+ import { parseExecuteRequest } from "@phreshos/core";
1
2
  import { defineCommand } from "../contract/command.js";
2
3
  import { option, processOptions, timeoutOption, withJson } from "./options.js";
3
- import { dataOutput, eventOutput, eventPresentation, windowGeometryPresentation, windowMinimizePresentation, windowMaximizePresentation, windowOutput, windowPositionPresentation, windowPresentation, windowRaisePresentation, windowSizePresentation, windowTitlePresentation } from "./schemas.js";
4
- import { connected, requireProcess } from "./connection.js";
4
+ import { dataOutput, eventOutput, eventPresentation, windowGeometryPresentation, windowHeaderPresentation, windowMinimizePresentation, windowMaximizePresentation, windowOutput, windowPositionPresentation, windowPresentation, windowRaisePresentation, windowSizePresentation, windowTitlePresentation } from "./schemas.js";
5
+ import { connected } from "./connection.js";
5
6
  import { bounded, position, size } from "./input.js";
6
- import { wait } from "./observation.js";
7
- import { windowOf, windowView } from "./projection.js";
7
+ import { executeDescription } from "./execution.js";
8
8
  export default function windowCommands(root, connect) {
9
9
  const windows = defineCommand(root, {
10
10
  name: "window",
11
11
  description: "inspect and control authoritative Client Windows",
12
12
  guidance: ["A Window belongs to the Client Endpoint of one exact Process."]
13
13
  });
14
- defineCommand(windows, state("inspect", "read the complete current Window state", windowPresentation), async ({ options }) => {
15
- return await withWindow(connect, options, windowView);
14
+ defineCommand(windows, state("inspect", windowPresentation), async ({ options }) => {
15
+ return executeWindow(connect, options, { $operation: "inspect" });
16
16
  });
17
17
  defineCommand(windows, {
18
- ...state("move", "change Window position", windowPositionPresentation),
18
+ ...state("move", windowPositionPresentation),
19
19
  options: withJson(...processOptions, option("--x <value>", "horizontal pixels or workspace-relative expression", { mandatory: true }), option("--y <value>", "vertical pixels or workspace-relative expression", { mandatory: true })),
20
20
  examples: ["phresh window move --process main --program terminal --x 50% --y 0"]
21
- }, async ({ options }) => withWindow(connect, options, async (process) => {
22
- await windowOf(process).move(position(options.x, options.y));
23
- return await windowView(process);
24
- }));
21
+ }, async ({ options }) => executeWindow(connect, options, { $operation: "move", position: position(options.x, options.y) }));
25
22
  defineCommand(windows, {
26
- ...state("resize", "change Window size", windowSizePresentation),
23
+ ...state("resize", windowSizePresentation),
27
24
  options: withJson(...processOptions, option("--width <value>", "width in pixels or a workspace-relative expression", { mandatory: true }), option("--height <value>", "height in pixels or a workspace-relative expression", { mandatory: true })),
28
25
  examples: ["phresh window resize --process main --program terminal --width 800 --height 600"]
29
- }, async ({ options }) => withWindow(connect, options, async (process) => {
30
- await windowOf(process).resize(size(options.width, options.height));
31
- return await windowView(process);
32
- }));
26
+ }, async ({ options }) => executeWindow(connect, options, { $operation: "resize", size: size(options.width, options.height) }));
33
27
  defineCommand(windows, {
34
- ...state("setGeometry", "change Window position and size atomically", windowGeometryPresentation),
28
+ ...state("setGeometry", windowGeometryPresentation),
35
29
  aliases: ["set-geometry"],
36
30
  options: withJson(...processOptions, option("--x <value>", "horizontal pixels or workspace-relative expression", { mandatory: true }), option("--y <value>", "vertical pixels or workspace-relative expression", { mandatory: true }), option("--width <value>", "width in pixels or a workspace-relative expression", { mandatory: true }), option("--height <value>", "height in pixels or a workspace-relative expression", { mandatory: true })),
37
31
  examples: ["phresh window set-geometry --process main --program terminal --x 0 --y 0 --width 100% --height 100%"]
38
- }, async ({ options }) => withWindow(connect, options, async (process) => {
39
- await windowOf(process).setGeometry({
40
- position: position(options.x, options.y),
41
- size: size(options.width, options.height)
42
- });
43
- return await windowView(process);
32
+ }, async ({ options }) => executeWindow(connect, options, {
33
+ $operation: "setGeometry",
34
+ position: position(options.x, options.y),
35
+ size: size(options.width, options.height)
44
36
  }));
45
37
  defineCommand(windows, {
46
- ...state("minimize", "set Window visibility without changing its order", windowMinimizePresentation),
38
+ ...state("minimize", windowMinimizePresentation),
47
39
  options: withJson(...processOptions, option("--restore", "restore rather than minimize the Window")),
48
40
  examples: ["phresh window minimize --process main --program terminal", "phresh window minimize --process main --program terminal --restore"]
49
- }, async ({ options }) => withWindow(connect, options, async (process) => {
50
- await windowOf(process).minimize(options.restore !== true);
51
- return await windowView(process);
52
- }));
41
+ }, async ({ options }) => executeWindow(connect, options, { $operation: "minimize", minimized: options.restore !== true }));
53
42
  defineCommand(windows, {
54
- ...state("maximize", "set Window maximization without changing visibility or stored geometry", windowMaximizePresentation),
43
+ ...state("maximize", windowMaximizePresentation),
55
44
  options: withJson(...processOptions, option("--restore", "restore rather than maximize the Window")),
56
45
  examples: ["phresh window maximize --process main --program terminal", "phresh window maximize --process main --program terminal --restore"]
57
- }, async ({ options }) => withWindow(connect, options, async (process) => {
58
- await windowOf(process).maximize(options.restore !== true);
59
- return await windowView(process);
60
- }));
46
+ }, async ({ options }) => executeWindow(connect, options, { $operation: "maximize", maximized: options.restore !== true }));
61
47
  defineCommand(windows, {
62
- ...state("changeTitle", "change the human-readable Window title", windowTitlePresentation),
48
+ ...state("changeTitle", windowTitlePresentation),
63
49
  aliases: ["change-title"],
64
50
  options: withJson(...processOptions, option("--title <title>", "new Window title", { mandatory: true })),
65
51
  examples: ["phresh window change-title --process main --program terminal --title Shell"]
66
- }, async ({ options }) => withWindow(connect, options, async (process) => {
67
- await windowOf(process).changeTitle(options.title);
68
- return await windowView(process);
69
- }));
52
+ }, async ({ options }) => executeWindow(connect, options, { $operation: "changeTitle", title: options.title }));
53
+ defineCommand(windows, {
54
+ ...state("changeHeader", windowHeaderPresentation),
55
+ aliases: ["change-header"],
56
+ options: withJson(...processOptions, option("--hide", "hide rather than show the Window header")),
57
+ examples: ["phresh window change-header --process main --program terminal --hide", "phresh window change-header --process main --program terminal"]
58
+ }, async ({ options }) => executeWindow(connect, options, { $operation: "changeHeader", header: options.hide !== true }));
70
59
  defineCommand(windows, {
71
- ...state("raise", "raise the Window within its own layer", windowRaisePresentation),
60
+ ...state("raise", windowRaisePresentation),
72
61
  examples: ["phresh window raise --process main --program terminal"]
73
- }, async ({ options }) => withWindow(connect, options, async (process) => {
74
- await windowOf(process).raise();
75
- return await windowView(process);
76
- }));
62
+ }, async ({ options }) => executeWindow(connect, options, { $operation: "raise" }));
77
63
  defineCommand(windows, {
78
64
  name: "wait",
79
- description: "wait for one authoritative Window change",
65
+ description: executeDescription("window", "wait"),
80
66
  requiresSystem: true,
81
67
  options: withJson(...processOptions, option("--event <event>", "Window event", {
82
68
  mandatory: true,
83
- choices: ["move", "resize", "geometry", "minimize", "maximize", "changeTitle", "front"]
69
+ choices: ["move", "resize", "geometry", "minimize", "maximize", "changeTitle", "changeHeader", "front"]
84
70
  }), timeoutOption),
85
71
  output: dataOutput(eventOutput("The observed Window event"), "One Window event", eventPresentation),
86
72
  examples: ["phresh window wait --process main --program terminal --event geometry --json"]
87
- }, async ({ options }) => withWindow(connect, options, async (process) => {
88
- return {
89
- scope: `window:${process.identity}`,
90
- event: options.event,
91
- payload: await wait(windowOf(process), options.event, options.timeout === undefined
92
- ? undefined
93
- : bounded(options.timeout, "--timeout", 1))
94
- };
73
+ }, async ({ options }) => executeWindow(connect, options, {
74
+ $operation: "wait",
75
+ event: options.event,
76
+ ...(options.timeout === undefined ? {} : { timeout: bounded(options.timeout, "--timeout", 1) })
95
77
  }));
96
78
  }
97
- function state(name, description, presentation) {
79
+ function state(name, presentation) {
98
80
  return {
99
81
  name,
100
- description,
82
+ description: executeDescription("window", name),
101
83
  requiresSystem: true,
102
84
  options: withJson(...processOptions),
103
85
  output: dataOutput(windowOutput, "The current Window state", presentation)
104
86
  };
105
87
  }
106
- async function withWindow(connect, options, action) {
107
- return await connected(connect, async (system) => {
108
- return await action(await requireProcess(system, options.process, options.program));
88
+ async function executeWindow(connect, options, operation) {
89
+ const request = parseExecuteRequest({
90
+ $domain: "window",
91
+ ...operation,
92
+ process: options.process,
93
+ ...(options.program ? { program: options.program } : {})
109
94
  });
95
+ return connected(connect, system => system.execute(request));
110
96
  }