@powerhousedao/academy 5.1.0-staging.0 → 5.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 (76) hide show
  1. package/CHANGELOG.md +46 -1148
  2. package/blog/BeyondCommunication-ABlueprintForDevelopment.md +1 -2
  3. package/blog/TheChallengeOfChange.md +0 -1
  4. package/docs/academy/00-EthereumArgentinaHackathon.md +207 -0
  5. package/docs/academy/01-GetStarted/00-ExploreDemoPackage.mdx +27 -24
  6. package/docs/academy/01-GetStarted/01-CreateNewPowerhouseProject.md +10 -155
  7. package/docs/academy/01-GetStarted/02-DefineToDoListDocumentModel.md +35 -122
  8. package/docs/academy/01-GetStarted/03-ImplementOperationReducers.md +155 -178
  9. package/docs/academy/01-GetStarted/04-BuildToDoListEditor.md +218 -0
  10. package/docs/academy/{02-MasteryTrack/01-BuilderEnvironment → 01-GetStarted}/05-VetraStudio.md +22 -62
  11. package/docs/academy/01-GetStarted/06-ReactorMCP.md +58 -0
  12. package/docs/academy/01-GetStarted/_04-BuildToDoListEditor +1 -1
  13. package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/03-BuilderTools.md +2 -2
  14. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/02-SpecifyTheStateSchema.md +44 -75
  15. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/03-SpecifyDocumentOperations.md +22 -28
  16. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/04-UseTheDocumentModelGenerator.md +31 -28
  17. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/05-ImplementDocumentReducers.md +206 -211
  18. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/06-ImplementDocumentModelTests.md +62 -176
  19. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/07-ExampleToDoListRepository.md +0 -21
  20. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/01-BuildingDocumentEditors.md +319 -309
  21. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/06-DocumentTools/00-DocumentToolbar.mdx +0 -4
  22. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/06-DocumentTools/01-OperationHistory.md +0 -4
  23. package/docs/academy/02-MasteryTrack/05-Launch/04-ConfigureEnvironment.md +1 -1
  24. package/docs/academy/03-ExampleUsecases/Chatroom/02-CreateNewPowerhouseProject.md +35 -111
  25. package/docs/academy/03-ExampleUsecases/Chatroom/03-DefineChatroomDocumentModel.md +79 -195
  26. package/docs/academy/03-ExampleUsecases/Chatroom/04-ImplementOperationReducers.md +241 -435
  27. package/docs/academy/03-ExampleUsecases/Chatroom/05-ImplementChatroomEditor.md +27 -388
  28. package/docs/academy/03-ExampleUsecases/Chatroom/06-LaunchALocalReactor.md +7 -95
  29. package/docs/academy/03-ExampleUsecases/Chatroom/_category_.json +1 -1
  30. package/docs/academy/04-APIReferences/00-PowerhouseCLI.md +2 -6
  31. package/docs/academy/04-APIReferences/01-ReactHooks.md +501 -291
  32. package/docs/academy/05-Architecture/00-PowerhouseArchitecture.md +39 -7
  33. package/docs/academy/05-Architecture/02-ReferencingMonorepoPackages +65 -0
  34. package/docs/academy/05-Architecture/04-MovingBeyondCRUD +61 -0
  35. package/docs/academy/06-ComponentLibrary/00-DocumentEngineering.md +24 -72
  36. package/docs/academy/08-Glossary.md +0 -7
  37. package/docusaurus.config.ts +3 -28
  38. package/package.json +1 -1
  39. package/sidebars.ts +13 -49
  40. package/src/css/custom.css +18 -26
  41. package/docs/academy/01-GetStarted/04-WriteDocumentModelTests.md +0 -425
  42. package/docs/academy/01-GetStarted/05-BuildToDoListEditor.md +0 -557
  43. package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/images/Modules.png +0 -0
  44. package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/images/VetraStudioDrive.png +0 -0
  45. package/docs/academy/02-MasteryTrack/05-Launch/05-DockerDeployment.md +0 -384
  46. package/docs/academy/03-ExampleUsecases/TodoList/00-GetTheStarterCode.md +0 -24
  47. package/docs/academy/03-ExampleUsecases/TodoList/01-GenerateTodoListDocumentModel.md +0 -211
  48. package/docs/academy/03-ExampleUsecases/TodoList/02-ImplementTodoListDocumentModelReducerOperationHandlers.md +0 -171
  49. package/docs/academy/03-ExampleUsecases/TodoList/03-AddTestsForTodoListActions.md +0 -462
  50. package/docs/academy/03-ExampleUsecases/TodoList/04-GenerateTodoListDocumentEditor.md +0 -45
  51. package/docs/academy/03-ExampleUsecases/TodoList/05-ImplementTodoListDocumentEditorUIComponents.md +0 -422
  52. package/docs/academy/03-ExampleUsecases/TodoList/06-GenerateTodoDriveExplorer.md +0 -61
  53. package/docs/academy/03-ExampleUsecases/TodoList/07-AddSharedComponentForShowingTodoListStats.md +0 -384
  54. package/docs/academy/03-ExampleUsecases/TodoList/_category_.json +0 -8
  55. package/docs/academy/03-ExampleUsecases/VetraPackageLibrary/VetraPackageLibrary.md +0 -7
  56. package/docs/academy/03-ExampleUsecases/VetraPackageLibrary/_category_.json +0 -9
  57. package/docs/academy/04-APIReferences/06-VetraRemoteDrive.md +0 -160
  58. package/docs/academy/04-APIReferences/renown-sdk/00-Overview.md +0 -316
  59. package/docs/academy/04-APIReferences/renown-sdk/01-Authentication.md +0 -672
  60. package/docs/academy/04-APIReferences/renown-sdk/02-APIReference.md +0 -957
  61. package/docs/academy/04-APIReferences/renown-sdk/_category_.json +0 -8
  62. package/docs/academy/10-TodoListTutorial/02-ImplementTodoListDocumentModelReducerOperationHandlers.md +0 -171
  63. package/docs/academy/10-TodoListTutorial/03-AddTestsForTodoListActions.md +0 -462
  64. package/docs/academy/10-TodoListTutorial/05-ImplementTodoListDocumentEditorUIComponents.md +0 -422
  65. package/docs/academy/10-TodoListTutorial/07-AddSharedComponentForShowingTodoListStats.md +0 -370
  66. package/static/img/Vetra-logo-dark.svg +0 -11
  67. package/static/img/vetra-logo-light.svg +0 -11
  68. /package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/06-DocumentTools/{02-RevisionHistoryTimeline/360/237/232/247" → 02-RevisionHistoryTimeline} +0 -0
  69. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{360/237/232/247 /01-WhatIsADocumentModel" → 01-WhatIsADocumentModel} +0 -0
  70. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{360/237/232/247 /02-DAOandDocumentsModelsQ+A" → 02-DAOandDocumentsModelsQ+A} +0 -0
  71. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{360/237/232/247 /02-domain-modeling" → 02-domain-modeling} +0 -0
  72. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{360/237/232/247 /03-BenefitsOfDocumentModels" → 03-BenefitsOfDocumentModels} +0 -0
  73. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{360/237/232/247 /04-UtilitiesAndTips" → 04-UtilitiesAndTips} +0 -0
  74. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{360/237/232/247 /05-best-practices" → 05-best-practices} +0 -0
  75. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{360/237/232/247 /_category_.json" → _category_.json} +0 -0
  76. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{360/237/232/247 /three-data-layers.png" → three-data-layers.png} +0 -0
@@ -1,384 +0,0 @@
1
- # Step 7 - Add shared component for showing TodoList stats
2
-
3
- So far we've been creating components that live in the same directories as the editors that use them. But sometimes we want to use the same component across multiple editors.
4
-
5
- Let's create a component for showing statistics about our todos. We'd like this component to work with any set of todos or todo lists, so that we can use the same one in our document editor or in our drive editor or a folder.
6
-
7
- ## Creating the `<Stats />` component
8
-
9
- Create a new directory at `editors/components` and create two new files inside it:
10
-
11
- `editors/components/Stats.tsx` with this content:
12
-
13
- ```jsx
14
- import type {
15
- TodoItem,
16
- TodoListDocument,
17
- } from "todo-tutorial/document-models/todo-list";
18
-
19
- type Props = {
20
- todos: TodoItem[] | undefined;
21
- todoListDocuments?: TodoListDocument[] | undefined;
22
- createdAtUtcIso?: string;
23
- lastModifiedAtUtcIso?: string;
24
- };
25
-
26
- /** Generic component for showing statistics about todo lists and the todos they contain */
27
- export function Stats({
28
- todos,
29
- todoListDocuments,
30
- createdAtUtcIso,
31
- lastModifiedAtUtcIso,
32
- }: Props) {
33
- const totalTodos = todos?.length ?? 0;
34
- const totalChecked = todos?.filter((todo) => todo.checked).length ?? 0;
35
- const totalUnchecked = todos?.filter((todo) => !todo.checked).length ?? 0;
36
- const percentageChecked = Math.round(
37
- calculatePercentage(totalTodos, totalChecked),
38
- );
39
- const percentageUnchecked = Math.round(
40
- calculatePercentage(totalTodos, totalUnchecked),
41
- );
42
- const createdAt = createdAtUtcIso ? new Date(createdAtUtcIso) : null;
43
- const hasCreatedAt = createdAt !== null;
44
- const lastModified = lastModifiedAtUtcIso
45
- ? new Date(lastModifiedAtUtcIso)
46
- : null;
47
- const hasLastModified = lastModified !== null;
48
- const createdAtFormattedDate = createdAt
49
- ? createdAt.toLocaleDateString()
50
- : null;
51
- const lastModifiedFormattedDate = lastModified
52
- ? lastModified.toLocaleDateString()
53
- : null;
54
- const createdAtFormattedTime = createdAt
55
- ? createdAt.toLocaleTimeString()
56
- : null;
57
- const lastModifiedFormattedTime = lastModified
58
- ? lastModified.toLocaleTimeString()
59
- : null;
60
- const totalTodoListDocuments = todoListDocuments?.length ?? 0;
61
- const hasTodoLists = todoListDocuments !== undefined;
62
-
63
- return (
64
- <ul className="text-sm text-gray-800 max-w-1/2">
65
- {hasTodoLists && (
66
- <li className="flex justify-between">
67
- <span>Todo Lists:</span> <span>{totalTodoListDocuments}</span>
68
- </li>
69
- )}
70
- <li className="flex justify-between">
71
- <span>Todos:</span> <span>{totalTodos}</span>
72
- </li>
73
- <li className="flex justify-between">
74
- <span>Checked:</span>{" "}
75
- <span>
76
- {totalChecked} ({percentageChecked}%)
77
- </span>
78
- </li>
79
- <li className="flex justify-between">
80
- <span>Unchecked:</span>{" "}
81
- <span>
82
- {totalUnchecked} ({percentageUnchecked}%)
83
- </span>
84
- </li>
85
- {hasCreatedAt && (
86
- <li className="flex justify-between">
87
- <span>Created:</span>{" "}
88
- <span>
89
- {createdAtFormattedDate} {createdAtFormattedTime}
90
- </span>
91
- </li>
92
- )}
93
- {hasLastModified && (
94
- <li className="flex justify-between">
95
- <span>Last modified:</span>{" "}
96
- <span>
97
- {lastModifiedFormattedDate} {lastModifiedFormattedTime}
98
- </span>
99
- </li>
100
- )}
101
- </ul>
102
- );
103
- }
104
-
105
- function calculatePercentage(total: unknown, value: unknown) {
106
- if (typeof total !== "number" || typeof value !== "number") {
107
- return 0;
108
- }
109
- const ratio = value / total;
110
- if (isNaN(ratio)) {
111
- return 0;
112
- }
113
- return ratio * 100;
114
- }
115
- ```
116
-
117
- And `editors/components/index.ts` with this content:
118
-
119
- ```ts
120
- export { Stats } from "./Stats.js";
121
- ```
122
-
123
- The index file lets us use a nice neat import path like `todo-tutorial/editors/components` in all of our editor components.
124
-
125
- Don't be too concerned with the math and time related code you see here — those are just implementation details.
126
-
127
- ## Using the `<Stats />` component in our `TodoListEditor`
128
-
129
- Now let's use the `<Stats />` component in our `<TodoList />` component:
130
-
131
- ```tsx
132
- import { useSelectedTodoListDocument } from "todo-tutorial/document-models/todo-list";
133
- // added-line
134
- import { Stats } from "todo-tutorial/editors/components";
135
- import { EditTodoListName } from "./EditName.js";
136
- import { Todos } from "./Todos.js";
137
- import { AddTodo } from "./AddTodo.js";
138
- import { CloseButton } from "./CloseButton.js";
139
-
140
- /** Displays the selected todo list */
141
- export function TodoList() {
142
- const [selectedTodoList] = useSelectedTodoListDocument();
143
-
144
- if (!selectedTodoList) return null;
145
-
146
- const todos = selectedTodoList.state.global.items;
147
- // added-start
148
- const createdAtUtcIso = selectedTodoList.header.createdAtUtcIso;
149
- const lastModifiedAtUtcIso = selectedTodoList.header.lastModifiedAtUtcIso;
150
- // added-end
151
-
152
- return (
153
- <div>
154
- <section className="mb-4 flex gap-2 items-center">
155
- <div className="grow">
156
- <EditTodoListName />
157
- </div>
158
- <div className="flex-none">
159
- <CloseButton />
160
- </div>
161
- </section>
162
- // added-start
163
- <section className="mb-4">
164
- <Stats
165
- todos={todos}
166
- createdAtUtcIso={createdAtUtcIso}
167
- lastModifiedAtUtcIso={lastModifiedAtUtcIso}
168
- />
169
- </section>
170
- // added-end
171
- <section className="mb-4">
172
- <Todos todos={todos} />
173
- </section>
174
- <section>
175
- <AddTodo />
176
- </section>
177
- </div>
178
- );
179
- }
180
- ```
181
-
182
- With this, you will now see statistics about the todo items in a todo list document.
183
-
184
- And now we can also show off the flexibility of our new `<Stats />` component. Since drives are also just documents themselves, we can derive the same information about a drive too. This means we can use this same component in our drive editor as well.
185
-
186
- ## Using the `<Stats />` component in our `TodoDriveExplorer`
187
-
188
- Let's add this to our `<DriveContents />` component, along with some conditional logic that either shows stats for the selected folder (if one is selected) or the selected drive otherwise.
189
-
190
- ```tsx
191
- // added-start
192
- import {
193
- useSelectedDrive,
194
- useSelectedFolder,
195
- } from "@powerhousedao/reactor-browser";
196
- // added-end
197
- import { CreateDocument } from "./CreateDocument.js";
198
- import { EmptyState } from "./EmptyState.js";
199
- import { Files } from "./Files.js";
200
- import { Folders } from "./Folders.js";
201
- import { NavigationBreadcrumbs } from "./NavigationBreadcrumbs.js";
202
- // added-start
203
- import { Stats } from "todo-tutorial/editors/components";
204
- import {
205
- useTodoListDocumentsInSelectedDrive,
206
- useTodoListDocumentsInSelectedFolder,
207
- type TodoItem,
208
- type TodoListDocument,
209
- } from "todo-tutorial/document-models/todo-list";
210
-
211
- /** Small helper function to get all todo items from all todo lists */
212
- export function getAllTodoItemsFromTodoLists(
213
- todoLists: TodoListDocument[] | undefined,
214
- ): TodoItem[] {
215
- return todoLists?.flatMap((todoList) => todoList.state.global.items) ?? [];
216
- }
217
- // added-end
218
-
219
- /** Shows the documents and folders in the selected drive */
220
- export function DriveContents() {
221
- // added-start
222
- const selectedFolder = useSelectedFolder();
223
- const hasSelectedFolder = selectedFolder !== undefined;
224
- // added-end
225
- return (
226
- <div className="space-y-6 px-6">
227
- <NavigationBreadcrumbs />
228
- // added-line
229
- {hasSelectedFolder ? <FolderStats /> : <DriveStats />}
230
- <Folders />
231
- <Files />
232
- <EmptyState />
233
- <CreateDocument />
234
- </div>
235
- );
236
- }
237
-
238
- // added-start
239
- /** Shows the statistics for the selected drive */
240
- function DriveStats() {
241
- const todoListDocumentsInSelectedDrive =
242
- useTodoListDocumentsInSelectedDrive();
243
- const allTodos = getAllTodoItemsFromTodoLists(
244
- todoListDocumentsInSelectedDrive,
245
- );
246
- const [selectedDrive] = useSelectedDrive();
247
- const driveCreatedAt = selectedDrive.header.createdAtUtcIso;
248
- const driveLastModified = selectedDrive.header.lastModifiedAtUtcIso;
249
-
250
- return (
251
- <Stats
252
- todos={allTodos}
253
- todoListDocuments={todoListDocumentsInSelectedDrive}
254
- createdAtUtcIso={driveCreatedAt}
255
- lastModifiedAtUtcIso={driveLastModified}
256
- />
257
- );
258
- }
259
-
260
- /** Shows the statistics for the selected folder */
261
- function FolderStats() {
262
- const todoListDocumentsInSelectedFolder =
263
- useTodoListDocumentsInSelectedFolder();
264
- const allTodos = getAllTodoItemsFromTodoLists(
265
- todoListDocumentsInSelectedFolder,
266
- );
267
-
268
- return (
269
- <Stats
270
- todos={allTodos}
271
- todoListDocuments={todoListDocumentsInSelectedFolder}
272
- />
273
- );
274
- }
275
- // added-end
276
- ```
277
-
278
- The final result should look like this:
279
-
280
- ```jsx
281
- import {
282
- useSelectedDrive,
283
- useSelectedFolder,
284
- } from "@powerhousedao/reactor-browser";
285
- import { CreateDocument } from "./CreateDocument.js";
286
- import { EmptyState } from "./EmptyState.js";
287
- import { Files } from "./Files.js";
288
- import { Folders } from "./Folders.js";
289
- import { NavigationBreadcrumbs } from "./NavigationBreadcrumbs.js";
290
- import { Stats } from "todo-tutorial/editors/components";
291
- import {
292
- useTodoListDocumentsInSelectedDrive,
293
- useTodoListDocumentsInSelectedFolder,
294
- type TodoItem,
295
- type TodoListDocument,
296
- } from "todo-tutorial/document-models/todo-list";
297
-
298
- /** Small helper function to get all todo items from all todo lists */
299
- export function getAllTodoItemsFromTodoLists(
300
- todoLists: TodoListDocument[] | undefined,
301
- ): TodoItem[] {
302
- return todoLists?.flatMap((todoList) => todoList.state.global.items) ?? [];
303
- }
304
-
305
- /** Shows the documents and folders in the selected drive */
306
- export function DriveContents() {
307
- const selectedFolder = useSelectedFolder();
308
- const hasSelectedFolder = selectedFolder !== undefined;
309
- return (
310
- <div className="space-y-6 px-6">
311
- <NavigationBreadcrumbs />
312
- {hasSelectedFolder ? <FolderStats /> : <DriveStats />}
313
- <Folders />
314
- <Files />
315
- <EmptyState />
316
- <CreateDocument />
317
- </div>
318
- );
319
- }
320
-
321
- /** Shows the statistics for the selected drive */
322
- function DriveStats() {
323
- const todoListDocumentsInSelectedDrive =
324
- useTodoListDocumentsInSelectedDrive();
325
- const allTodos = getAllTodoItemsFromTodoLists(
326
- todoListDocumentsInSelectedDrive,
327
- );
328
- const [selectedDrive] = useSelectedDrive();
329
- const driveCreatedAt = selectedDrive.header.createdAtUtcIso;
330
- const driveLastModified = selectedDrive.header.lastModifiedAtUtcIso;
331
-
332
- return (
333
- <Stats
334
- todos={allTodos}
335
- todoListDocuments={todoListDocumentsInSelectedDrive}
336
- createdAtUtcIso={driveCreatedAt}
337
- lastModifiedAtUtcIso={driveLastModified}
338
- />
339
- );
340
- }
341
-
342
- /** Shows the statistics for the selected folder */
343
- function FolderStats() {
344
- const todoListDocumentsInSelectedFolder =
345
- useTodoListDocumentsInSelectedFolder();
346
- const allTodos = getAllTodoItemsFromTodoLists(
347
- todoListDocumentsInSelectedFolder,
348
- );
349
-
350
- return (
351
- <Stats
352
- todos={allTodos}
353
- todoListDocuments={todoListDocumentsInSelectedFolder}
354
- />
355
- );
356
- }
357
- ```
358
-
359
- With this update, you can now see the statistics for the todo lists and todo items for the selected drive, folder or document depending on which you select.
360
-
361
- ## Check your work
362
-
363
- To make sure all works as expected, we should:
364
-
365
- - check types
366
- run: `pnpm tsc`
367
-
368
- - check linting
369
- run: `pnpm lint`
370
-
371
- - check tests
372
- run: `pnpm test`
373
-
374
- - test in connect
375
- run: `pnpm connect` — you should now be able to see the `<Stats />` component showing the data for your drives, folder and documents.
376
-
377
- - make sure your code matches the code in the completed step branch
378
- run: `git diff step-7-complete-added-shared-component-for-showing-todo-list-stats`
379
-
380
- ## The end
381
-
382
- Congratulations! You now have a working `TodoList` document model, and editor for those documents, and a drive editor for managing those documents. This will make a good starting point for creating your own new implementations.
383
-
384
- We're excited to see what you build!
@@ -1,8 +0,0 @@
1
- {
2
- "label": "Todo List",
3
- "position": 3,
4
- "link": {
5
- "type": "generated-index"
6
- }
7
- }
8
-
@@ -1,7 +0,0 @@
1
- ---
2
- title: Vetra Package Library
3
- ---
4
-
5
- The Vetra package library is your best source to explore packages built by different builder teams on the Powerhouse Vetra platform. Through the packages you'll find the GitHub repository with the source code of each package.
6
-
7
- You can get access to the [package library here.](https://vetra.io/packages)
@@ -1,9 +0,0 @@
1
- {
2
- "label": "Vetra Package Library",
3
- "position": 2,
4
- "link": {
5
- "type": "doc",
6
- "id": "academy/ExampleUsecases/VetraPackageLibrary/VetraPackageLibrary"
7
- }
8
- }
9
-
@@ -1,160 +0,0 @@
1
- # Vetra Remote Drive
2
-
3
- These commands enable collaborative development using Vetra remote drives. Instead of working with local drives only, you can connect your Powerhouse project to a remote drive that syncs across team members.
4
-
5
- ## Commands Overview
6
-
7
- ### `ph init --remote-drive`
8
-
9
- **Purpose:** Create a new Powerhouse project and connect it to a remote Vetra drive.
10
-
11
- **When to use:** You're starting a NEW project that will be shared via a remote drive.
12
-
13
- **How it works:**
14
-
15
- 1. Validates the remote drive URL and checks that no GitHub URL is configured yet
16
- 2. Creates a standard Powerhouse project from the boilerplate
17
- 3. Adds Vetra configuration to `powerhouse.config.json`:
18
- ```json
19
- {
20
- "vetra": {
21
- "driveId": "abc123",
22
- "driveUrl": "https://vetra.example.com/d/abc123"
23
- }
24
- }
25
- ```
26
-
27
- **Usage:**
28
- ```bash
29
- ph init my-project --remote-drive https://vetra.example.com/d/abc123
30
- ```
31
-
32
- **After initialization:**
33
- - Create a GitHub repository
34
- - Commit and push your code
35
- - Run `ph vetra` to configure the GitHub URL in the remote drive
36
-
37
- ---
38
-
39
- ### `ph checkout --remote-drive`
40
-
41
- **Purpose:** Clone an existing Powerhouse project that's already connected to a remote drive.
42
-
43
- **When to use:** You're joining an EXISTING project that someone else initialized.
44
-
45
- **How it works:**
46
-
47
- 1. Queries the remote drive to find the configured GitHub URL
48
- 2. Clones the repository from GitHub
49
- 3. Installs dependencies
50
- 4. The project is already configured to use the remote drive
51
-
52
- **Usage:**
53
- ```bash
54
- ph checkout --remote-drive https://vetra.example.com/d/abc123
55
- ```
56
-
57
- **Requirements:**
58
- - The remote drive must have a GitHub URL configured (done during `ph vetra` after init)
59
-
60
- ---
61
-
62
- ### `ph vetra`
63
-
64
- **Purpose:** Start the Vetra development environment with Switchboard and Connect Studio.
65
-
66
- **When to use:** After initializing or checking out a project, to start development.
67
-
68
- **How it works:**
69
-
70
- 1. Reads the remote drive URL from `powerhouse.config.json` (or `--remote-drive` flag)
71
- 2. Starts Switchboard connected to the remote drive (syncs automatically)
72
- 3. Prompts to configure GitHub URL if not set (first time after init)
73
- 4. Starts Connect Studio pointing to the drive(s)
74
-
75
- **With `--watch` flag:**
76
- - Creates a second "Vetra Preview" drive for testing local changes
77
- - Dynamically loads your local document models and editors
78
- - Main drive stays stable, preview drive for experimentation
79
-
80
- **Usage:**
81
- ```bash
82
- # Basic usage (uses config from powerhouse.config.json)
83
- ph vetra
84
-
85
- # With watch mode for development
86
- ph vetra --watch
87
-
88
- # Override remote drive URL
89
- ph vetra --remote-drive https://vetra.example.com/d/abc123
90
-
91
- # Disable Connect Studio
92
- ph vetra --disable-connect
93
- ```
94
-
95
- **Key options:**
96
- - `--watch` - Enable dynamic loading and create preview drive
97
- - `--remote-drive <url>` - Specify remote drive URL
98
- - `--switchboard-port <port>` - Custom Switchboard port (default: 4001)
99
- - `--connect-port <port>` - Custom Connect Studio port (default: 3000)
100
- - `--disable-connect` - Skip Connect Studio
101
- - `--interactive` - Enable interactive mode for code generation
102
-
103
- ---
104
-
105
- ## Workflows
106
-
107
- ### Starting a New Project (Owner)
108
-
109
- ```bash
110
- # 1. Initialize with remote drive
111
- ph init my-project --remote-drive https://vetra.example.com/d/abc123
112
-
113
- # 2. Create GitHub repo and push
114
- cd my-project
115
- git add .
116
- git commit -m "Initial commit"
117
- git remote add origin https://github.com/user/my-project.git
118
- git push -u origin main
119
-
120
- # 3. Start Vetra and configure GitHub URL
121
- ph vetra
122
- # (Select option to use detected GitHub URL when prompted)
123
-
124
- # 4. Start developing with watch mode
125
- ph vetra --watch
126
- ```
127
-
128
- ### Joining an Existing Project (Collaborator)
129
-
130
- ```bash
131
- # 1. Checkout from remote drive
132
- ph checkout --remote-drive https://vetra.example.com/d/abc123
133
-
134
- # 2. Navigate to project
135
- cd project-name
136
-
137
- # 3. Start Vetra environment
138
- ph vetra
139
-
140
- # You're now synced with the remote drive
141
- ```
142
-
143
- ---
144
-
145
- ## Key Concepts
146
-
147
- **Remote Drive vs Local Drive:**
148
- - Without remote drive: `ph vetra` creates a local drive on your machine only
149
- - With remote drive: `ph vetra` connects to a shared drive that syncs across team members
150
-
151
- **When to use each command:**
152
- - Use `ph init --remote-drive` when starting a NEW project (no GitHub URL configured in drive yet)
153
- - Use `ph checkout --remote-drive` when joining an EXISTING project (GitHub URL already configured)
154
- - Use `ph vetra` to start development after either init or checkout
155
-
156
- **Preview Drive (`--watch` mode):**
157
- - Main "Vetra" drive: syncs with remote, contains stable package configuration
158
- - "Vetra Preview" drive: created locally with `--watch`, for testing local document models
159
- - Without `--watch`: safer, prevents untested code from affecting Connect
160
- - With `--watch`: enables rapid development and testing