@phreshos/cli 0.1.66 → 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.
@@ -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.getLaunch": ["program", "getLaunch"],
10
- "program.setLaunch": ["program", "setLaunch"],
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"],
@@ -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: "getLaunch",
64
- aliases: ["get-launch"],
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("Saved Process launch or null"), "The saved Program launch", { format: "value" }),
69
- examples: ["phresh program get-launch --program terminal --json"]
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: "getLaunch",
72
+ $operation: "definition",
73
73
  identity: options.program
74
74
  })));
75
75
  defineCommand(programs, {
76
- name: "setLaunch",
77
- aliases: ["set-launch"],
78
- description: executeDescription("program", "setLaunch"),
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("Saved Process launch"), "The saved Program launch", { format: "value" }),
82
- examples: ["phresh program set-launch --program terminal --client --name main --json"]
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: "setLaunch",
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
+ }
@@ -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 the installed Program before startup"), option("--purge", "delete existing installed Program storage")],
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."
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 declaration. An
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
- * The System executes the Program's stored startup after installation.
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
- if (options.run)
21
- stopObserving = installed.subscribe("processCreate", created => { process ??= created.identity; });
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.40",
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.46",
18
- "@phreshos/core": "^0.1.54",
19
- "@phreshos/react": "^0.1.28",
20
- "@phreshos/server": "^0.1.50",
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.66",
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.40",
7
+ version: "0.1.42",
8
8
  icon: "icon.png",
9
9
  categories: ["Development"],
10
10
  keywords: ["example", "counter", "client", "server"],
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "repository": "PhreshOS/phresh-program",
3
- "version": "0.1.40",
4
- "sha256": "7f2bb99438c7224e543147519a75d76a1db04313ff6ec6b024bb7532feb6a017",
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.66",
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.55",
51
- "@phreshos/node": "^0.1.28",
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"