@phreshos/cli 0.1.65 → 0.1.67
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/dist/commands/access.js +2 -0
- package/dist/commands/execution.js +26 -4
- package/dist/commands/options.js +4 -4
- package/dist/commands/program.js +148 -13
- package/dist/commands/project.js +1 -1
- package/dist/commands/projection.js +12 -9
- package/dist/commands/schemas.js +62 -10
- package/dist/commands/service.js +133 -0
- package/dist/commands/window.js +93 -14
- package/dist/install.js +2 -3
- package/dist/program-installation.js +3 -2
- package/dist/template/package.json +6 -6
- package/dist/template/phresh.config.ts +1 -1
- package/dist/template.json +2 -2
- package/package.json +3 -3
package/dist/commands/access.js
CHANGED
|
@@ -5,6 +5,7 @@ import { connectSystem } from "./connection.js";
|
|
|
5
5
|
import windowCommands from "./window.js";
|
|
6
6
|
import executeCommand from "./execute.js";
|
|
7
7
|
import operationCommands from "./operation.js";
|
|
8
|
+
import serviceCommands from "./service.js";
|
|
8
9
|
/** Expose the shared System domains through explicit Node SDK executors. */
|
|
9
10
|
export default function accessCommands(program, connect = connectSystem) {
|
|
10
11
|
executeCommand(program, connect);
|
|
@@ -12,5 +13,6 @@ export default function accessCommands(program, connect = connectSystem) {
|
|
|
12
13
|
programCommands(program, connect);
|
|
13
14
|
processCommands(program, connect);
|
|
14
15
|
endpointCommands(program, connect);
|
|
16
|
+
serviceCommands(program, connect);
|
|
15
17
|
windowCommands(program, connect);
|
|
16
18
|
}
|
|
@@ -6,8 +6,19 @@ export const executeCommandPaths = Object.freeze({
|
|
|
6
6
|
"program.list": ["program", "list"],
|
|
7
7
|
"program.find": ["program", "inspect"],
|
|
8
8
|
"program.agent": ["program", "agent"],
|
|
9
|
-
"program.
|
|
10
|
-
"program.
|
|
9
|
+
"program.definition": ["program", "definition"],
|
|
10
|
+
"program.getStartup": ["program", "getStartup"],
|
|
11
|
+
"program.enableStartup": ["program", "enableStartup"],
|
|
12
|
+
"program.disableStartup": ["program", "disableStartup"],
|
|
13
|
+
"program.pinned": ["program", "pinned"],
|
|
14
|
+
"program.pin": ["program", "pin"],
|
|
15
|
+
"program.unpin": ["program", "unpin"],
|
|
16
|
+
"program.getPermission": ["program", "getPermission"],
|
|
17
|
+
"program.listPermissions": ["program", "listPermissions"],
|
|
18
|
+
"program.allowsPermission": ["program", "allowsPermission"],
|
|
19
|
+
"program.allowPermission": ["program", "allowPermission"],
|
|
20
|
+
"program.denyPermission": ["program", "denyPermission"],
|
|
21
|
+
"program.requestPermission": ["program", "requestPermission"],
|
|
11
22
|
"program.logs": ["program", "logs"],
|
|
12
23
|
"program.wait": ["program", "wait"],
|
|
13
24
|
"process.list": ["process", "list"],
|
|
@@ -24,14 +35,25 @@ export const executeCommandPaths = Object.freeze({
|
|
|
24
35
|
"endpoint.publish": ["endpoint", "publish"],
|
|
25
36
|
"endpoint.wait": ["endpoint", "wait"],
|
|
26
37
|
"endpoint.waitLifecycle": ["endpoint", "waitLifecycle"],
|
|
38
|
+
"service.list": ["service", "list"],
|
|
39
|
+
"service.search": ["service", "search"],
|
|
40
|
+
"service.inspect": ["service", "inspect"],
|
|
41
|
+
"service.waitReady": ["service", "waitReady"],
|
|
42
|
+
"service.ask": ["service", "ask"],
|
|
43
|
+
"service.publish": ["service", "publish"],
|
|
44
|
+
"service.wait": ["service", "wait"],
|
|
45
|
+
"service.waitLifecycle": ["service", "waitLifecycle"],
|
|
46
|
+
"service.waitDiscovery": ["service", "waitDiscovery"],
|
|
27
47
|
"window.inspect": ["window", "inspect"],
|
|
28
48
|
"window.move": ["window", "move"],
|
|
29
49
|
"window.resize": ["window", "resize"],
|
|
30
50
|
"window.setGeometry": ["window", "setGeometry"],
|
|
31
51
|
"window.minimize": ["window", "minimize"],
|
|
32
52
|
"window.maximize": ["window", "maximize"],
|
|
33
|
-
"window.
|
|
34
|
-
"window.
|
|
53
|
+
"window.setTitle": ["window", "setTitle"],
|
|
54
|
+
"window.setHeader": ["window", "setHeader"],
|
|
55
|
+
"window.setFrame": ["window", "setFrame"],
|
|
56
|
+
"window.setTransaction": ["window", "setTransaction"],
|
|
35
57
|
"window.raise": ["window", "raise"],
|
|
36
58
|
"window.wait": ["window", "wait"]
|
|
37
59
|
});
|
package/dist/commands/options.js
CHANGED
|
@@ -10,8 +10,8 @@ export const endpointOptions = Object.freeze([
|
|
|
10
10
|
option("--endpoint <endpoint>", "Endpoint kind", { mandatory: true, choices: ["server", "client"] })
|
|
11
11
|
]);
|
|
12
12
|
export const clientOverrideOptions = Object.freeze([
|
|
13
|
-
option("--client-service", "
|
|
14
|
-
option("--no-client-service", "
|
|
13
|
+
option("--client-service", "make this Client execution context available through Service discovery"),
|
|
14
|
+
option("--no-client-service", "keep this Client execution context out of Service discovery"),
|
|
15
15
|
option("--client-title <title>", "initial Window title"),
|
|
16
16
|
option("--client-width <value>", "initial Window width"),
|
|
17
17
|
option("--client-height <value>", "initial Window height"),
|
|
@@ -22,8 +22,8 @@ export const clientOverrideOptions = Object.freeze([
|
|
|
22
22
|
option("--client-maximized", "open the Window maximized")
|
|
23
23
|
]);
|
|
24
24
|
export const serverOverrideOptions = Object.freeze([
|
|
25
|
-
option("--server-service", "
|
|
26
|
-
option("--no-server-service", "
|
|
25
|
+
option("--server-service", "make this Server execution context available through Service discovery"),
|
|
26
|
+
option("--no-server-service", "keep this Server execution context out of Service discovery")
|
|
27
27
|
]);
|
|
28
28
|
export const launchOptions = Object.freeze([
|
|
29
29
|
...serverOverrideOptions,
|
package/dist/commands/program.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { parsePermissionName } from "@phreshos/core";
|
|
1
2
|
import { defineCommand } from "../contract/command.js";
|
|
2
3
|
import { value } from "../contract/schema.js";
|
|
3
4
|
import { launchOptions, option, timeoutOption, withJson } from "./options.js";
|
|
@@ -60,32 +61,157 @@ export default function programCommands(root, connect) {
|
|
|
60
61
|
return result;
|
|
61
62
|
}));
|
|
62
63
|
defineCommand(programs, {
|
|
63
|
-
name: "
|
|
64
|
-
|
|
65
|
-
description: executeDescription("program", "getLaunch"),
|
|
64
|
+
name: "definition",
|
|
65
|
+
description: executeDescription("program", "definition"),
|
|
66
66
|
requiresSystem: true,
|
|
67
67
|
options: withJson(option("--program <identity>", "Program identity", { mandatory: true })),
|
|
68
|
-
output: dataOutput(value.any("
|
|
69
|
-
examples: ["phresh program
|
|
68
|
+
output: dataOutput(value.any("Complete canonical Program definition"), "The Program definition", { format: "value" }),
|
|
69
|
+
examples: ["phresh program definition --program terminal --json"]
|
|
70
70
|
}, ({ options }) => connected(connect, system => system.execute({
|
|
71
71
|
$domain: "program",
|
|
72
|
-
$operation: "
|
|
72
|
+
$operation: "definition",
|
|
73
73
|
identity: options.program
|
|
74
74
|
})));
|
|
75
75
|
defineCommand(programs, {
|
|
76
|
-
name: "
|
|
77
|
-
aliases: ["
|
|
78
|
-
description: executeDescription("program", "
|
|
76
|
+
name: "getStartup",
|
|
77
|
+
aliases: ["get-startup"],
|
|
78
|
+
description: executeDescription("program", "getStartup"),
|
|
79
|
+
requiresSystem: true,
|
|
80
|
+
options: withJson(option("--program <identity>", "Program identity", { mandatory: true })),
|
|
81
|
+
output: dataOutput(value.any("Stored System-start launch or null"), "The Program startup launch", { format: "value" }),
|
|
82
|
+
examples: ["phresh program get-startup --program terminal --json"]
|
|
83
|
+
}, ({ options }) => connected(connect, system => system.execute({
|
|
84
|
+
$domain: "program",
|
|
85
|
+
$operation: "getStartup",
|
|
86
|
+
identity: options.program
|
|
87
|
+
})));
|
|
88
|
+
defineCommand(programs, {
|
|
89
|
+
name: "enableStartup",
|
|
90
|
+
aliases: ["enable-startup"],
|
|
91
|
+
description: executeDescription("program", "enableStartup"),
|
|
79
92
|
requiresSystem: true,
|
|
80
93
|
options: withJson(option("--program <identity>", "Program identity", { mandatory: true }), ...launchOptions),
|
|
81
|
-
output: dataOutput(value.any("
|
|
82
|
-
examples: ["phresh program
|
|
94
|
+
output: dataOutput(value.any("Stored System-start launch"), "The Program startup launch", { format: "value" }),
|
|
95
|
+
examples: ["phresh program enable-startup --program terminal --client --name main --json"]
|
|
83
96
|
}, ({ options }) => connected(connect, system => system.execute({
|
|
84
97
|
$domain: "program",
|
|
85
|
-
$operation: "
|
|
98
|
+
$operation: "enableStartup",
|
|
86
99
|
identity: options.program,
|
|
87
100
|
launch: launch(options)
|
|
88
101
|
})));
|
|
102
|
+
defineCommand(programs, {
|
|
103
|
+
name: "disableStartup",
|
|
104
|
+
aliases: ["disable-startup"],
|
|
105
|
+
description: executeDescription("program", "disableStartup"),
|
|
106
|
+
requiresSystem: true,
|
|
107
|
+
options: withJson(option("--program <identity>", "Program identity", { mandatory: true })),
|
|
108
|
+
output: dataOutput(value.nullable(value.any("disabled startup")), "Startup is disabled", { format: "value" }),
|
|
109
|
+
examples: ["phresh program disable-startup --program terminal"]
|
|
110
|
+
}, ({ options }) => connected(connect, system => system.execute({
|
|
111
|
+
$domain: "program",
|
|
112
|
+
$operation: "disableStartup",
|
|
113
|
+
identity: options.program
|
|
114
|
+
})));
|
|
115
|
+
for (const operation of ["pinned", "pin", "unpin"])
|
|
116
|
+
defineCommand(programs, {
|
|
117
|
+
name: operation,
|
|
118
|
+
description: executeDescription("program", operation),
|
|
119
|
+
requiresSystem: true,
|
|
120
|
+
options: withJson(option("--program <identity>", "Program identity", { mandatory: true })),
|
|
121
|
+
output: dataOutput(value.boolean("whether the Program is pinned"), "The Program pinned state", { format: "value" }),
|
|
122
|
+
examples: [`phresh program ${operation} --program terminal`]
|
|
123
|
+
}, ({ options }) => connected(connect, system => system.execute({
|
|
124
|
+
$domain: "program",
|
|
125
|
+
$operation: operation,
|
|
126
|
+
identity: options.program
|
|
127
|
+
})));
|
|
128
|
+
defineCommand(programs, {
|
|
129
|
+
name: "getPermission",
|
|
130
|
+
aliases: ["get-permission"],
|
|
131
|
+
description: executeDescription("program", "getPermission"),
|
|
132
|
+
requiresSystem: true,
|
|
133
|
+
options: withJson(option("--program <identity>", "Program identity", { mandatory: true }), option("--permission <name>", "permission name", { mandatory: true })),
|
|
134
|
+
output: dataOutput(value.any("effective permission assignment"), "The effective permission", { format: "value" }),
|
|
135
|
+
examples: ["phresh program get-permission --program terminal --permission network --json"]
|
|
136
|
+
}, ({ options }) => connected(connect, system => system.execute({
|
|
137
|
+
$domain: "program",
|
|
138
|
+
$operation: "getPermission",
|
|
139
|
+
identity: options.program,
|
|
140
|
+
permission: parsePermissionName(options.permission)
|
|
141
|
+
})));
|
|
142
|
+
defineCommand(programs, {
|
|
143
|
+
name: "listPermissions",
|
|
144
|
+
aliases: ["list-permissions"],
|
|
145
|
+
description: executeDescription("program", "listPermissions"),
|
|
146
|
+
requiresSystem: true,
|
|
147
|
+
options: withJson(option("--program <identity>", "Program identity", { mandatory: true })),
|
|
148
|
+
output: dataOutput(value.any("effective permission assignments"), "The effective permissions", { format: "value" }),
|
|
149
|
+
examples: ["phresh program list-permissions --program terminal --json"]
|
|
150
|
+
}, ({ options }) => connected(connect, system => system.execute({
|
|
151
|
+
$domain: "program",
|
|
152
|
+
$operation: "listPermissions",
|
|
153
|
+
identity: options.program
|
|
154
|
+
})));
|
|
155
|
+
defineCommand(programs, {
|
|
156
|
+
name: "allowsPermission",
|
|
157
|
+
aliases: ["allows-permission"],
|
|
158
|
+
description: executeDescription("program", "allowsPermission"),
|
|
159
|
+
requiresSystem: true,
|
|
160
|
+
options: withJson(option("--program <identity>", "Program identity", { mandatory: true }), option("--permission <name>", "permission name", { mandatory: true }), option("--value <json>", "requested permission value encoded as JSON")),
|
|
161
|
+
output: dataOutput(value.boolean("whether the requested access is allowed"), "The permission decision", { format: "value" }),
|
|
162
|
+
examples: ["phresh program allows-permission --program terminal --permission network --value '[\"https://example.com\"]'"]
|
|
163
|
+
}, ({ options }) => connected(connect, system => system.execute({
|
|
164
|
+
$domain: "program",
|
|
165
|
+
$operation: "allowsPermission",
|
|
166
|
+
identity: options.program,
|
|
167
|
+
permission: parsePermissionName(options.permission),
|
|
168
|
+
...(options.value === undefined ? {} : { value: permissionRequest(options.value) })
|
|
169
|
+
})));
|
|
170
|
+
defineCommand(programs, {
|
|
171
|
+
name: "allowPermission",
|
|
172
|
+
aliases: ["allow-permission"],
|
|
173
|
+
description: executeDescription("program", "allowPermission"),
|
|
174
|
+
requiresSystem: true,
|
|
175
|
+
options: withJson(option("--program <identity>", "Program identity", { mandatory: true }), option("--permission <name>", "permission name", { mandatory: true }), option("--value <json>", "complete allowed permission value encoded as JSON")),
|
|
176
|
+
output: dataOutput(value.any("stored permission assignment"), "The stored permission", { format: "value" }),
|
|
177
|
+
examples: ["phresh program allow-permission --program terminal --permission network --value '[\"https://example.com\"]'"]
|
|
178
|
+
}, ({ options }) => connected(connect, system => system.execute({
|
|
179
|
+
$domain: "program",
|
|
180
|
+
$operation: "allowPermission",
|
|
181
|
+
identity: options.program,
|
|
182
|
+
permission: parsePermissionName(options.permission),
|
|
183
|
+
...(options.value === undefined ? {} : { value: permissionRequest(options.value) })
|
|
184
|
+
})));
|
|
185
|
+
defineCommand(programs, {
|
|
186
|
+
name: "denyPermission",
|
|
187
|
+
aliases: ["deny-permission"],
|
|
188
|
+
description: executeDescription("program", "denyPermission"),
|
|
189
|
+
requiresSystem: true,
|
|
190
|
+
options: withJson(option("--program <identity>", "Program identity", { mandatory: true }), option("--permission <name>", "permission name", { mandatory: true })),
|
|
191
|
+
output: dataOutput(value.any("stored permission assignment"), "The stored permission", { format: "value" }),
|
|
192
|
+
examples: ["phresh program deny-permission --program terminal --permission network"]
|
|
193
|
+
}, ({ options }) => connected(connect, system => system.execute({
|
|
194
|
+
$domain: "program",
|
|
195
|
+
$operation: "denyPermission",
|
|
196
|
+
identity: options.program,
|
|
197
|
+
permission: parsePermissionName(options.permission)
|
|
198
|
+
})));
|
|
199
|
+
defineCommand(programs, {
|
|
200
|
+
name: "requestPermission",
|
|
201
|
+
aliases: ["request-permission"],
|
|
202
|
+
description: executeDescription("program", "requestPermission"),
|
|
203
|
+
requiresSystem: true,
|
|
204
|
+
options: withJson(option("--program <identity>", "Program identity", { mandatory: true }), option("--permission <name>", "permission name", { mandatory: true }), option("--value <json>", "complete requested permission value encoded as JSON"), timeoutOption),
|
|
205
|
+
output: dataOutput(value.any("permission decision"), "The permission decision", { format: "value" }),
|
|
206
|
+
examples: ["phresh program request-permission --program terminal --permission uploads"]
|
|
207
|
+
}, ({ options }) => connected(connect, system => system.execute({
|
|
208
|
+
$domain: "program",
|
|
209
|
+
$operation: "requestPermission",
|
|
210
|
+
identity: options.program,
|
|
211
|
+
permission: parsePermissionName(options.permission),
|
|
212
|
+
...(options.value === undefined ? {} : { value: permissionRequest(options.value) }),
|
|
213
|
+
...(options.timeout === undefined ? {} : { timeout: bounded(options.timeout, "--timeout", 0) })
|
|
214
|
+
})));
|
|
89
215
|
defineCommand(programs, {
|
|
90
216
|
name: "logs",
|
|
91
217
|
description: executeDescription("program", "logs"),
|
|
@@ -111,7 +237,7 @@ export default function programCommands(root, connect) {
|
|
|
111
237
|
requiresSystem: true,
|
|
112
238
|
options: withJson(option("--event <event>", "Program lifecycle event", {
|
|
113
239
|
mandatory: true,
|
|
114
|
-
choices: ["create", "forget", "install", "uninstall", "processCreate", "processExit"]
|
|
240
|
+
choices: ["create", "forget", "install", "uninstall", "pinned", "processCreate", "processExit"]
|
|
115
241
|
}), option("--program <identity>", "observe events belonging to one Program"), timeoutOption),
|
|
116
242
|
output: dataOutput(eventOutput("The observed Program event", value.any("Program state or uninstall result")), "One Program event", eventPresentation),
|
|
117
243
|
examples: ["phresh program wait --event create", "phresh program wait --event uninstall --program terminal --json"]
|
|
@@ -123,3 +249,12 @@ export default function programCommands(root, connect) {
|
|
|
123
249
|
...(options.timeout === undefined ? {} : { timeout: bounded(options.timeout, "--timeout", 1) })
|
|
124
250
|
})));
|
|
125
251
|
}
|
|
252
|
+
function permissionRequest(source) {
|
|
253
|
+
const value = json(source, "--value");
|
|
254
|
+
if (value === true || strings(value))
|
|
255
|
+
return value;
|
|
256
|
+
throw new Error("--value must be true or a JSON array of strings");
|
|
257
|
+
}
|
|
258
|
+
function strings(value) {
|
|
259
|
+
return Array.isArray(value) && value.every(entry => typeof entry === "string");
|
|
260
|
+
}
|
package/dist/commands/project.js
CHANGED
|
@@ -85,7 +85,7 @@ export default function projectCommands(program, coreRange) {
|
|
|
85
85
|
name: "install",
|
|
86
86
|
description: "install a local or official Program",
|
|
87
87
|
arguments: [{ syntax: "[name]", description: "name of an official Program" }],
|
|
88
|
-
options: [option("--run", "launch
|
|
88
|
+
options: [option("--run", "launch one default Process after installation"), option("--purge", "delete existing installed Program storage")],
|
|
89
89
|
guidance: [
|
|
90
90
|
"Without a name, builds and installs the Program declared by this project.",
|
|
91
91
|
"A name installs its verified official production release. --run launches the installed Program now."
|
|
@@ -18,19 +18,22 @@ export async function programView(program) {
|
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
20
|
export async function processView(process) {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
const program = process.program();
|
|
22
|
+
const [server, client] = await Promise.all([
|
|
23
|
+
program.server === null
|
|
24
|
+
? Promise.resolve({ running: false, service: false })
|
|
25
|
+
: Promise.all([process.server.running(), process.server.isService()]).then(([running, service]) => ({ running, service })),
|
|
26
|
+
program.client === null
|
|
27
|
+
? Promise.resolve({ running: false, service: false })
|
|
28
|
+
: Promise.all([process.client.running(), process.client.isService()]).then(([running, service]) => ({ running, service }))
|
|
26
29
|
]);
|
|
27
30
|
return {
|
|
28
31
|
identity: process.identity,
|
|
29
32
|
name: process.name,
|
|
30
|
-
program:
|
|
33
|
+
program: program.identity,
|
|
31
34
|
startedAt: process.startedAt.toISOString(),
|
|
32
|
-
server: { declared:
|
|
33
|
-
client: { declared:
|
|
35
|
+
server: { declared: program.server !== null, ...server },
|
|
36
|
+
client: { declared: program.client !== null, ...client }
|
|
34
37
|
};
|
|
35
38
|
}
|
|
36
39
|
export async function endpointView(process, name) {
|
|
@@ -40,7 +43,7 @@ export async function endpointView(process, name) {
|
|
|
40
43
|
program: program.identity,
|
|
41
44
|
endpoint: name,
|
|
42
45
|
declared: name === "server" ? program.server !== null : program.client !== null,
|
|
43
|
-
running: await endpoint(process, name).
|
|
46
|
+
running: await endpoint(process, name).running(),
|
|
44
47
|
service: await endpoint(process, name).isService()
|
|
45
48
|
};
|
|
46
49
|
}
|
package/dist/commands/schemas.js
CHANGED
|
@@ -3,25 +3,60 @@ import { value } from "../contract/schema.js";
|
|
|
3
3
|
const metric = {
|
|
4
4
|
anyOf: [value.number("pixels"), value.string("workspace-relative expression")]
|
|
5
5
|
};
|
|
6
|
+
const transaction = {
|
|
7
|
+
anyOf: [
|
|
8
|
+
value.boolean("default or disabled transaction"),
|
|
9
|
+
value.number("duration in milliseconds"),
|
|
10
|
+
value.object({
|
|
11
|
+
duration: value.number("duration in milliseconds"),
|
|
12
|
+
easing: value.any("CSS easing name or cubic Bézier tuple")
|
|
13
|
+
}, ["duration", "easing"], "appearance transaction")
|
|
14
|
+
]
|
|
15
|
+
};
|
|
16
|
+
const frame = {
|
|
17
|
+
anyOf: [
|
|
18
|
+
value.boolean("default or absent frame"),
|
|
19
|
+
value.object({
|
|
20
|
+
radius: { anyOf: [value.number("radius in pixels"), value.literal("full", "fully rounded radius")] },
|
|
21
|
+
color: value.string("Appearance color role or CSS color"),
|
|
22
|
+
material: {
|
|
23
|
+
anyOf: [
|
|
24
|
+
value.literal(false, "disabled Material"),
|
|
25
|
+
value.object({
|
|
26
|
+
grain: value.number("grain frequency"),
|
|
27
|
+
grainAmount: value.number("grain intensity"),
|
|
28
|
+
backdrop: value.number("backdrop blur"),
|
|
29
|
+
opacity: value.number("Material opacity"),
|
|
30
|
+
distortion: value.number("backdrop distortion"),
|
|
31
|
+
saturation: value.number("backdrop saturation")
|
|
32
|
+
}, [], "partial Appearance Material")
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
}, [], "Window frame customization")
|
|
36
|
+
]
|
|
37
|
+
};
|
|
6
38
|
const endpointDeclaration = value.nullable(value.object({
|
|
7
39
|
start: value.boolean("whether a default Process starts this Endpoint"),
|
|
8
|
-
service: value.boolean("default Service role for new
|
|
40
|
+
service: value.boolean("default Service role for new execution contexts")
|
|
9
41
|
}, ["start", "service"], "resolved Server Endpoint declaration"));
|
|
10
42
|
const clientDeclaration = value.nullable(value.object({
|
|
11
43
|
start: value.boolean("whether a default Process starts this Endpoint"),
|
|
12
|
-
service: value.boolean("default Service role for new
|
|
44
|
+
service: value.boolean("default Service role for new execution contexts"),
|
|
13
45
|
title: value.nullable(value.string("default Window title")),
|
|
46
|
+
header: value.nullable(value.boolean("default Window header visibility")),
|
|
47
|
+
frame: value.nullable(frame),
|
|
48
|
+
transaction: value.nullable(transaction),
|
|
14
49
|
size: value.nullable(value.object({ width: metric, height: metric }, ["width", "height"], "default Window size")),
|
|
15
50
|
position: value.nullable(value.object({ x: metric, y: metric }, ["x", "y"], "default Window position")),
|
|
16
51
|
layer: value.nullable(value.enumeration(layers, "default Window layer")),
|
|
17
52
|
minimize: value.nullable(value.boolean("default minimized state")),
|
|
18
53
|
maximize: value.nullable(value.boolean("default maximized state"))
|
|
19
|
-
}, ["start", "service", "title", "size", "position", "layer", "minimize", "maximize"], "resolved Client Endpoint declaration"));
|
|
54
|
+
}, ["start", "service", "title", "header", "frame", "transaction", "size", "position", "layer", "minimize", "maximize"], "resolved Client Endpoint declaration"));
|
|
20
55
|
export const programOutput = value.object({
|
|
21
56
|
identity: value.string("stable Program identity"),
|
|
22
57
|
assetId: value.string("public Program asset identity"),
|
|
23
58
|
name: value.string("human-readable Program name"),
|
|
24
|
-
version: value.
|
|
59
|
+
version: value.string("Resolved Program version"),
|
|
25
60
|
description: value.nullable(value.string("Program description")),
|
|
26
61
|
installed: value.boolean("whether production files are installed"),
|
|
27
62
|
hasAgent: value.boolean("whether the Program provides agent documentation"),
|
|
@@ -41,19 +76,28 @@ export const endpointOutput = value.object({
|
|
|
41
76
|
program: value.string("owning Program identity"),
|
|
42
77
|
endpoint: value.enumeration(["server", "client"], "Endpoint kind"),
|
|
43
78
|
declared: value.boolean("whether the Program declares this Endpoint"),
|
|
44
|
-
running: value.boolean("whether the Endpoint currently
|
|
45
|
-
service: value.boolean("whether this Endpoint
|
|
79
|
+
running: value.boolean("whether the Endpoint currently has a running execution context"),
|
|
80
|
+
service: value.boolean("whether this Endpoint execution context is addressable as a Service")
|
|
46
81
|
}, ["process", "program", "endpoint", "declared", "running", "service"], "Endpoint state");
|
|
82
|
+
export const serviceOutput = value.object({
|
|
83
|
+
program: value.string("owning Program identity"),
|
|
84
|
+
process: value.string("Process and Service name"),
|
|
85
|
+
endpoint: value.enumeration(["server", "client"], "Endpoint kind"),
|
|
86
|
+
available: value.boolean("whether a ready Endpoint is currently available at this address")
|
|
87
|
+
}, ["program", "process", "endpoint", "available"], "Service state");
|
|
47
88
|
export const windowOutput = value.object({
|
|
48
89
|
process: value.string("owning Process identity"),
|
|
49
90
|
title: value.string("Window title"),
|
|
91
|
+
header: value.boolean("whether the Desktop-owned Window header is shown"),
|
|
92
|
+
frame,
|
|
93
|
+
transaction,
|
|
50
94
|
position: value.object({ x: metric, y: metric }, ["x", "y"], "Window position"),
|
|
51
95
|
size: value.object({ width: metric, height: metric }, ["width", "height"], "Window size"),
|
|
52
96
|
minimized: value.boolean("whether the Window is minimized"),
|
|
53
97
|
maximized: value.boolean("whether the Window is maximized"),
|
|
54
98
|
front: value.boolean("whether the Window is at the front of its layer"),
|
|
55
99
|
layer: value.enumeration(layers, "Window layer")
|
|
56
|
-
}, ["process", "title", "position", "size", "minimized", "maximized", "front", "layer"], "Window state");
|
|
100
|
+
}, ["process", "title", "header", "frame", "transaction", "position", "size", "minimized", "maximized", "front", "layer"], "Window state");
|
|
57
101
|
export const programPresentation = fields(["Identity", "identity"], ["Asset", "assetId"], ["Name", "name"], ["Version", "version"], ["Description", "description"], ["Installed", "installed"], ["Agent", "hasAgent"], ["Server", "server"], ["Client", "client"]);
|
|
58
102
|
export const programListPresentation = list("data", "Program", "Programs", "No matching Programs", [
|
|
59
103
|
{ label: "Name", path: "name" },
|
|
@@ -73,7 +117,13 @@ export const processListPresentation = list("data", "Process", "Processes", "No
|
|
|
73
117
|
]);
|
|
74
118
|
export const endpointPresentation = fields(["Process", "process"], ["Program", "program"], ["Endpoint", "endpoint"], ["Declared", "declared"], ["Running", "running"], ["Service", "service"]);
|
|
75
119
|
export const endpointActionPresentation = fields(["Process", "process"], ["Endpoint", "endpoint"], ["Running", "running"], ["Service", "service"]);
|
|
76
|
-
export const
|
|
120
|
+
export const servicePresentation = fields(["Program", "program"], ["Service", "process"], ["Endpoint", "endpoint"], ["Available", "available"]);
|
|
121
|
+
export const serviceListPresentation = list("data", "Service", "Services", "No matching Services", [
|
|
122
|
+
{ label: "Service", path: "process" },
|
|
123
|
+
{ label: "Program", path: "program" },
|
|
124
|
+
{ label: "Endpoint", path: "endpoint" }
|
|
125
|
+
]);
|
|
126
|
+
export const windowPresentation = fields(["Process", "process"], ["Title", "title"], ["Header", "header"], ["Frame", "frame"], ["Transaction", "transaction"], ["Position", "position"], ["Size", "size"], ["Minimized", "minimized"], ["Maximized", "maximized"], ["Front", "front"], ["Layer", "layer"]);
|
|
77
127
|
export const windowPositionPresentation = fields(["Process", "process"], ["Position", "position"]);
|
|
78
128
|
export const windowSizePresentation = fields(["Process", "process"], ["Size", "size"]);
|
|
79
129
|
export const windowGeometryPresentation = fields(["Process", "process"], ["Position", "position"], ["Size", "size"]);
|
|
@@ -81,6 +131,8 @@ export const windowMinimizePresentation = fields(["Process", "process"], ["Minim
|
|
|
81
131
|
export const windowMaximizePresentation = fields(["Process", "process"], ["Maximized", "maximized"]);
|
|
82
132
|
export const windowTitlePresentation = fields(["Process", "process"], ["Title", "title"]);
|
|
83
133
|
export const windowHeaderPresentation = fields(["Process", "process"], ["Header", "header"]);
|
|
134
|
+
export const windowFramePresentation = fields(["Process", "process"], ["Frame", "frame"]);
|
|
135
|
+
export const windowTransactionPresentation = fields(["Process", "process"], ["Transaction", "transaction"]);
|
|
84
136
|
export const windowRaisePresentation = fields(["Process", "process"], ["Front", "front"]);
|
|
85
137
|
export const eventPresentation = fields(["Scope", "scope"], ["Event", "event"], ["Payload", "payload"]);
|
|
86
138
|
export const lifecyclePresentation = fields(["Scope", "scope"], ["Event", "event"]);
|
|
@@ -109,8 +161,8 @@ export function textOutput(description) {
|
|
|
109
161
|
function endpointState(description) {
|
|
110
162
|
return value.object({
|
|
111
163
|
declared: value.boolean("whether the Program declares this Endpoint"),
|
|
112
|
-
running: value.boolean("whether the Endpoint currently
|
|
113
|
-
service: value.boolean("whether this Endpoint
|
|
164
|
+
running: value.boolean("whether the Endpoint currently has a running execution context"),
|
|
165
|
+
service: value.boolean("whether this Endpoint execution context is a Service")
|
|
114
166
|
}, ["declared", "running", "service"], description);
|
|
115
167
|
}
|
|
116
168
|
function fields(...values) {
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { parseExecuteRequest } from "@phreshos/core";
|
|
2
|
+
import { defineCommand } from "../contract/command.js";
|
|
3
|
+
import { value } from "../contract/schema.js";
|
|
4
|
+
import { dataOutput, eventOutput, eventPresentation, lifecyclePresentation, serviceListPresentation, serviceOutput, servicePresentation, valuePresentation } from "./schemas.js";
|
|
5
|
+
import { connected } from "./connection.js";
|
|
6
|
+
import { bounded, payload } from "./input.js";
|
|
7
|
+
import { executeDescription } from "./execution.js";
|
|
8
|
+
import { option, timeoutOption, withJson } from "./options.js";
|
|
9
|
+
const addressOptions = [
|
|
10
|
+
option("--program <identity>", "owning Program identity", { mandatory: true }),
|
|
11
|
+
option("--process <name>", "Process and Service name", { mandatory: true }),
|
|
12
|
+
option("--endpoint <endpoint>", "Endpoint kind", { mandatory: true, choices: ["server", "client"] })
|
|
13
|
+
];
|
|
14
|
+
const availabilityEvents = ["available", "unavailable"];
|
|
15
|
+
export default function serviceCommands(root, connect) {
|
|
16
|
+
const services = defineCommand(root, {
|
|
17
|
+
name: "service",
|
|
18
|
+
description: "discover and communicate with named Endpoint Services",
|
|
19
|
+
guidance: ["Discovery returns ready Services; exact addresses remain stable while their providers are unavailable."]
|
|
20
|
+
});
|
|
21
|
+
defineCommand(services, {
|
|
22
|
+
name: "list",
|
|
23
|
+
description: executeDescription("service", "list"),
|
|
24
|
+
requiresSystem: true,
|
|
25
|
+
options: withJson(),
|
|
26
|
+
output: dataOutput(value.array(serviceOutput, "ready Services"), "Visible Services", serviceListPresentation),
|
|
27
|
+
examples: ["phresh service list"]
|
|
28
|
+
}, async () => executeService(connect, { $operation: "list" }));
|
|
29
|
+
defineCommand(services, {
|
|
30
|
+
name: "search",
|
|
31
|
+
description: executeDescription("service", "search"),
|
|
32
|
+
requiresSystem: true,
|
|
33
|
+
options: withJson(option("--name <name>", "Process and Service name", { mandatory: true })),
|
|
34
|
+
output: dataOutput(value.array(serviceOutput, "matching ready Services"), "Matching Services", serviceListPresentation),
|
|
35
|
+
examples: ["phresh service search --name ssh"]
|
|
36
|
+
}, async ({ options }) => executeService(connect, { $operation: "search", name: options.name }));
|
|
37
|
+
defineCommand(services, {
|
|
38
|
+
name: "inspect",
|
|
39
|
+
description: executeDescription("service", "inspect"),
|
|
40
|
+
requiresSystem: true,
|
|
41
|
+
options: withJson(...addressOptions),
|
|
42
|
+
output: dataOutput(serviceOutput, "The selected Service", servicePresentation),
|
|
43
|
+
examples: ["phresh service inspect --program terminal --process ssh --endpoint server"]
|
|
44
|
+
}, async ({ options }) => executeAddressedService(connect, options, { $operation: "inspect" }));
|
|
45
|
+
defineCommand(services, {
|
|
46
|
+
name: "waitReady",
|
|
47
|
+
aliases: ["wait-ready"],
|
|
48
|
+
description: executeDescription("service", "waitReady"),
|
|
49
|
+
requiresSystem: true,
|
|
50
|
+
options: withJson(...addressOptions, timeoutOption),
|
|
51
|
+
output: dataOutput(serviceOutput, "The ready Service", servicePresentation),
|
|
52
|
+
examples: ["phresh service wait-ready --program terminal --process ssh --endpoint server"]
|
|
53
|
+
}, async ({ options }) => executeAddressedService(connect, options, {
|
|
54
|
+
$operation: "waitReady",
|
|
55
|
+
...(options.timeout === undefined ? {} : { timeout: timeout(options.timeout) })
|
|
56
|
+
}));
|
|
57
|
+
defineCommand(services, {
|
|
58
|
+
name: "ask",
|
|
59
|
+
description: executeDescription("service", "ask"),
|
|
60
|
+
requiresSystem: true,
|
|
61
|
+
options: withJson(option("--program <identity>", "owning Program identity", { mandatory: true }), option("--process <name>", "Process and Service name", { mandatory: true }), option("--endpoint <endpoint>", "Endpoint kind", { mandatory: true, choices: ["server"] }), option("--event <event>", "event name", { mandatory: true }), option("--payload <json>", "arbitrary event payload as JSON"), timeoutOption),
|
|
62
|
+
output: dataOutput(value.any("answer returned by the Server Service contract"), "The Service answer", valuePresentation),
|
|
63
|
+
examples: ["phresh service ask --program tilo --process board --endpoint server --event board.list --json"]
|
|
64
|
+
}, async ({ options }) => executeAddressedService(connect, options, {
|
|
65
|
+
$operation: "ask",
|
|
66
|
+
event: options.event,
|
|
67
|
+
...(options.payload === undefined ? {} : { input: payload(options.payload) }),
|
|
68
|
+
...(options.timeout === undefined ? {} : { timeout: timeout(options.timeout) })
|
|
69
|
+
}));
|
|
70
|
+
defineCommand(services, {
|
|
71
|
+
name: "publish",
|
|
72
|
+
description: executeDescription("service", "publish"),
|
|
73
|
+
requiresSystem: true,
|
|
74
|
+
options: withJson(...addressOptions, option("--event <event>", "event name", { mandatory: true }), option("--payload <json>", "arbitrary event payload as JSON")),
|
|
75
|
+
output: dataOutput(serviceOutput, "The addressed Service", servicePresentation),
|
|
76
|
+
examples: ["phresh service publish --program tilo --process board --endpoint client --event changed"]
|
|
77
|
+
}, async ({ options }) => executeAddressedService(connect, options, {
|
|
78
|
+
$operation: "publish",
|
|
79
|
+
event: options.event,
|
|
80
|
+
...(options.payload === undefined ? {} : { input: payload(options.payload) })
|
|
81
|
+
}));
|
|
82
|
+
defineCommand(services, {
|
|
83
|
+
name: "wait",
|
|
84
|
+
description: executeDescription("service", "wait"),
|
|
85
|
+
requiresSystem: true,
|
|
86
|
+
options: withJson(...addressOptions, option("--event <event>", "event name", { mandatory: true }), timeoutOption),
|
|
87
|
+
output: dataOutput(eventOutput("The observed Service event"), "One Service event", eventPresentation),
|
|
88
|
+
examples: ["phresh service wait --program tilo --process board --endpoint client --event changed"]
|
|
89
|
+
}, async ({ options }) => executeAddressedService(connect, options, {
|
|
90
|
+
$operation: "wait",
|
|
91
|
+
event: options.event,
|
|
92
|
+
...(options.timeout === undefined ? {} : { timeout: timeout(options.timeout) })
|
|
93
|
+
}));
|
|
94
|
+
defineCommand(services, {
|
|
95
|
+
name: "waitLifecycle",
|
|
96
|
+
aliases: ["wait-lifecycle"],
|
|
97
|
+
description: executeDescription("service", "waitLifecycle"),
|
|
98
|
+
requiresSystem: true,
|
|
99
|
+
options: withJson(...addressOptions, option("--event <event>", "availability event", { mandatory: true, choices: availabilityEvents }), timeoutOption),
|
|
100
|
+
output: dataOutput(eventOutput("The observed Service availability event"), "One Service lifecycle event", lifecyclePresentation),
|
|
101
|
+
examples: ["phresh service wait-lifecycle --program tilo --process board --endpoint server --event available"]
|
|
102
|
+
}, async ({ options }) => executeAddressedService(connect, options, {
|
|
103
|
+
$operation: "waitLifecycle",
|
|
104
|
+
event: options.event,
|
|
105
|
+
...(options.timeout === undefined ? {} : { timeout: timeout(options.timeout) })
|
|
106
|
+
}));
|
|
107
|
+
defineCommand(services, {
|
|
108
|
+
name: "waitDiscovery",
|
|
109
|
+
aliases: ["wait-discovery"],
|
|
110
|
+
description: executeDescription("service", "waitDiscovery"),
|
|
111
|
+
requiresSystem: true,
|
|
112
|
+
options: withJson(option("--event <event>", "discovery event", { mandatory: true, choices: availabilityEvents }), timeoutOption),
|
|
113
|
+
output: dataOutput(eventOutput("The observed Service discovery event"), "One Service discovery event", lifecyclePresentation),
|
|
114
|
+
examples: ["phresh service wait-discovery --event available"]
|
|
115
|
+
}, async ({ options }) => executeService(connect, {
|
|
116
|
+
$operation: "waitDiscovery",
|
|
117
|
+
event: options.event,
|
|
118
|
+
...(options.timeout === undefined ? {} : { timeout: timeout(options.timeout) })
|
|
119
|
+
}));
|
|
120
|
+
}
|
|
121
|
+
function executeAddressedService(connect, options, operation) {
|
|
122
|
+
return executeService(connect, {
|
|
123
|
+
...operation,
|
|
124
|
+
program: options.program,
|
|
125
|
+
process: options.process,
|
|
126
|
+
endpoint: options.endpoint
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function executeService(connect, operation) {
|
|
130
|
+
const request = parseExecuteRequest({ $domain: "service", ...operation });
|
|
131
|
+
return connected(connect, system => system.execute(request));
|
|
132
|
+
}
|
|
133
|
+
function timeout(value) { return value === undefined ? undefined : bounded(value, "--timeout", 1); }
|
package/dist/commands/window.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { parseExecuteRequest } from "@phreshos/core";
|
|
1
|
+
import { parseExecuteRequest, parseWindowFrame, parseWindowTransaction } from "@phreshos/core";
|
|
2
2
|
import { defineCommand } from "../contract/command.js";
|
|
3
3
|
import { option, processOptions, timeoutOption, withJson } from "./options.js";
|
|
4
|
-
import { dataOutput, eventOutput, eventPresentation, windowGeometryPresentation, windowHeaderPresentation, windowMinimizePresentation, windowMaximizePresentation, windowOutput, windowPositionPresentation, windowPresentation, windowRaisePresentation, windowSizePresentation, windowTitlePresentation } from "./schemas.js";
|
|
4
|
+
import { dataOutput, eventOutput, eventPresentation, windowGeometryPresentation, windowFramePresentation, windowHeaderPresentation, windowMinimizePresentation, windowMaximizePresentation, windowOutput, windowPositionPresentation, windowTransactionPresentation, windowPresentation, windowRaisePresentation, windowSizePresentation, windowTitlePresentation } from "./schemas.js";
|
|
5
5
|
import { connected } from "./connection.js";
|
|
6
6
|
import { bounded, position, size } from "./input.js";
|
|
7
7
|
import { executeDescription } from "./execution.js";
|
|
@@ -31,8 +31,8 @@ export default function windowCommands(root, connect) {
|
|
|
31
31
|
examples: ["phresh window set-geometry --process main --program terminal --x 0 --y 0 --width 100% --height 100%"]
|
|
32
32
|
}, async ({ options }) => executeWindow(connect, options, {
|
|
33
33
|
$operation: "setGeometry",
|
|
34
|
-
position
|
|
35
|
-
size
|
|
34
|
+
...position(options.x, options.y),
|
|
35
|
+
...size(options.width, options.height)
|
|
36
36
|
}));
|
|
37
37
|
defineCommand(windows, {
|
|
38
38
|
...state("minimize", windowMinimizePresentation),
|
|
@@ -45,17 +45,38 @@ export default function windowCommands(root, connect) {
|
|
|
45
45
|
examples: ["phresh window maximize --process main --program terminal", "phresh window maximize --process main --program terminal --restore"]
|
|
46
46
|
}, async ({ options }) => executeWindow(connect, options, { $operation: "maximize", maximized: options.restore !== true }));
|
|
47
47
|
defineCommand(windows, {
|
|
48
|
-
...state("
|
|
49
|
-
aliases: ["
|
|
48
|
+
...state("setTitle", windowTitlePresentation),
|
|
49
|
+
aliases: ["set-title"],
|
|
50
50
|
options: withJson(...processOptions, option("--title <title>", "new Window title", { mandatory: true })),
|
|
51
|
-
examples: ["phresh window
|
|
52
|
-
}, async ({ options }) => executeWindow(connect, options, { $operation: "
|
|
51
|
+
examples: ["phresh window set-title --process main --program terminal --title Shell"]
|
|
52
|
+
}, async ({ options }) => executeWindow(connect, options, { $operation: "setTitle", title: options.title }));
|
|
53
53
|
defineCommand(windows, {
|
|
54
|
-
...state("
|
|
55
|
-
aliases: ["
|
|
54
|
+
...state("setHeader", windowHeaderPresentation),
|
|
55
|
+
aliases: ["set-header"],
|
|
56
56
|
options: withJson(...processOptions, option("--hide", "hide rather than show the Window header")),
|
|
57
|
-
examples: ["phresh window
|
|
58
|
-
}, async ({ options }) => executeWindow(connect, options, { $operation: "
|
|
57
|
+
examples: ["phresh window set-header --process main --program terminal --hide", "phresh window set-header --process main --program terminal"]
|
|
58
|
+
}, async ({ options }) => executeWindow(connect, options, { $operation: "setHeader", header: options.hide !== true }));
|
|
59
|
+
defineCommand(windows, {
|
|
60
|
+
...state("setFrame", windowFramePresentation),
|
|
61
|
+
aliases: ["set-frame"],
|
|
62
|
+
options: withJson(...processOptions, option("--default", "use the default Window frame"), option("--absent", "remove the Window frame"), option("--radius <radius>", "frame radius in pixels or full"), option("--color <color>", "Appearance color role or CSS color"), option("--without-material", "render the frame without Material"), option("--grain <value>", "frame Material grain", { parse: input => numeric(input, "--grain") }), option("--grain-amount <value>", "frame Material grain intensity", { parse: input => numeric(input, "--grain-amount") }), option("--backdrop <value>", "frame Material backdrop blur", { parse: input => numeric(input, "--backdrop") }), option("--opacity <value>", "frame Material opacity", { parse: input => numeric(input, "--opacity") }), option("--distortion <value>", "frame Material distortion", { parse: input => numeric(input, "--distortion") }), option("--saturation <value>", "frame Material saturation", { parse: input => numeric(input, "--saturation") })),
|
|
63
|
+
examples: [
|
|
64
|
+
"phresh window set-frame --process overlay --absent",
|
|
65
|
+
"phresh window set-frame --process overlay --radius full --color primary"
|
|
66
|
+
]
|
|
67
|
+
}, async ({ options }) => executeWindow(connect, options, { $operation: "setFrame", frame: frame(options) }));
|
|
68
|
+
defineCommand(windows, {
|
|
69
|
+
...state("setTransaction", windowTransactionPresentation),
|
|
70
|
+
aliases: ["set-transaction"],
|
|
71
|
+
options: withJson(...processOptions, option("--default", "use the default Appearance transaction"), option("--disabled", "disable the default Window transaction"), option("--duration <milliseconds>", "transaction duration", { parse: input => numeric(input, "--duration") }), option("--easing <easing>", "standard easing name or four comma-separated cubic Bézier values")),
|
|
72
|
+
examples: [
|
|
73
|
+
"phresh window set-transaction --process overlay --default",
|
|
74
|
+
"phresh window set-transaction --process overlay --duration 240 --easing ease-out"
|
|
75
|
+
]
|
|
76
|
+
}, async ({ options }) => executeWindow(connect, options, {
|
|
77
|
+
$operation: "setTransaction",
|
|
78
|
+
transaction: transaction(options)
|
|
79
|
+
}));
|
|
59
80
|
defineCommand(windows, {
|
|
60
81
|
...state("raise", windowRaisePresentation),
|
|
61
82
|
examples: ["phresh window raise --process main --program terminal"]
|
|
@@ -66,10 +87,10 @@ export default function windowCommands(root, connect) {
|
|
|
66
87
|
requiresSystem: true,
|
|
67
88
|
options: withJson(...processOptions, option("--event <event>", "Window event", {
|
|
68
89
|
mandatory: true,
|
|
69
|
-
choices: ["move", "resize", "
|
|
90
|
+
choices: ["move", "resize", "minimize", "maximize", "changeTitle", "changeHeader", "changeFrame", "changeTransaction", "front"]
|
|
70
91
|
}), timeoutOption),
|
|
71
92
|
output: dataOutput(eventOutput("The observed Window event"), "One Window event", eventPresentation),
|
|
72
|
-
examples: ["phresh window wait --process main --program terminal --event
|
|
93
|
+
examples: ["phresh window wait --process main --program terminal --event move --json"]
|
|
73
94
|
}, async ({ options }) => executeWindow(connect, options, {
|
|
74
95
|
$operation: "wait",
|
|
75
96
|
event: options.event,
|
|
@@ -94,3 +115,61 @@ async function executeWindow(connect, options, operation) {
|
|
|
94
115
|
});
|
|
95
116
|
return connected(connect, system => system.execute(request));
|
|
96
117
|
}
|
|
118
|
+
function frame(options) {
|
|
119
|
+
const materialValues = material(options);
|
|
120
|
+
const customized = options.radius !== undefined || options.color !== undefined || materialValues !== undefined;
|
|
121
|
+
const modes = Number(options.default === true) + Number(options.absent === true) + Number(customized);
|
|
122
|
+
if (modes !== 1)
|
|
123
|
+
throw new Error("Choose exactly one of --default, --absent, or frame customization options");
|
|
124
|
+
if (options.default)
|
|
125
|
+
return true;
|
|
126
|
+
if (options.absent)
|
|
127
|
+
return false;
|
|
128
|
+
return parseWindowFrame({
|
|
129
|
+
...(options.radius === undefined ? {} : { radius: options.radius === "full" ? "full" : numeric(options.radius, "--radius") }),
|
|
130
|
+
...(options.color === undefined ? {} : { color: options.color }),
|
|
131
|
+
...(materialValues === undefined ? {} : { material: materialValues })
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
function material(options) {
|
|
135
|
+
const values = {
|
|
136
|
+
grain: options.grain,
|
|
137
|
+
grainAmount: options.grainAmount,
|
|
138
|
+
backdrop: options.backdrop,
|
|
139
|
+
opacity: options.opacity,
|
|
140
|
+
distortion: options.distortion,
|
|
141
|
+
saturation: options.saturation
|
|
142
|
+
};
|
|
143
|
+
const customized = Object.values(values).some(value => value !== undefined);
|
|
144
|
+
const modes = Number(options.withoutMaterial === true) + Number(customized);
|
|
145
|
+
if (modes > 1)
|
|
146
|
+
throw new Error("Choose only one Material mode");
|
|
147
|
+
if (options.withoutMaterial)
|
|
148
|
+
return false;
|
|
149
|
+
if (!customized)
|
|
150
|
+
return undefined;
|
|
151
|
+
return Object.fromEntries(Object.entries(values).filter(([, value]) => value !== undefined));
|
|
152
|
+
}
|
|
153
|
+
function transaction(options) {
|
|
154
|
+
const customized = options.duration !== undefined || options.easing !== undefined;
|
|
155
|
+
const modes = Number(options.default === true) + Number(options.disabled === true) + Number(customized);
|
|
156
|
+
if (modes !== 1)
|
|
157
|
+
throw new Error("Choose exactly one of --default, --disabled, or --duration");
|
|
158
|
+
if (options.default)
|
|
159
|
+
return true;
|
|
160
|
+
if (options.disabled)
|
|
161
|
+
return false;
|
|
162
|
+
if (options.duration === undefined)
|
|
163
|
+
throw new Error("--easing requires --duration");
|
|
164
|
+
if (options.easing === undefined)
|
|
165
|
+
return parseWindowTransaction(options.duration);
|
|
166
|
+
const pieces = options.easing.split(",").map(value => value.trim());
|
|
167
|
+
const easing = pieces.length === 4 ? pieces.map(value => numeric(value, "--easing")) : options.easing;
|
|
168
|
+
return parseWindowTransaction({ duration: options.duration, easing });
|
|
169
|
+
}
|
|
170
|
+
function numeric(value, name) {
|
|
171
|
+
const result = Number(value);
|
|
172
|
+
if (!Number.isFinite(result))
|
|
173
|
+
throw new Error(`${name} must be a finite number`);
|
|
174
|
+
return result;
|
|
175
|
+
}
|
package/dist/install.js
CHANGED
|
@@ -5,7 +5,7 @@ import { prepareOfficialProgram } from "./program-release.js";
|
|
|
5
5
|
/**
|
|
6
6
|
* Lay this program out on this machine's system.
|
|
7
7
|
*
|
|
8
|
-
* A local project is built and derived from its authoring
|
|
8
|
+
* A local project is built and derived from its authoring definition. An
|
|
9
9
|
* official name resolves a verified production package and turns its
|
|
10
10
|
* canonical paths into the same concrete definition. From that point on,
|
|
11
11
|
* both sources cross the exact same gateway and the System performs the exact
|
|
@@ -15,8 +15,7 @@ import { prepareOfficialProgram } from "./program-release.js";
|
|
|
15
15
|
* production Program is derived and sent. The command remains authoring
|
|
16
16
|
* metadata and never becomes part of the installed Program.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
* `run` requests an additional Process before startup, created by System. It belongs
|
|
18
|
+
* `run` overrides the Program's install launch with one default Process. It belongs
|
|
20
19
|
* to the installed Program and
|
|
21
20
|
* therefore outlives this command; `phresh start` and `phresh dev` remain
|
|
22
21
|
* attached authoring runs whose lifetime is the terminal's.
|
|
@@ -17,8 +17,9 @@ export default async function installProgram(program, options = {}) {
|
|
|
17
17
|
}
|
|
18
18
|
else
|
|
19
19
|
installed = await system.program.forceCreate(program);
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
// A definition-owned installLaunch can create the Process even when
|
|
21
|
+
// the CLI did not supply --run, so observation belongs to installation.
|
|
22
|
+
stopObserving = installed.subscribe("processCreate", created => { process ??= created.identity; });
|
|
22
23
|
for await (const chunk of installed.install({ launch: options.run ? true : undefined, purge: options.purge }))
|
|
23
24
|
writeProgramCommandOutput(chunk);
|
|
24
25
|
installationFinished = true;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "phresh",
|
|
3
3
|
"private": true,
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.42",
|
|
5
5
|
"description": "The official PhreshOS starter Program.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
@@ -14,15 +14,15 @@
|
|
|
14
14
|
"starter"
|
|
15
15
|
],
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@phreshos/client": "^0.1.
|
|
18
|
-
"@phreshos/core": "^0.1.
|
|
19
|
-
"@phreshos/react": "^0.1.
|
|
20
|
-
"@phreshos/server": "^0.1.
|
|
17
|
+
"@phreshos/client": "^0.1.48",
|
|
18
|
+
"@phreshos/core": "^0.1.56",
|
|
19
|
+
"@phreshos/react": "^0.1.29",
|
|
20
|
+
"@phreshos/server": "^0.1.52",
|
|
21
21
|
"react": "^19.2.8",
|
|
22
22
|
"react-dom": "^19.2.8"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@phreshos/cli": "^0.1.
|
|
25
|
+
"@phreshos/cli": "^0.1.67",
|
|
26
26
|
"@types/node": "^26.4.0",
|
|
27
27
|
"@types/react": "^19.2.18",
|
|
28
28
|
"@types/react-dom": "^19.2.5",
|
|
@@ -4,7 +4,7 @@ export default defineConfig({
|
|
|
4
4
|
identity: "phresh",
|
|
5
5
|
name: "Phresh Program",
|
|
6
6
|
description: "A minimal counter with direct Client and Server endpoints.",
|
|
7
|
-
version: "0.1.
|
|
7
|
+
version: "0.1.42",
|
|
8
8
|
icon: "icon.png",
|
|
9
9
|
categories: ["Development"],
|
|
10
10
|
keywords: ["example", "counter", "client", "server"],
|
package/dist/template.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"repository": "PhreshOS/phresh-program",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"sha256": "
|
|
3
|
+
"version": "0.1.42",
|
|
4
|
+
"sha256": "a05d624c773f52acaf7b16f65b0fd8f421bf61e7caad84348e4ec3871ae019cd",
|
|
5
5
|
"development": true
|
|
6
6
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phreshos/cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.67",
|
|
5
5
|
"description": "The Phresh command-line interface for Program projects and system management.",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=20.10"
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"packageManager": "bun@1.3.14",
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@clack/prompts": "^1.7.0",
|
|
50
|
-
"@phreshos/core": "^0.1.
|
|
51
|
-
"@phreshos/node": "^0.1.
|
|
50
|
+
"@phreshos/core": "^0.1.56",
|
|
51
|
+
"@phreshos/node": "^0.1.29",
|
|
52
52
|
"adm-zip": "^0.6.0",
|
|
53
53
|
"commander": "^15.0.0",
|
|
54
54
|
"picocolors": "^1.1.1"
|