@jals1212/pi-spaces 0.4.0 → 0.5.0

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/CHANGELOG.md CHANGED
@@ -6,6 +6,26 @@ commands and options and a patch version fixes.
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## 0.5.0
10
+
11
+ ### Added
12
+
13
+ - `/space new` names `pi-space setup <name>` when `PI_SPACES_SETUP` holds a
14
+ setup command, so a space a program needs prepared is not entered bare.
15
+
16
+ ### Changed
17
+
18
+ - `setup` is a reserved name, as the other command words are. A space already
19
+ named `setup` is no longer listed; rename its folder by hand.
20
+
21
+ ## 0.4.1
22
+
23
+ ### Changed
24
+
25
+ - The status line shows `◆ base` in the base home when pi-spaces opened it
26
+ (`pi --space base`, `pi-space base`, or a switch back to base); Pi started
27
+ plainly still shows nothing there.
28
+
9
29
  ## 0.4.0
10
30
 
11
31
  ### Added
package/README.md CHANGED
@@ -59,7 +59,7 @@ A new space starts empty except for a `settings.json` that declares this package
59
59
  | --- | --- |
60
60
  | `/space` | Opens a list of the other spaces and restarts Pi in the one you pick. Without the interactive terminal it lists them instead. |
61
61
  | `/space list` | Lists `base` and every space, with `*` on the active one. |
62
- | `/space new <name>` | Creates an empty space. |
62
+ | `/space new <name>` | Creates an empty space. When a setup command is set (`PI_SPACES_SETUP`), it names `pi-space setup <name>` to run from a shell. |
63
63
  | `/space switch <name>` | Restarts Pi in that space. `base` is the home Pi started with. |
64
64
  | `/space switch` | Same as `/space`. |
65
65
  | `/space rename <old> <new>` | Renames a space. The active space cannot be renamed. |
@@ -67,15 +67,15 @@ A new space starts empty except for a `settings.json` that declares this package
67
67
  | `pi --space <name>` | Starts Pi directly in a space, keeping the prompt and every other option. |
68
68
  | `pi --space <name> <command> [args...]` | Runs one of Pi's package commands (`install`, `remove`, `uninstall`, `update`, `list`) in a space, or in the base home with `base`: `pi --space work update --extensions`, `pi --space work install npm:<package>`. |
69
69
 
70
- The status line shows `◆ <name>` while a space is active, and nothing in the base home.
70
+ The status line shows `◆ <name>` while a space is active. In the base home it shows `◆ base` when pi-spaces opened it (`pi --space base`, `pi-space base`, or `/space switch base`), and nothing when Pi was started plainly.
71
71
 
72
72
  Choosing an argument such as `switch` from the `/space ` suggestions only fills the line; press Enter again to run it. `/space` and Enter opens the picker in one step.
73
73
 
74
- **Names**: lowercase letters, digits, `-` and `_`, starting with a letter or digit, at most 64 characters. `base` is reserved, and so are the command words `list`, `new`, `remove`, `rename`, `switch`, `update`, `install` and `uninstall`.
74
+ **Names**: lowercase letters, digits, `-` and `_`, starting with a letter or digit, at most 64 characters. `base` is reserved, and so are the command words `list`, `new`, `remove`, `rename`, `switch`, `update`, `install`, `uninstall` and `setup`.
75
75
 
76
76
  ## The `pi-space` command
77
77
 
78
- The optional `@jals1212/pi-spaces-cli` package adds a `pi-space` command to your shell: `pi-space` picks a space from a numbered list and starts Pi in it, `pi-space <name> [pi args...]` starts Pi in a named space, `pi-space new <name>` creates one, `pi-space rename <old> <new>` renames one, `pi-space remove <name>` deletes one, and `pi-space list` lists them. `pi-space list|update|install|uninstall <name|--every> ...` runs Pi's package commands in a space, or in every space. `--command` and `--dir` (or `PI_SPACES_COMMAND` and `PI_SPACES_DIR`) make it run another program that runs Pi, with that program's spaces. It only runs `pi --space <name> [command]`, so this extension must be installed in the home it opens. See [`cli/README.md`](cli/README.md) for the commands, the options and the exit status.
78
+ The optional `@jals1212/pi-spaces-cli` package adds a `pi-space` command to your shell: `pi-space` picks a space from a numbered list and starts Pi in it, `pi-space <name> [pi args...]` starts Pi in a named space, `pi-space new <name>` creates one, `pi-space rename <old> <new>` renames one, `pi-space remove <name>` deletes one, and `pi-space list` lists them. `pi-space list|update|install|uninstall <name|--every> ...` runs Pi's package commands in a space, or in every space. `--command` and `--dir` (or `PI_SPACES_COMMAND` and `PI_SPACES_DIR`) make it run another program that runs Pi, with that program's spaces, and `--setup` (or `PI_SPACES_SETUP`) gives that program's command to prepare a new space: `pi-space new` runs it, and `pi-space setup <name|--every>` runs it again. It only runs `pi --space <name> [command]`, so this extension must be installed in the home it opens. See [`cli/README.md`](cli/README.md) for the commands, the options and the exit status.
79
79
 
80
80
  ## Configuration reference
81
81
 
@@ -91,6 +91,7 @@ Read:
91
91
  | --- | --- |
92
92
  | `PI_SPACES_DIR` | The spaces folder. A relative value is taken from your home folder. Default: `spaces` next to the base home. |
93
93
  | `PI_SPACES_COMMAND` | For the `pi-space` command ([`cli/README.md`](cli/README.md)): the program to run, before `--space <name>`. Default: `pi`. |
94
+ | `PI_SPACES_SETUP` | For the `pi-space` command: the command that prepares a new space. `/space new` names `pi-space setup <name>` when it is set. |
94
95
  | `PI_CODING_AGENT_DIR` | Pi's agent home; its parent holds the default spaces folder. Default: `~/.pi/agent`. |
95
96
 
96
97
  Set for the Pi a switch starts:
package/dist/command.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // The /space command, kept apart from Pi's extension API so it can be tested directly.
2
2
  import { join } from "node:path";
3
- import { relaunchEnv, resolveSwitch } from "./relaunch.js";
3
+ import { parseSpaceFlag, relaunchEnv, resolveSwitch } from "./relaunch.js";
4
4
  import {
5
5
  activeSpace,
6
6
  BACKUPS,
@@ -9,6 +9,7 @@ import {
9
9
  checkRemovable,
10
10
  createSpace,
11
11
 
12
+ hasSetupCommand,
12
13
  listSpaces,
13
14
 
14
15
  removeSpace,
@@ -55,7 +56,13 @@ export async function runSpaceCommand(args , deps )
55
56
  if (sub === "list" && rest.length === 0) return list(deps);
56
57
  if (sub === "new" && rest.length === 1) {
57
58
  const path = createSpace(deps.dir, rest[0], deps.declaration());
58
- ctx.ui.notify(`Created space "${rest[0]}" at ${path}. Enter it with /space switch ${rest[0]}.`, "info");
59
+ const name = rest[0];
60
+ ctx.ui.notify(
61
+ hasSetupCommand(deps.env)
62
+ ? `Created space "${name}" at ${path}. Prepare it from a shell with: pi-space setup ${name}. Then enter it with /space switch ${name}.`
63
+ : `Created space "${name}" at ${path}. Enter it with /space switch ${name}.`,
64
+ "info",
65
+ );
59
66
  return;
60
67
  }
61
68
  const removal = sub === "remove" ? parseRemove(rest) : undefined;
@@ -154,10 +161,17 @@ function switchTo(name , deps ) {
154
161
  ctx.shutdown();
155
162
  }
156
163
 
157
- /** Status line text: the active space, or nothing in the base home. */
158
- export function statusText(dir , currentHome ) {
164
+ /**
165
+ * Status line text: the active space; in the base home, `◆ base` only when pi-spaces opened it
166
+ * (`pi --space base`, which `pi-space base` runs, or a switch back to base, which sets
167
+ * PI_SPACES_BASE_HOME), and nothing when Pi was started plainly.
168
+ */
169
+ export function statusText(dir , currentHome , proc = process, env = process.env) {
159
170
  const active = activeSpace(dir, currentHome);
160
- return active === undefined ? undefined : `◆ ${active}`;
171
+ if (active !== undefined) return `◆ ${active}`;
172
+ const parsed = parseSpaceFlag(proc.argv.slice(2));
173
+ const openedBySpaces = ("name" in parsed && parsed.name === BASE) || Boolean(env.PI_SPACES_BASE_HOME);
174
+ return openedBySpaces ? `◆ ${BASE}` : undefined;
161
175
  }
162
176
 
163
177
  export function completeSpaceArgs(prefix , dir ) {
package/dist/spaces.js CHANGED
@@ -38,7 +38,12 @@ export function spacesDir(env = process.env, home = osHomedir())
38
38
  }
39
39
 
40
40
  // The words of the pi-space and /space commands, so a space name never reads as one.
41
- const COMMANDS = new Set(["list", "new", "remove", "rename", "switch", "update", "install", "uninstall"]);
41
+ const COMMANDS = new Set(["list", "new", "remove", "rename", "switch", "update", "install", "uninstall", "setup"]);
42
+
43
+ /** True when PI_SPACES_SETUP holds a setup command, not just blanks. */
44
+ export function hasSetupCommand(env ) {
45
+ return (env.PI_SPACES_SETUP ?? "").trim() !== "";
46
+ }
42
47
 
43
48
  /** Returns the error message for an unusable name, or undefined when the name is valid. */
44
49
  export function validateName(name ) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jals1212/pi-spaces",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Named spaces for Pi: keep several agent homes (sign-ins, packages, settings) and pick one by name.",
5
5
  "license": "MIT",
6
6
  "author": "jals1212",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: pi-spaces
3
- description: "Trigger: pi-spaces, space, spaces, /space, pi-space, pi --space, PI_SPACE, PI_SPACE_HOME, PI_SPACES_COMMAND, which space, agent home, base home, update, install, uninstall. Know which Pi space this session runs in, its home and start command, and how spaces and their packages are listed, created, updated, switched and removed."
3
+ description: "Trigger: pi-spaces, space, spaces, /space, pi-space, pi --space, PI_SPACE, PI_SPACE_HOME, PI_SPACES_COMMAND, PI_SPACES_SETUP, which space, agent home, base home, update, install, uninstall, setup. Know which Pi space this session runs in, its home and start command, and how spaces and their packages are listed, created, set up, updated, switched and removed."
4
4
  license: MIT
5
5
  metadata:
6
6
  author: jals1212
@@ -27,12 +27,13 @@ Use when a task depends on which Pi agent home this session uses (settings, sign
27
27
  | Which space, home, command | `<pi_space>` section, or `echo "$PI_SPACE|$PI_SPACE_HOME|$PI_SPACES_COMMAND"` |
28
28
  | List spaces from a shell | `pi-space list` (optional `@jals1212/pi-spaces-cli`) |
29
29
  | Spaces folder | `PI_SPACES_DIR`, else `spaces` next to the base home (`PI_SPACES_BASE_HOME`, else this home) |
30
- | Create a space | `pi-space new <name>`, or ask the user for `/space new <name>` |
30
+ | Create a space | `pi-space new <name>`, or ask the user for `/space new <name>`; `pi-space new` also runs the setup command when there is one (`--setup <cmd>` or `PI_SPACES_SETUP`) |
31
+ | Prepare a space for the program that runs Pi | `pi-space setup <name|--every>`: runs the setup command (`{home}` and `{name}` become the space's folder and name) with the space as `PI_CODING_AGENT_DIR`; never in base |
31
32
  | Work in another space | User runs `/space switch <name>`, or `$PI_SPACES_COMMAND --space <name> "<prompt>"` |
32
33
  | Remove a space | User request only: `pi-space remove <name> --yes` keeps a backup in `.backups` |
33
34
  | Packages of a space | `pi-space update <name|base|--every> --extensions`, `pi-space install <name> <source>`, `pi-space uninstall <name> <source>`, `pi-space list <name>`; without the CLI, `$PI_SPACES_COMMAND --space <name|base> update --extensions` |
34
35
 
35
- Names: lowercase letters, digits, `-` and `_`, starting with a letter or digit, at most 64 characters; `base` (the base home) and the command words (`list`, `new`, `remove`, `rename`, `switch`, `update`, `install`, `uninstall`) are reserved.
36
+ Names: lowercase letters, digits, `-` and `_`, starting with a letter or digit, at most 64 characters; `base` (the base home) and the command words (`list`, `new`, `remove`, `rename`, `switch`, `update`, `install`, `uninstall`, `setup`) are reserved.
36
37
 
37
38
  ## Execution Steps
38
39
 
package/src/command.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  // The /space command, kept apart from Pi's extension API so it can be tested directly.
2
2
  import { join } from "node:path";
3
- import { type Command, relaunchEnv, resolveSwitch } from "./relaunch.ts";
3
+ import { type Command, parseSpaceFlag, relaunchEnv, resolveSwitch } from "./relaunch.ts";
4
4
  import {
5
5
  activeSpace,
6
6
  BACKUPS,
@@ -9,6 +9,7 @@ import {
9
9
  checkRemovable,
10
10
  createSpace,
11
11
  type Env,
12
+ hasSetupCommand,
12
13
  listSpaces,
13
14
  type PackageDeclaration,
14
15
  removeSpace,
@@ -55,7 +56,13 @@ export async function runSpaceCommand(args: string, deps: SpaceCommandDeps): Pro
55
56
  if (sub === "list" && rest.length === 0) return list(deps);
56
57
  if (sub === "new" && rest.length === 1) {
57
58
  const path = createSpace(deps.dir, rest[0], deps.declaration());
58
- ctx.ui.notify(`Created space "${rest[0]}" at ${path}. Enter it with /space switch ${rest[0]}.`, "info");
59
+ const name = rest[0];
60
+ ctx.ui.notify(
61
+ hasSetupCommand(deps.env)
62
+ ? `Created space "${name}" at ${path}. Prepare it from a shell with: pi-space setup ${name}. Then enter it with /space switch ${name}.`
63
+ : `Created space "${name}" at ${path}. Enter it with /space switch ${name}.`,
64
+ "info",
65
+ );
59
66
  return;
60
67
  }
61
68
  const removal = sub === "remove" ? parseRemove(rest) : undefined;
@@ -154,10 +161,17 @@ function switchTo(name: string, deps: SpaceCommandDeps): void {
154
161
  ctx.shutdown();
155
162
  }
156
163
 
157
- /** Status line text: the active space, or nothing in the base home. */
158
- export function statusText(dir: string, currentHome: string): string | undefined {
164
+ /**
165
+ * Status line text: the active space; in the base home, `◆ base` only when pi-spaces opened it
166
+ * (`pi --space base`, which `pi-space base` runs, or a switch back to base, which sets
167
+ * PI_SPACES_BASE_HOME), and nothing when Pi was started plainly.
168
+ */
169
+ export function statusText(dir: string, currentHome: string, proc: { argv: string[] } = process, env: Env = process.env): string | undefined {
159
170
  const active = activeSpace(dir, currentHome);
160
- return active === undefined ? undefined : `◆ ${active}`;
171
+ if (active !== undefined) return `◆ ${active}`;
172
+ const parsed = parseSpaceFlag(proc.argv.slice(2));
173
+ const openedBySpaces = ("name" in parsed && parsed.name === BASE) || Boolean(env.PI_SPACES_BASE_HOME);
174
+ return openedBySpaces ? `◆ ${BASE}` : undefined;
161
175
  }
162
176
 
163
177
  export function completeSpaceArgs(prefix: string, dir: string): { value: string; label: string }[] | null {
package/src/spaces.ts CHANGED
@@ -38,7 +38,12 @@ export function spacesDir(env: Env = process.env, home: string = osHomedir()): s
38
38
  }
39
39
 
40
40
  // The words of the pi-space and /space commands, so a space name never reads as one.
41
- const COMMANDS = new Set(["list", "new", "remove", "rename", "switch", "update", "install", "uninstall"]);
41
+ const COMMANDS = new Set(["list", "new", "remove", "rename", "switch", "update", "install", "uninstall", "setup"]);
42
+
43
+ /** True when PI_SPACES_SETUP holds a setup command, not just blanks. */
44
+ export function hasSetupCommand(env: Env): boolean {
45
+ return (env.PI_SPACES_SETUP ?? "").trim() !== "";
46
+ }
42
47
 
43
48
  /** Returns the error message for an unusable name, or undefined when the name is valid. */
44
49
  export function validateName(name: string): string | undefined {