@phreshos/cli 0.1.59 → 0.1.61

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.
@@ -18,7 +18,7 @@ export async function requireProgram(system, identity) {
18
18
  }
19
19
  export async function requireProcess(system, identity, programIdentity) {
20
20
  const process = programIdentity
21
- ? await (await requireProgram(system, programIdentity)).process.find(identity)
21
+ ? await (await requireProgram(system, programIdentity)).findProcess(identity)
22
22
  : await system.process.find(identity);
23
23
  if (!process)
24
24
  throw new Error(`Unknown Process "${identity}"`);
@@ -21,7 +21,7 @@ export default function processCommands(root, connect) {
21
21
  examples: ["phresh process list", "phresh process list --program terminal --json"]
22
22
  }, async ({ options }) => connected(connect, async (system) => {
23
23
  const processes = options.program
24
- ? await (await requireProgram(system, options.program)).process.list()
24
+ ? await (await requireProgram(system, options.program)).processes()
25
25
  : await system.process.list();
26
26
  const selected = page(processes, options.search, bounded(options.offset, "--offset", 0), bounded(options.limit, "--limit", 1, 100), current => `${current.identity}\n${current.name ?? ""}`);
27
27
  return { ...selected, data: await Promise.all(selected.data.map(processView)) };
@@ -45,7 +45,7 @@ export default function processCommands(root, connect) {
45
45
  examples: ["phresh process create --program terminal --server --client", "phresh process create --program terminal --name main --json"]
46
46
  }, async ({ options }) => connected(connect, async (system) => {
47
47
  const program = await requireProgram(system, options.program);
48
- return await processView(await program.process.create(launch(options)));
48
+ return await processView(await program.createProcess(launch(options)));
49
49
  }));
50
50
  defineCommand(processes, {
51
51
  name: "findOrCreate",
@@ -57,7 +57,7 @@ export default function processCommands(root, connect) {
57
57
  examples: ["phresh process find-or-create --program terminal --name main --json"]
58
58
  }, async ({ options }) => connected(connect, async (system) => {
59
59
  const program = await requireProgram(system, options.program);
60
- return await processView(await program.process.findOrCreate(launch(options, true)));
60
+ return await processView(await program.findOrCreateProcess(launch(options, true)));
61
61
  }));
62
62
  defineCommand(processes, {
63
63
  name: "exit",
@@ -82,14 +82,15 @@ export default function processCommands(root, connect) {
82
82
  }, async ({ options }) => connected(connect, async (system) => {
83
83
  if (options.process && options.event === "create")
84
84
  throw new Error("An individual Process does not emit create");
85
+ const timeout = options.timeout === undefined ? undefined : bounded(options.timeout, "--timeout", 1);
85
86
  const target = options.process
86
87
  ? await requireProcess(system, options.process, options.program)
87
88
  : options.program
88
- ? (await requireProgram(system, options.program)).process
89
+ ? await requireProgram(system, options.program)
89
90
  : system.process;
90
- const message = await wait(target, options.event, options.timeout === undefined
91
- ? undefined
92
- : bounded(options.timeout, "--timeout", 1));
91
+ const message = options.program && !options.process
92
+ ? await wait(target, options.event === "create" ? "processCreate" : "processExit", timeout)
93
+ : await wait(target, options.event, timeout);
93
94
  return {
94
95
  scope: options.process ? `process:${options.process}` : options.program ? `program:${options.program}` : "process",
95
96
  event: options.event,
@@ -5,7 +5,7 @@ import { dataOutput, eventOutput, eventPresentation, pageOutput, programListPres
5
5
  import { connected, requireProgram } from "./connection.js";
6
6
  import { bounded, integer, page } from "./input.js";
7
7
  import { wait } from "./observation.js";
8
- import { programView } from "./projection.js";
8
+ import { processView, programView } from "./projection.js";
9
9
  export default function programCommands(root, connect) {
10
10
  const programs = defineCommand(root, {
11
11
  name: "program",
@@ -60,13 +60,16 @@ export default function programCommands(root, connect) {
60
60
  requiresSystem: true,
61
61
  options: withJson(option("--event <event>", "Program lifecycle event", {
62
62
  mandatory: true,
63
- choices: ["create", "forget", "install", "uninstall"]
64
- }), option("--program <identity>", "scope forget or uninstall to one Program"), timeoutOption),
63
+ choices: ["create", "forget", "install", "uninstall", "processCreate", "processExit"]
64
+ }), option("--program <identity>", "observe events belonging to one Program"), timeoutOption),
65
65
  output: dataOutput(eventOutput("The observed Program event", value.any("Program state or uninstall result")), "One Program event", eventPresentation),
66
66
  examples: ["phresh program wait --event create", "phresh program wait --event uninstall --program terminal --json"]
67
67
  }, async ({ options }) => connected(connect, async (system) => {
68
- if (options.program && options.event !== "forget" && options.event !== "uninstall") {
69
- throw new Error("An individual Program emits only forget and uninstall");
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`);
70
73
  }
71
74
  const target = options.program ? await requireProgram(system, options.program) : system.program;
72
75
  const message = await wait(target, options.event, timeout(options.timeout));
@@ -80,10 +83,16 @@ export default function programCommands(root, connect) {
80
83
  async function eventView(event, message, scoped) {
81
84
  if (event === "uninstall") {
82
85
  if (scoped)
83
- return { program: await programView(scoped), purge: message === true };
86
+ return { program: await programView(scoped), purge: message.purge };
84
87
  const current = message;
85
88
  return { program: await programView(current.program), purge: current.purge };
86
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
+ }
87
96
  if (scoped)
88
97
  return programView(scoped);
89
98
  return programView(message);
@@ -15,7 +15,7 @@ export const value = Object.freeze({
15
15
  description
16
16
  }),
17
17
  array: (items, description) => ({ type: "array", items, description }),
18
- object: (properties, required, description, additionalProperties = false) => ({ type: "object", properties, required, additionalProperties, description }),
18
+ object: (properties, required, description, additionalProperties = true) => ({ type: "object", properties, required, additionalProperties, description }),
19
19
  nullable: (schema) => ({ anyOf: [schema, { type: "null" }] })
20
20
  });
21
21
  /** Validate one emitted JSON value against its declared CLI output contract. */
@@ -57,8 +57,6 @@ export function assertValue(value, contract, path = "result") {
57
57
  const property = contract.properties?.[name];
58
58
  if (property)
59
59
  assertValue(item, property, `${path}.${name}`);
60
- else if (contract.additionalProperties === false)
61
- throw new Error(`${path}.${name} is not declared by its CLI contract`);
62
60
  else if (typeof contract.additionalProperties === "object")
63
61
  assertValue(item, contract.additionalProperties, `${path}.${name}`);
64
62
  }
@@ -18,7 +18,7 @@ export default async function installProgram(program, options = {}) {
18
18
  else
19
19
  installed = await system.program.forceCreate(program);
20
20
  if (options.run)
21
- stopObserving = installed.process.subscribe("create", created => { process ??= created.identity; });
21
+ stopObserving = installed.subscribe("processCreate", created => { process ??= created.identity; });
22
22
  for await (const chunk of installed.install({ launch: options.run ? true : undefined, purge: options.purge }))
23
23
  writeProgramCommandOutput(chunk);
24
24
  installationFinished = true;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "phresh",
3
3
  "private": true,
4
- "version": "0.1.36",
4
+ "version": "0.1.37",
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.42",
18
- "@phreshos/core": "^0.1.48",
19
- "@phreshos/react": "^0.1.24",
20
- "@phreshos/server": "^0.1.46",
17
+ "@phreshos/client": "^0.1.43",
18
+ "@phreshos/core": "^0.1.49",
19
+ "@phreshos/react": "^0.1.25",
20
+ "@phreshos/server": "^0.1.47",
21
21
  "react": "^19.2.8",
22
22
  "react-dom": "^19.2.8"
23
23
  },
24
24
  "devDependencies": {
25
- "@phreshos/cli": "^0.1.59",
25
+ "@phreshos/cli": "^0.1.61",
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.36",
7
+ version: "0.1.37",
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.36",
4
- "sha256": "f22ae33155bc70b8533834835acdc8d8857a631caa57f135aa4ba5eeeb9fc4d0",
3
+ "version": "0.1.37",
4
+ "sha256": "2cf505d4ee6be9a7659b5969d59f7ed68fe9a2e44e79bd7fe827e9e42423b003",
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.59",
4
+ "version": "0.1.61",
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.48",
51
- "@phreshos/node": "^0.1.22",
50
+ "@phreshos/core": "^0.1.52",
51
+ "@phreshos/node": "^0.1.24",
52
52
  "adm-zip": "^0.6.0",
53
53
  "cli-table3": "^0.6.5",
54
54
  "commander": "^15.0.0",