visionos-monorepo 0.1.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.
Files changed (160) hide show
  1. package/.claude/worktrees/competent-burnell-8d1330/README.md +138 -0
  2. package/.claude/worktrees/competent-burnell-8d1330/cli/package.json +35 -0
  3. package/.claude/worktrees/competent-burnell-8d1330/cli/scripts/copy-web-assets.mjs +12 -0
  4. package/.claude/worktrees/competent-burnell-8d1330/cli/src/commands/logout.ts +12 -0
  5. package/.claude/worktrees/competent-burnell-8d1330/cli/src/commands/open.ts +19 -0
  6. package/.claude/worktrees/competent-burnell-8d1330/cli/src/commands/start.ts +97 -0
  7. package/.claude/worktrees/competent-burnell-8d1330/cli/src/commands/status.ts +23 -0
  8. package/.claude/worktrees/competent-burnell-8d1330/cli/src/commands/userinfo.ts +47 -0
  9. package/.claude/worktrees/competent-burnell-8d1330/cli/src/index.ts +23 -0
  10. package/.claude/worktrees/competent-burnell-8d1330/cli/src/lib/auth.ts +84 -0
  11. package/.claude/worktrees/competent-burnell-8d1330/cli/src/lib/browser.ts +37 -0
  12. package/.claude/worktrees/competent-burnell-8d1330/cli/src/lib/localState.ts +80 -0
  13. package/.claude/worktrees/competent-burnell-8d1330/cli/src/lib/runtime.ts +203 -0
  14. package/.claude/worktrees/competent-burnell-8d1330/cli/src/runtime/index.ts +36 -0
  15. package/.claude/worktrees/competent-burnell-8d1330/cli/src/types/inquirer.d.ts +9 -0
  16. package/.claude/worktrees/competent-burnell-8d1330/cli/tsconfig.json +19 -0
  17. package/.claude/worktrees/competent-burnell-8d1330/client/index.html +15 -0
  18. package/.claude/worktrees/competent-burnell-8d1330/client/package.json +27 -0
  19. package/.claude/worktrees/competent-burnell-8d1330/client/postcss.config.cjs +7 -0
  20. package/.claude/worktrees/competent-burnell-8d1330/client/src/App.tsx +57 -0
  21. package/.claude/worktrees/competent-burnell-8d1330/client/src/components/CliAuthPage.tsx +385 -0
  22. package/.claude/worktrees/competent-burnell-8d1330/client/src/components/ManifestoPage.tsx +946 -0
  23. package/.claude/worktrees/competent-burnell-8d1330/client/src/components/TrackCard.tsx +19 -0
  24. package/.claude/worktrees/competent-burnell-8d1330/client/src/lib/api.ts +58 -0
  25. package/.claude/worktrees/competent-burnell-8d1330/client/src/main.tsx +11 -0
  26. package/.claude/worktrees/competent-burnell-8d1330/client/src/styles/index.css +33 -0
  27. package/.claude/worktrees/competent-burnell-8d1330/client/src/styles/manifesto.css +1398 -0
  28. package/.claude/worktrees/competent-burnell-8d1330/client/tailwind.config.ts +36 -0
  29. package/.claude/worktrees/competent-burnell-8d1330/client/tsconfig.json +25 -0
  30. package/.claude/worktrees/competent-burnell-8d1330/client/vite.config.ts +20 -0
  31. package/.claude/worktrees/competent-burnell-8d1330/package-lock.json +5278 -0
  32. package/.claude/worktrees/competent-burnell-8d1330/package.json +24 -0
  33. package/.claude/worktrees/competent-burnell-8d1330/server/package.json +25 -0
  34. package/.claude/worktrees/competent-burnell-8d1330/server/src/app.ts +71 -0
  35. package/.claude/worktrees/competent-burnell-8d1330/server/src/config/env.ts +14 -0
  36. package/.claude/worktrees/competent-burnell-8d1330/server/src/features/auth/sessionStore.ts +74 -0
  37. package/.claude/worktrees/competent-burnell-8d1330/server/src/index.ts +8 -0
  38. package/.claude/worktrees/competent-burnell-8d1330/server/src/routes/auth.ts +112 -0
  39. package/.claude/worktrees/competent-burnell-8d1330/server/src/routes/health.ts +14 -0
  40. package/.claude/worktrees/competent-burnell-8d1330/server/tsconfig.json +19 -0
  41. package/.claude/worktrees/competent-burnell-8d1330/shared/package.json +24 -0
  42. package/.claude/worktrees/competent-burnell-8d1330/shared/src/index.ts +91 -0
  43. package/.claude/worktrees/competent-burnell-8d1330/shared/tsconfig.json +16 -0
  44. package/.claude/worktrees/competent-burnell-8d1330/tsconfig.base.json +12 -0
  45. package/.claude/worktrees/competent-burnell-8d1330/visionos-manifesto/index.html +392 -0
  46. package/.claude/worktrees/competent-burnell-8d1330/visionos-manifesto/script.js +146 -0
  47. package/.claude/worktrees/competent-burnell-8d1330/visionos-manifesto/styles.css +1082 -0
  48. package/.claude/worktrees/vigilant-napier-0de76f/README.md +138 -0
  49. package/.claude/worktrees/vigilant-napier-0de76f/cli/package.json +35 -0
  50. package/.claude/worktrees/vigilant-napier-0de76f/cli/scripts/copy-web-assets.mjs +12 -0
  51. package/.claude/worktrees/vigilant-napier-0de76f/cli/src/commands/logout.ts +12 -0
  52. package/.claude/worktrees/vigilant-napier-0de76f/cli/src/commands/open.ts +19 -0
  53. package/.claude/worktrees/vigilant-napier-0de76f/cli/src/commands/start.ts +97 -0
  54. package/.claude/worktrees/vigilant-napier-0de76f/cli/src/commands/status.ts +23 -0
  55. package/.claude/worktrees/vigilant-napier-0de76f/cli/src/commands/userinfo.ts +47 -0
  56. package/.claude/worktrees/vigilant-napier-0de76f/cli/src/index.ts +23 -0
  57. package/.claude/worktrees/vigilant-napier-0de76f/cli/src/lib/auth.ts +84 -0
  58. package/.claude/worktrees/vigilant-napier-0de76f/cli/src/lib/browser.ts +37 -0
  59. package/.claude/worktrees/vigilant-napier-0de76f/cli/src/lib/localState.ts +80 -0
  60. package/.claude/worktrees/vigilant-napier-0de76f/cli/src/lib/runtime.ts +203 -0
  61. package/.claude/worktrees/vigilant-napier-0de76f/cli/src/runtime/index.ts +36 -0
  62. package/.claude/worktrees/vigilant-napier-0de76f/cli/src/types/inquirer.d.ts +9 -0
  63. package/.claude/worktrees/vigilant-napier-0de76f/cli/tsconfig.json +19 -0
  64. package/.claude/worktrees/vigilant-napier-0de76f/client/index.html +15 -0
  65. package/.claude/worktrees/vigilant-napier-0de76f/client/package.json +27 -0
  66. package/.claude/worktrees/vigilant-napier-0de76f/client/postcss.config.cjs +7 -0
  67. package/.claude/worktrees/vigilant-napier-0de76f/client/src/App.tsx +57 -0
  68. package/.claude/worktrees/vigilant-napier-0de76f/client/src/components/CliAuthPage.tsx +385 -0
  69. package/.claude/worktrees/vigilant-napier-0de76f/client/src/components/ManifestoPage.tsx +946 -0
  70. package/.claude/worktrees/vigilant-napier-0de76f/client/src/components/TrackCard.tsx +19 -0
  71. package/.claude/worktrees/vigilant-napier-0de76f/client/src/lib/api.ts +58 -0
  72. package/.claude/worktrees/vigilant-napier-0de76f/client/src/main.tsx +11 -0
  73. package/.claude/worktrees/vigilant-napier-0de76f/client/src/styles/index.css +33 -0
  74. package/.claude/worktrees/vigilant-napier-0de76f/client/src/styles/manifesto.css +1398 -0
  75. package/.claude/worktrees/vigilant-napier-0de76f/client/tailwind.config.ts +36 -0
  76. package/.claude/worktrees/vigilant-napier-0de76f/client/tsconfig.json +25 -0
  77. package/.claude/worktrees/vigilant-napier-0de76f/client/vite.config.ts +20 -0
  78. package/.claude/worktrees/vigilant-napier-0de76f/package-lock.json +5278 -0
  79. package/.claude/worktrees/vigilant-napier-0de76f/package.json +24 -0
  80. package/.claude/worktrees/vigilant-napier-0de76f/server/package.json +25 -0
  81. package/.claude/worktrees/vigilant-napier-0de76f/server/src/app.ts +71 -0
  82. package/.claude/worktrees/vigilant-napier-0de76f/server/src/config/env.ts +14 -0
  83. package/.claude/worktrees/vigilant-napier-0de76f/server/src/features/auth/sessionStore.ts +74 -0
  84. package/.claude/worktrees/vigilant-napier-0de76f/server/src/index.ts +8 -0
  85. package/.claude/worktrees/vigilant-napier-0de76f/server/src/routes/auth.ts +112 -0
  86. package/.claude/worktrees/vigilant-napier-0de76f/server/src/routes/health.ts +14 -0
  87. package/.claude/worktrees/vigilant-napier-0de76f/server/tsconfig.json +19 -0
  88. package/.claude/worktrees/vigilant-napier-0de76f/shared/package.json +24 -0
  89. package/.claude/worktrees/vigilant-napier-0de76f/shared/src/index.ts +91 -0
  90. package/.claude/worktrees/vigilant-napier-0de76f/shared/tsconfig.json +16 -0
  91. package/.claude/worktrees/vigilant-napier-0de76f/tsconfig.base.json +12 -0
  92. package/.claude/worktrees/vigilant-napier-0de76f/visionos-manifesto/index.html +392 -0
  93. package/.claude/worktrees/vigilant-napier-0de76f/visionos-manifesto/script.js +146 -0
  94. package/.claude/worktrees/vigilant-napier-0de76f/visionos-manifesto/styles.css +1082 -0
  95. package/.github/workflows/publish.yml +30 -0
  96. package/README.md +175 -0
  97. package/cli/README.md +165 -0
  98. package/cli/package.json +36 -0
  99. package/cli/scripts/copy-web-assets.mjs +12 -0
  100. package/cli/src/commands/lessons.ts +68 -0
  101. package/cli/src/commands/login.ts +46 -0
  102. package/cli/src/commands/logout.ts +12 -0
  103. package/cli/src/commands/open.ts +29 -0
  104. package/cli/src/commands/start.ts +146 -0
  105. package/cli/src/commands/status.ts +28 -0
  106. package/cli/src/commands/userinfo.ts +59 -0
  107. package/cli/src/index.ts +109 -0
  108. package/cli/src/lib/auth.ts +84 -0
  109. package/cli/src/lib/browser.ts +37 -0
  110. package/cli/src/lib/content.ts +57 -0
  111. package/cli/src/lib/lessonPrinter.ts +38 -0
  112. package/cli/src/lib/lessonRunner.ts +381 -0
  113. package/cli/src/lib/localState.ts +114 -0
  114. package/cli/src/lib/loginFlow.ts +74 -0
  115. package/cli/src/lib/progress.ts +94 -0
  116. package/cli/src/lib/runtime.ts +220 -0
  117. package/cli/src/lib/validator.ts +401 -0
  118. package/cli/src/runtime/index.ts +108 -0
  119. package/cli/src/types/inquirer.d.ts +9 -0
  120. package/cli/tsconfig.json +19 -0
  121. package/client/index.html +15 -0
  122. package/client/package.json +27 -0
  123. package/client/postcss.config.cjs +7 -0
  124. package/client/src/App.tsx +102 -0
  125. package/client/src/components/AccountPage.tsx +79 -0
  126. package/client/src/components/AuthPanel.tsx +312 -0
  127. package/client/src/components/CliAuthPage.tsx +367 -0
  128. package/client/src/components/CreatorPortal.tsx +885 -0
  129. package/client/src/components/ErrorBoundary.tsx +92 -0
  130. package/client/src/components/ManifestoPage.tsx +1126 -0
  131. package/client/src/components/TrackCard.tsx +19 -0
  132. package/client/src/lib/api.ts +215 -0
  133. package/client/src/main.tsx +14 -0
  134. package/client/src/styles/index.css +33 -0
  135. package/client/src/styles/manifesto.css +1828 -0
  136. package/client/tailwind.config.ts +36 -0
  137. package/client/tsconfig.json +25 -0
  138. package/client/vercel.json +8 -0
  139. package/client/vite.config.ts +33 -0
  140. package/package.json +27 -0
  141. package/server/package.json +26 -0
  142. package/server/src/app.ts +132 -0
  143. package/server/src/config/env.ts +135 -0
  144. package/server/src/features/accounts/accountStore.ts +359 -0
  145. package/server/src/features/accounts/contentStore.ts +264 -0
  146. package/server/src/features/accounts/password.ts +26 -0
  147. package/server/src/features/auth/sessionStore.ts +79 -0
  148. package/server/src/index.ts +8 -0
  149. package/server/src/routes/auth.ts +328 -0
  150. package/server/src/routes/content.ts +174 -0
  151. package/server/src/routes/health.ts +14 -0
  152. package/server/src/routes/progress.ts +105 -0
  153. package/server/tsconfig.json +19 -0
  154. package/shared/package.json +24 -0
  155. package/shared/src/index.ts +455 -0
  156. package/shared/tsconfig.json +16 -0
  157. package/tsconfig.base.json +12 -0
  158. package/visionos-manifesto/index.html +392 -0
  159. package/visionos-manifesto/script.js +146 -0
  160. package/visionos-manifesto/styles.css +1082 -0
@@ -0,0 +1,30 @@
1
+ name: Publish CLI to npm
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+ publish:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - name: Checkout repository
13
+ uses: actions/checkout@v4
14
+
15
+ - name: Setup Node.js
16
+ uses: actions/setup-node@v4
17
+ with:
18
+ node-version: '20'
19
+ registry-url: 'https://registry.npmjs.org'
20
+
21
+ - name: Install dependencies
22
+ run: npm ci
23
+
24
+ - name: Build monorepo packages
25
+ run: npm run build
26
+
27
+ - name: Publish CLI package to npm
28
+ run: npm publish -w cli
29
+ env:
30
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/README.md ADDED
@@ -0,0 +1,175 @@
1
+ # VisionOS
2
+
3
+ VisionOS is a CLI-first learning platform for command-line practice across tracks such as Git, Linux, React CLI, and OS commands.
4
+
5
+ The current build includes:
6
+
7
+ - An installable `visionos-cli` package with a `visionos` binary
8
+ - An embedded local runtime that serves the web UI and API automatically
9
+ - Browser-based CLI authentication handoff
10
+ - Local user/session persistence in `~/.visionos/`
11
+ - Commands for `start`, `login`, `lessons`, `open`, `userinfo`, `status`, and `logout`
12
+ - A monorepo dev setup for separate server/client development
13
+
14
+ ## Monorepo Layout
15
+
16
+ ```text
17
+ visionos/
18
+ ├── brain/
19
+ ├── cli/
20
+ ├── client/
21
+ ├── server/
22
+ ├── shared/
23
+ └── README.md
24
+ ```
25
+
26
+ ## Install The CLI
27
+
28
+ The npm package name is `visionos-cli`, but the command you run is `visionos`.
29
+
30
+ ### From npm
31
+
32
+ Once the package is published, install it globally with:
33
+
34
+ ```bash
35
+ npm install -g visionos-cli
36
+ ```
37
+
38
+ Then run:
39
+
40
+ ```bash
41
+ visionos start
42
+ ```
43
+
44
+ ### From this repository
45
+
46
+ This repo is not published automatically. To build the installable tarball locally:
47
+
48
+ ```bash
49
+ npm install
50
+ npm run pack:cli
51
+ npm install -g ./visionos-cli-0.1.1.tgz
52
+ ```
53
+
54
+ After that, the CLI works the same way:
55
+
56
+ ```bash
57
+ visionos start
58
+ ```
59
+
60
+ You do not need `npm run dev:cli -- start` for installed usage.
61
+
62
+ ## CLI Commands
63
+
64
+ > [!TIP]
65
+ > For a comprehensive guide covering options, internal behaviors, offline state configuration, and validation mechanics, refer directly to the [CLI Documentation](file:///Users/adityapathania/Codes/Chitkara/Projects/IP-project/VisionOS/cli/README.md).
66
+
67
+ - `visionos start`
68
+ Starts the local VisionOS runtime if needed, opens browser account login when required, lets the learner choose a beginner lesson, and saves the selected lesson as current progress.
69
+
70
+ - `visionos login`
71
+ Opens the browser account flow so a learner can log in or create a MongoDB-backed account.
72
+
73
+ - `visionos lessons`
74
+ Browses beginner lessons for Git, Linux, React CLI, and OS Commands.
75
+
76
+ - `visionos lessons --track git`
77
+ Shows beginner lessons for a specific track.
78
+
79
+ - `visionos open`
80
+ Opens the local VisionOS web interface without restarting the monorepo dev servers.
81
+
82
+ - `visionos userinfo`
83
+ Shows the locally stored learner profile from `~/.visionos/user.json`.
84
+
85
+ - `visionos userinfo --json`
86
+ Prints the stored learner profile, runtime info, and state file paths as JSON.
87
+
88
+ - `visionos status`
89
+ Shows whether the embedded runtime is running and whether a learner profile is stored.
90
+
91
+ - `visionos logout`
92
+ Removes the locally stored learner profile.
93
+
94
+ ## Installed Runtime Behavior
95
+
96
+ - `visionos start` boots a local embedded runtime on `127.0.0.1` using an available port.
97
+ - The runtime serves both the React frontend and the API from the same origin.
98
+ - The browser auth page writes the authenticated learner profile to `~/.visionos/user.json`.
99
+ - The account bearer token is stored separately in `~/.visionos/account.json`.
100
+ - Runtime metadata is stored in `~/.visionos/runtime.json`.
101
+
102
+ ## Development Workflow
103
+
104
+ If you want to work on the monorepo directly instead of using the installed package:
105
+
106
+ ```bash
107
+ npm install
108
+ npm run dev
109
+ ```
110
+
111
+ That starts:
112
+
113
+ - React on `http://localhost:5173`
114
+ - Express on `http://127.0.0.1:4000`
115
+
116
+ You can still run the CLI in dev mode with:
117
+
118
+ ```bash
119
+ npm run dev:cli -- start
120
+ ```
121
+
122
+ The backend API stays available at `http://127.0.0.1:4000`.
123
+
124
+ ## Workspace Scripts
125
+
126
+ - `npm run build` builds every workspace in dependency order, including the packaged CLI runtime assets
127
+ - `npm run pack:cli` builds the repo and creates `visionos-cli-0.1.1.tgz`
128
+ - `npm run dev` starts the Express API and React frontend together
129
+ - `npm run dev:cli` starts the CLI in development mode
130
+ - `npm run dev:server` starts the Express API with file watching
131
+ - `npm run dev:client` starts the React frontend
132
+
133
+ ## Current Web Surface
134
+
135
+ - `/` serves the VisionOS homepage and runtime dashboard
136
+ - `/login` serves the account login page
137
+ - `/register` serves the account registration page
138
+ - `/?cliAuthSession=...` serves the browser auth confirmation page
139
+ - `/health` returns API health JSON
140
+ - `/auth/me` returns the stored learner profile for the current machine
141
+ - `/auth/register`, `/auth/login`, and `/auth/google` authenticate MongoDB-backed accounts
142
+ - `/progress` reads and saves MongoDB-backed learner progress for the signed-in account
143
+ - `/runtime/info` returns the current app/API origin information
144
+
145
+ ## Account Storage
146
+
147
+ VisionOS account and progress storage uses MongoDB.
148
+
149
+ Server environment:
150
+
151
+ ```bash
152
+ MONGODB_URI=mongodb://127.0.0.1:27017
153
+ MONGODB_DB=visionos
154
+ GOOGLE_CLIENT_ID=
155
+ ```
156
+
157
+ Client environment:
158
+
159
+ ```bash
160
+ VITE_GOOGLE_CLIENT_ID=
161
+ ```
162
+
163
+ Password accounts are stored in MongoDB with salted `scrypt` password hashes. Google login is available in the UI and works once both `GOOGLE_CLIENT_ID` and `VITE_GOOGLE_CLIENT_ID` are configured.
164
+
165
+ ## Current Limitations
166
+
167
+ - The lesson execution engine is not implemented yet
168
+ - Progress persistence endpoints exist, but the lesson runner does not write real lesson progress yet
169
+ - The package is ready to publish, but publishing to npm has not been done from this repository
170
+
171
+ ## Next Milestones
172
+
173
+ - Command execution and validation engine
174
+ - Local progress persistence and backend sync
175
+ - Resume support across CLI and web experiences
package/cli/README.md ADDED
@@ -0,0 +1,165 @@
1
+ # VisionOS Command Line Interface (CLI)
2
+
3
+ The `visionos-cli` package provides the `visionos` binary—a high-fidelity, interactive, and terminal-first educational environment. It guides users through hands-on learning tracks (Git, Linux, OS, React) with physical workspace analysis and real-time command syntax validation.
4
+
5
+ ---
6
+
7
+ ## 🚀 Installation & Setup
8
+
9
+ ### Installing Globally
10
+ To install the `visionos` CLI executable globally from npm:
11
+
12
+ ```bash
13
+ npm install -g visionos-cli
14
+ ```
15
+
16
+ ### Building & Installing Locally
17
+ To build and install the CLI from this monorepo directory:
18
+
19
+ ```bash
20
+ # Navigate to monorepo root and execute build
21
+ npm run build
22
+
23
+ # Package the CLI into a tarball
24
+ npm run pack:cli
25
+
26
+ # Globally install the generated package tarball
27
+ npm install -g ./visionos-cli-*.tgz
28
+ ```
29
+
30
+ Verify your installation by running:
31
+ ```bash
32
+ visionos --version
33
+ ```
34
+
35
+ ---
36
+
37
+ ## 🛠 Command Reference
38
+
39
+ ### `visionos start`
40
+ Starts a guided, interactive terminal-based learning session.
41
+
42
+ * **Description**: Boots the local embedded runtime (if stopped), handles session authorization checks, prompts you to select a learning track, handles resume state checkpoints, configures your practice directory, and launches you into the step-by-step interactive lesson runner.
43
+ * **Interactive Engine Flow**:
44
+ 1. **Authentication Check**: Verifies active session token. Launches browser sign-in if credentials are missing.
45
+ 2. **Track Selector**: Queries all available tracks from MongoDB (or local offline catalog fallback).
46
+ 3. **Checkpoint Detection**: Automatically detects your progress. Offers to **Resume Last Lesson**, **Start from Beginning**, or **Browse Catalog**.
47
+ 4. **Workspace Choice**: Prompts you to practice in the **Default isolated sandbox** or a **Custom directory**.
48
+ 5. **Step Execution Loop**: Prints lesson title, estimated minutes, step instructions, and expected result verification commands. Executes commands, displays real OS system stdout/stderr outputs, and intercepts typos or failed exit codes to render descriptive mistake cards.
49
+ * **Usage**:
50
+ ```bash
51
+ visionos start
52
+ ```
53
+
54
+ ---
55
+
56
+ ### `visionos login`
57
+ Authenticates the terminal with your cloud-backed learner account.
58
+
59
+ * **Description**: Spins up a local temporary embedded bridge server, launches your system browser to coordinate a secure MongoDB or Google authentication token handoff, and saves credentials under `~/.visionos/account.json` and `~/.visionos/user.json`.
60
+ * **Options**:
61
+ * `-t, --track <trackId>`: Directly attach a specific learning track (e.g. `git`, `linux`, `os-commands`) to the browser login session to skip intermediate track prompts.
62
+ * **Usage**:
63
+ ```bash
64
+ visionos login
65
+ visionos login --track os-commands
66
+ ```
67
+
68
+ ---
69
+
70
+ ### `visionos lessons`
71
+ Browse and preview the interactive track curriculum.
72
+
73
+ * **Description**: Lists all structured lessons, estimated completion times, and step counts for each learning path.
74
+ * **Options**:
75
+ * `-t, --track <trackId>`: Filter and display lessons belonging exclusively to the specified track.
76
+ * `-l, --lesson <lessonId>`: Directly preview details (steps, objectives, verification commands, and descriptions) for a specific lesson without starting it.
77
+ * **Usage**:
78
+ ```bash
79
+ # Interactive track search
80
+ visionos lessons
81
+
82
+ # View all lessons in the Git track
83
+ visionos lessons --track git
84
+
85
+ # Inspect a specific rebase lesson
86
+ visionos lessons --lesson git-github-connect
87
+ ```
88
+
89
+ ---
90
+
91
+ ### `visionos open`
92
+ Instantly opens the VisionOS web learning dashboard.
93
+
94
+ * **Description**: Evaluates active local runtime parameters and opens the dashboard inside your default system browser. Automatically injects your local account credentials securely via one-time URL tokens so you bypass manual login screens.
95
+ * **Usage**:
96
+ ```bash
97
+ visionos open
98
+ ```
99
+
100
+ ---
101
+
102
+ ### `visionos userinfo`
103
+ Inspects and displays details about your locally stored learner profile.
104
+
105
+ * **Description**: Reads and formats cached session data, active progress tracks, authentication dates, and configuration folder structures.
106
+ * **Options**:
107
+ * `--json`: Prints the entire structured learner profile, active paths, and runtime metadata as a raw JSON block (perfect for script hooks or advanced telemetry debugging).
108
+ * **Usage**:
109
+ ```bash
110
+ # Formatted terminal display
111
+ visionos userinfo
112
+
113
+ # Print machine-readable JSON
114
+ visionos userinfo --json
115
+ ```
116
+
117
+ ---
118
+
119
+ ### `visionos status`
120
+ Show the embedded VisionOS runtime and connectivity status.
121
+
122
+ * **Description**: Runs a diagnostic inspect check on active local runtime configurations. Reports background process IDs (PIDs), target API server endpoints, web dashboard URLs, and authentication status.
123
+ * **Usage**:
124
+ ```bash
125
+ visionos status
126
+ ```
127
+
128
+ ---
129
+
130
+ ### `visionos logout`
131
+ Removes the locally stored VisionOS learner session.
132
+
133
+ * **Description**: Securely clears all cached profile states, local accounts, and session metadata from the `~/.visionos/` directory.
134
+ * **Usage**:
135
+ ```bash
136
+ visionos logout
137
+ ```
138
+
139
+ ---
140
+
141
+ ## 💾 State & Sandbox Architecture
142
+
143
+ VisionOS operates with a highly robust system structure designed for sandbox isolation and hybrid data replication:
144
+
145
+ ### 1. File Configuration Directory (`~/.visionos/`)
146
+ The CLI stores internal state and configurations in the user's home folder:
147
+ * `~/.visionos/account.json`: Stores secure token parameters for API authorization.
148
+ * `~/.visionos/user.json`: Caches core learner profile details (name, email, current track key).
149
+ * `~/.visionos/runtime.json`: Keeps track of current local embedded server specifications (ports, endpoints, PIDs).
150
+ * `~/.visionos/progress.json`: Stores local backup checkpoints for completed lessons/steps. Automatically synchronizes with the MongoDB remote server once internet connection is established.
151
+
152
+ ### 2. Workspace Sandbox Isolation
153
+ When executing dynamic steps, learners are offered two practice directories:
154
+ * **Default isolated sandbox (`~/.visionos/sandbox/<lesson-id>`)**: A completely secure, isolated repository rebuilt from scratch at every lesson boot. Bounded operations guarantee zero impact on your computer's home directory.
155
+ * **Custom workspace directory**: Allows learners to select a path of their choice on their system.
156
+ > [!IMPORTANT]
157
+ > When working inside a custom workspace, all clean/reset triggers are disabled. The CLI operates in a pure **read-only inspection mode**, ensuring none of your personal files are ever modified or deleted.
158
+
159
+ ---
160
+
161
+ ## 🔍 Validation Engine Modes
162
+ Every learning step defines a validation rule that is dynamically validated by the local parser without compiling TypeScript code:
163
+ * **`syntax` Mode**: The user runs the command. The engine runs it in the sandbox, captures real OS stdout/stderr, and confirms successful exit codes (exit 0). Intercepts errors (e.g. typos, options flags) to display rich troubleshooting mistake alerts.
164
+ * **`file-exists` Mode**: Scans the workspace to physically confirm folder or file creation rules.
165
+ * **`file-contains` Mode**: Inspects the file contents to verify exact characters, branch bindings, or repository commits exist.
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "visionos-cli",
3
+ "version": "0.1.7",
4
+ "type": "module",
5
+ "bin": {
6
+ "visionos": "dist/index.js"
7
+ },
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "engines": {
12
+ "node": ">=18.18.0"
13
+ },
14
+ "scripts": {
15
+ "build": "tsup src/index.ts src/runtime/index.ts --format esm --clean --out-dir dist && node ./scripts/copy-web-assets.mjs",
16
+ "dev": "tsx src/index.ts",
17
+ "lint": "tsc --noEmit -p tsconfig.json"
18
+ },
19
+ "dependencies": {
20
+ "chalk": "^5.3.0",
21
+ "commander": "^12.1.0",
22
+ "cors": "^2.8.5",
23
+ "dotenv": "^16.4.5",
24
+ "express": "^4.21.1",
25
+ "inquirer": "^9.3.7",
26
+ "mongodb": "^6.21.0"
27
+ },
28
+ "devDependencies": {
29
+ "@types/cors": "^2.8.17",
30
+ "@types/express": "^4.17.21",
31
+ "@types/node": "^22.10.1",
32
+ "tsup": "^8.3.0",
33
+ "tsx": "^4.19.1",
34
+ "typescript": "^5.6.3"
35
+ }
36
+ }
@@ -0,0 +1,12 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+
5
+ const currentDir = path.dirname(fileURLToPath(import.meta.url));
6
+ const cliDir = path.resolve(currentDir, "..");
7
+ const sourceDir = path.resolve(cliDir, "../client/dist");
8
+ const targetDir = path.resolve(cliDir, "./dist/web");
9
+
10
+ await fs.rm(targetDir, { force: true, recursive: true });
11
+ await fs.mkdir(path.dirname(targetDir), { recursive: true });
12
+ await fs.cp(sourceDir, targetDir, { recursive: true });
@@ -0,0 +1,68 @@
1
+ import chalk from "chalk";
2
+ import { Command } from "commander";
3
+ import inquirer from "inquirer";
4
+ import {
5
+ LEARNING_TRACKS,
6
+ getLessonById,
7
+ getLessonsForTrack,
8
+ type LearningTrackId
9
+ } from "../../../shared/src/index.js";
10
+ import { printLessonCatalog, printLessonPreview } from "../lib/lessonPrinter.js";
11
+
12
+ export function createLessonsCommand() {
13
+ return new Command("lessons")
14
+ .description("Browse beginner lessons for each VisionOS track.")
15
+ .option("-t, --track <trackId>", "Show lessons for a specific track.")
16
+ .option("-l, --lesson <lessonId>", "Preview a specific lesson.")
17
+ .action(async ({ lesson, track }: { lesson?: string; track?: LearningTrackId }) => {
18
+ if (lesson) {
19
+ const selectedLesson = getLessonById(lesson);
20
+
21
+ if (!selectedLesson) {
22
+ console.error(chalk.red(`Lesson not found: ${lesson}`));
23
+ process.exitCode = 1;
24
+ return;
25
+ }
26
+
27
+ printLessonPreview(selectedLesson);
28
+ return;
29
+ }
30
+
31
+ const trackId = track ?? (await promptForTrack());
32
+
33
+ printLessonCatalog(trackId);
34
+ });
35
+ }
36
+
37
+ export async function promptForLesson(trackId: LearningTrackId) {
38
+ const lessons = getLessonsForTrack(trackId);
39
+ const { lessonId } = await inquirer.prompt<{ lessonId: string }>([
40
+ {
41
+ type: "list",
42
+ name: "lessonId",
43
+ message: "Choose a beginner lesson:",
44
+ choices: lessons.map((lesson) => ({
45
+ name: `${lesson.title} - ${lesson.summary}`,
46
+ value: lesson.id
47
+ }))
48
+ }
49
+ ]);
50
+
51
+ return getLessonById(lessonId);
52
+ }
53
+
54
+ async function promptForTrack() {
55
+ const { trackId } = await inquirer.prompt<{ trackId: LearningTrackId }>([
56
+ {
57
+ type: "list",
58
+ name: "trackId",
59
+ message: "Choose a learning track:",
60
+ choices: LEARNING_TRACKS.map((track) => ({
61
+ name: `${track.label} - ${track.description}`,
62
+ value: track.id
63
+ }))
64
+ }
65
+ ]);
66
+
67
+ return trackId;
68
+ }
@@ -0,0 +1,46 @@
1
+ import chalk from "chalk";
2
+ import { Command } from "commander";
3
+ import inquirer from "inquirer";
4
+ import { LEARNING_TRACKS, type LearningTrackId } from "../../../shared/src/index.js";
5
+ import { VisionOsApiError } from "../lib/auth.js";
6
+ import { runBrowserLogin } from "../lib/loginFlow.js";
7
+
8
+ export function createLoginCommand() {
9
+ return new Command("login")
10
+ .description("Log in to a VisionOS account through the browser.")
11
+ .option("-t, --track <trackId>", "Learning track to attach to this login session.")
12
+ .action(async ({ track }: { track?: LearningTrackId }) => {
13
+ try {
14
+ const trackId = track ?? (await promptForTrack());
15
+
16
+ await runBrowserLogin(trackId);
17
+ } catch (error) {
18
+ if (error instanceof VisionOsApiError) {
19
+ console.error(chalk.red("Unable to complete VisionOS account login."));
20
+ console.error(chalk.gray(error.message));
21
+ } else if (error instanceof Error) {
22
+ console.error(chalk.red(error.message));
23
+ } else {
24
+ console.error(chalk.red("An unexpected error interrupted VisionOS account login."));
25
+ }
26
+
27
+ process.exitCode = 1;
28
+ }
29
+ });
30
+ }
31
+
32
+ async function promptForTrack() {
33
+ const { trackId } = await inquirer.prompt<{ trackId: LearningTrackId }>([
34
+ {
35
+ type: "list",
36
+ name: "trackId",
37
+ message: "Choose a track for this login session:",
38
+ choices: LEARNING_TRACKS.map((track) => ({
39
+ name: `${track.label} - ${track.description}`,
40
+ value: track.id
41
+ }))
42
+ }
43
+ ]);
44
+
45
+ return trackId;
46
+ }
@@ -0,0 +1,12 @@
1
+ import chalk from "chalk";
2
+ import { Command } from "commander";
3
+ import { clearAccountState, clearUserProfile } from "../lib/localState.js";
4
+
5
+ export function createLogoutCommand() {
6
+ return new Command("logout")
7
+ .description("Remove the locally stored VisionOS learner profile.")
8
+ .action(async () => {
9
+ await Promise.all([clearAccountState(), clearUserProfile()]);
10
+ console.log(chalk.yellow("Cleared the local VisionOS account session and learner profile."));
11
+ });
12
+ }
@@ -0,0 +1,29 @@
1
+ import chalk from "chalk";
2
+ import { Command } from "commander";
3
+ import { openBrowser } from "../lib/browser.js";
4
+ import { ensureVisionOsRuntime } from "../lib/runtime.js";
5
+ import { readAccountState } from "../lib/localState.js";
6
+
7
+ export function createOpenCommand() {
8
+ return new Command("open")
9
+ .description("Open the VisionOS web interface.")
10
+ .action(async () => {
11
+ const runtime = await ensureVisionOsRuntime();
12
+ const account = await readAccountState();
13
+
14
+ let launchUrl = runtime.appUrl;
15
+ if (account?.token) {
16
+ const separator = launchUrl.includes("?") ? "&" : "?";
17
+ launchUrl = `${launchUrl}${separator}token=${encodeURIComponent(account.token)}`;
18
+ }
19
+
20
+ const browserOpened = await openBrowser(launchUrl);
21
+
22
+ console.log(chalk.cyan(`VisionOS web interface: ${runtime.appUrl}`));
23
+
24
+ if (!browserOpened) {
25
+ console.log(chalk.yellow("Open the URL above manually if your browser did not launch."));
26
+ }
27
+ });
28
+ }
29
+