ptbk 0.119.0-56 → 0.119.0-62

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.
@@ -30,8 +30,15 @@ export type IntendedUser = {
30
30
  */
31
31
  export declare function intendedUser(env?: NodeJS.ProcessEnv): IntendedUser;
32
32
  /**
33
- * The shared home-based container of new projects: exactly `<home>/ptbk/project/` (lowercase `ptbk`, singular
34
- * `project`, one child per independent project). It is only a filesystem container, never a project or repository.
33
+ * Selects an available home-based projects container without changing existing files. When a file blocks
34
+ * `<home>/ptbk/project`, try `ptbk-projects`, then numbered siblings. Preserve permission and other OS errors.
35
+ *
36
+ * @private shared default-location policy, including the pre-Node Windows installer
37
+ */
38
+ export declare function projectsRootForHome(home: string): string;
39
+ /**
40
+ * The shared home-based container for new projects, with a non-destructive fallback when a file blocks the preferred
41
+ * `<home>/ptbk/project/`. This is only a filesystem container, never a project or repository.
35
42
  *
36
43
  * @private user home and identity
37
44
  */
@@ -1,5 +1,5 @@
1
1
  import { execFileSync } from 'node:child_process';
2
- import { readFileSync } from 'node:fs';
2
+ import { lstatSync, readFileSync, statSync } from 'node:fs';
3
3
  import { lchown, lstat, readdir } from 'node:fs/promises';
4
4
  import { homedir, userInfo } from 'node:os';
5
5
  import { dirname, join, resolve } from 'node:path';
@@ -73,13 +73,54 @@ export function intendedUser(env = process.env) {
73
73
  return { name: account.name, home: account.home, uid: account.uid, gid: account.gid, scope: 'sudo' };
74
74
  }
75
75
  /**
76
- * The shared home-based container of new projects: exactly `<home>/ptbk/project/` (lowercase `ptbk`, singular
77
- * `project`, one child per independent project). It is only a filesystem container, never a project or repository.
76
+ * Selects an available home-based projects container without changing existing files. When a file blocks
77
+ * `<home>/ptbk/project`, try `ptbk-projects`, then numbered siblings. Preserve permission and other OS errors.
78
+ *
79
+ * @private shared default-location policy, including the pre-Node Windows installer
80
+ */
81
+ export function projectsRootForHome(home) {
82
+ /** Checks existing ancestors without creating a directory or replacing an occupied item. */
83
+ const available = (path) => {
84
+ for (let current = path;; current = dirname(current)) {
85
+ try {
86
+ const entry = lstatSync(current);
87
+ if (!entry.isSymbolicLink())
88
+ return entry.isDirectory();
89
+ try {
90
+ return statSync(current).isDirectory();
91
+ }
92
+ catch (error) {
93
+ if (['ENOENT', 'ENOTDIR'].includes(error.code ?? ''))
94
+ return false;
95
+ throw error;
96
+ }
97
+ }
98
+ catch (error) {
99
+ const code = error.code;
100
+ if (code === 'ENOTDIR')
101
+ return false;
102
+ if (code !== 'ENOENT')
103
+ throw error;
104
+ if (dirname(current) === current)
105
+ throw error;
106
+ }
107
+ }
108
+ };
109
+ for (let index = 0; index < 100; index++) {
110
+ const candidate = index === 0 ? join(home, 'ptbk', 'project') : join(home, index === 1 ? 'ptbk-projects' : `ptbk-projects-${index}`);
111
+ if (available(candidate))
112
+ return candidate;
113
+ }
114
+ throw new Error('No available home-based projects location was found. Choose a projects folder explicitly.');
115
+ }
116
+ /**
117
+ * The shared home-based container for new projects, with a non-destructive fallback when a file blocks the preferred
118
+ * `<home>/ptbk/project/`. This is only a filesystem container, never a project or repository.
78
119
  *
79
120
  * @private user home and identity
80
121
  */
81
122
  export function sharedProjectsRoot(env = process.env) {
82
- return join(intendedUser(env).home, 'ptbk', 'project');
123
+ return projectsRootForHome(intendedUser(env).home);
83
124
  }
84
125
  /**
85
126
  * The directories that do not exist yet on the way to a destination (outermost first): exactly what creating it adds.
@@ -1 +1 @@
1
- {"version":3,"file":"user-home.js","sourceRoot":"","sources":["../../src/common/user-home.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"user-home.js","sourceRoot":"","sources":["../../src/common/user-home.ts"],"names":[],"mappings":"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"}
@@ -36,8 +36,12 @@ Make the selected executables available immediately to the launched terminal, in
36
36
 
37
37
  Propose a writable projects root beneath the initiating user's actual home, defaulting to `<resolved-user-home>/ptbk/project/` under the shared [home/identity policy](workspace.md#home-directory-and-shared-projects-root). Show the resolved path and allow a different location. Create it if missing, otherwise reuse it. This is an ordinary container for independent project directories, not itself a Promptbook project, Git repository or global engine workspace.
38
38
 
39
+ If a legacy file or unavailable link occupies either segment of that default, select the shared safe alternative `<home>/ptbk-projects` (then numbered siblings when needed), explain the alternative and display its resolved path in the wizard. Preserve the occupying item, including an empty file. Reserve npm's extensionless `ptbk` launcher at its resolved global prefix even before it exists; do not create a projects directory where npm needs that launcher. Recheck the default after preparing Node/npm. Explicitly supplied or edited locations never move to another folder automatically. Read-only default discovery creates no project directories; create the accepted container only after the software location is known.
40
+
39
41
  Offer **Create the first project** with an editable, sensible folder name and a way to skip it. Create one empty child directory for the accepted project. Folder naming is not a project brief; intent is still collected by init. Do not prepopulate Books, `ptbk.json`, package metadata or `.git` in either the projects root or its new child.
40
42
 
43
+ Validate the complete projects root and valid Windows child name before installing or changing prerequisites or the CLI, and recheck before handoff. Create all missing parent directories using literal filesystem paths. A file where a directory is needed, inaccessible ancestor, unavailable link, or existing nonempty destination is an actionable folder error; preserve the conflicting item. An existing first-project directory link is refused rather than initializing outside the selected root. Keep the original failing path, ancestor types and underlying OS error in diagnostics. Skipping project creation does not require or create a projects root.
44
+
41
45
  Validate writability and valid Windows names before handoff. A collision must not overwrite content: offer another name or explicit reuse of an existing empty directory. Do not silently initialize a nonempty directory, create a duplicate project on retry, or interpret a project name as a path escaping the selected root. Spaces, Unicode and shell-special characters in valid paths must be handled safely without changing their meaning or executing them as commands.
42
46
 
43
47
  Skipping the first project leaves the CLI installed and reports that no project was initialized. It must not initialize the projects root as a fallback. With desktop selected, open its project overview without starting first-project setup on that launch; New project returns to shared init. CLI-only completion explains how to run init later.
@@ -56,6 +60,8 @@ If automatic terminal launch is unavailable, report the failed handoff distinctl
56
60
 
57
61
  Separate preparation, directory creation and terminal handoff outcomes. A failed download, denied permission or package installation must stop the dependent steps, show the actual failed stage, error and useful retry action directly in the installer, and retain readable diagnostics without secrets. Unexpected PowerShell exceptions use the same result channel; no message may rely on a separate terminal window. Retry transient downloads and verify their checksums before use. Never launch an initializer against missing/unverified dependencies or claim a project is ready merely because the installer finished.
58
62
 
63
+ Every handled preparation error, invalid destination and installed-version decision offers **Copy report**. The report is selectable/scrollable and includes the exact installer version, OS/PowerShell, failed stage/code, selected destination, useful recovery action and recent diagnostics, with credentials redacted and no environment dump. Copying must keep the dialog open without choosing Retry, Replace or Cancel; report access remains on the incomplete final page. If PowerShell or report creation fails, the native dialog still provides a minimal report. Folder failures after preparation allow selecting another projects root without discarding satisfied installation steps.
64
+
59
65
  Repeating setup rechecks and reuses satisfied prerequisites, the requested package version and approved empty destination. Do not duplicate PATH entries, reset project configuration, delete existing user files or launch duplicate initializers from repeated completion actions. Resume already-started project setup through ordinary CLI behavior with explicit user intent, not by treating its now-nonempty directory as a new empty project. Reinstallation, repair and any removal of the bootstrap layer preserve user projects and shared Node.js/npm/Git installations.
60
66
 
61
67
  ## Acceptance outcomes
@@ -74,4 +80,8 @@ The desktop executable and tray controller follow [the desktop contract](desktop
74
80
 
75
81
  ## Windows discovery and completion
76
82
 
77
- Show the Promptbook logo and license acceptance before installation. Create `Promptbook terminal` and `ptbk` Start menu shortcuts for the ordinary context-aware CLI, with the verified runtime and user home. With desktop selected, add `Promptbook` for the graphical client and register only its tray controller at sign-in. Uninstalling desktop removes that registration and its own files without stopping or deleting the separate engines/projects. Preserve lowercase `ptbk` in command examples. Failed or declined preparation must change the final page to an explicit incomplete result and return a nonzero setup exit code. Codex and Claude Code remain choices in ordinary init.
83
+ Show the Promptbook logo and license acceptance before installation. Create `Promptbook terminal` and `ptbk` Start menu shortcuts for the ordinary context-aware CLI, with the verified runtime and user home. Resolve the per-user Programs known folder without requiring it to exist yet, create missing directories through literal paths, and reuse those shortcuts on repeated setup, including redirected profiles. With desktop selected, add `Promptbook` for the graphical client and register only its tray controller at sign-in. Uninstalling desktop removes that registration and its own files without stopping or deleting the separate engines/projects. Preserve lowercase `ptbk` in command examples. Failed or declined preparation must change the final page to an explicit incomplete result and return a nonzero setup exit code. Codex and Claude Code remain choices in ordinary init.
84
+
85
+ ## Unattended installer verification
86
+
87
+ For reproducible Windows checks, `/ProjectsRoot="<path>"` and `/ProjectName="<name>"` select the same fields as the wizard. `/SkipProject=yes` selects its ordinary skip option. `/PrepareOnly=yes` explicitly suppresses initializer launch after verifying software and preparing the empty destination; completion states that project setup was not launched. These options compose with Inno Setup's standard silent/component switches, retain the same validation and nonzero incomplete outcomes, and never change ordinary double-click setup behavior.
@@ -12,6 +12,8 @@ Resolve the intended OS account's actual home at runtime through shared platform
12
12
 
13
13
  The convenience root is exactly `ptbk/project/` beneath that home: lowercase `ptbk`, singular lowercase `project`, one child per independent project. Example paths are `C:\Users\Alice\ptbk\project\demo`, `/Users/alice/ptbk/project/demo` and `/home/alice/ptbk/project/demo`; these illustrate layouts, not account lookup rules. Explicit destinations and existing projects remain unchanged.
14
14
 
15
+ When an existing file or unavailable directory link blocks that default, preserve it and propose `<home>/ptbk-projects`, then `ptbk-projects-2`, `ptbk-projects-3`, and so on until an available ordinary container is found. Reuse an existing usable container consistently on later launches. Show the resolved suggestion before confirmation. This fallback applies only to a suggested default; an explicit destination remains the user's choice and receives an actionable error when blocked. The Windows bootstrap also reserves npm's extensionless `ptbk` launcher before package installation when the global prefix is the user's home.
16
+
15
17
  On Linux an ordinary launch uses that user's home. A launch through `sudo` on behalf of another user keeps the validated **original invoking user's** home and ptbk project/discovery scope even if the effective process account or `HOME` names root. Direct root launch without an originating non-root sudo user uses root's actual home. Do not guess ownership from CWD or blindly trust an environment-supplied username/path. Diagnose an unresolved intended account/home before creating a project elsewhere.
16
18
 
17
19
  Init defaults, known-project registry and engine discovery share this identity resolution; detached/recovered launches preserve that intended scope. This grants no extra cross-user or harness/browser account authority. Keep created files/directories usable by their intended owner; elevated creation must not accidentally leave a user's project root-only. Do not recursively change unrelated ownership/permissions.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ptbk",
3
- "version": "0.119.0-56",
3
+ "version": "0.119.0-62",
4
4
  "description": "Autonomous AI agendas on your machine. Readable agents, your choice of models, and Git history under your control.",
5
5
  "private": false,
6
6
  "sideEffects": false,