@jkwd/inbase 0.1.21 → 0.1.22

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 (58) hide show
  1. package/README.md +13 -7
  2. package/apps/explorer/package.json +1 -0
  3. package/apps/explorer/scripts/explain-store.d.ts +135 -0
  4. package/apps/explorer/scripts/explain-store.mjs +666 -0
  5. package/apps/explorer/scripts/patch-lib.mjs +4 -0
  6. package/apps/explorer/scripts/scan-target.mjs +22 -5
  7. package/apps/explorer/scripts/session-store.d.ts +86 -11
  8. package/apps/explorer/scripts/session-store.mjs +371 -58
  9. package/apps/explorer/scripts/target-config.d.ts +38 -3
  10. package/apps/explorer/scripts/target-config.mjs +147 -3
  11. package/apps/explorer/src/App.tsx +1073 -158
  12. package/apps/explorer/src/agentIntent.ts +61 -7
  13. package/apps/explorer/src/codebase.ts +1 -1
  14. package/apps/explorer/src/devTargets.ts +66 -0
  15. package/apps/explorer/src/explain.ts +312 -0
  16. package/apps/explorer/src/index.css +874 -222
  17. package/apps/explorer/src/layout.ts +55 -0
  18. package/apps/explorer/src/scene/DistantFileBlocks.tsx +4 -2
  19. package/apps/explorer/src/scene/FileBlock.tsx +95 -72
  20. package/apps/explorer/src/scene/FolderArea.tsx +55 -32
  21. package/apps/explorer/src/scene/MapView.tsx +506 -33
  22. package/apps/explorer/src/scene/RelationLines.tsx +7 -0
  23. package/apps/explorer/src/scene/World.tsx +146 -32
  24. package/apps/explorer/src/speech.ts +228 -0
  25. package/apps/explorer/src/theme.ts +29 -0
  26. package/apps/explorer/src/types.ts +98 -8
  27. package/apps/explorer/src/ui/CanvasErrorBoundary.tsx +1 -1
  28. package/apps/explorer/src/ui/ExplainAskCard.tsx +142 -0
  29. package/apps/explorer/src/ui/ExplainHud.tsx +524 -0
  30. package/apps/explorer/src/ui/ExplainInfoPanel.tsx +135 -0
  31. package/apps/explorer/src/ui/ExplainPointer.tsx +73 -0
  32. package/apps/explorer/src/ui/EyeIcon.tsx +38 -1
  33. package/apps/explorer/src/ui/HUD.tsx +1067 -795
  34. package/apps/explorer/src/ui/NameInput.tsx +114 -5
  35. package/apps/explorer/src/userContext.ts +0 -11
  36. package/apps/explorer/src/userCreated.ts +54 -1
  37. package/apps/explorer/vite.config.ts +173 -26
  38. package/bin/inbase.mjs +11 -2
  39. package/bin/project.mjs +1 -1
  40. package/bin/session.mjs +287 -38
  41. package/package.json +4 -1
  42. package/skill/commands/amber.md +23 -0
  43. package/skill/commands/blue.md +13 -0
  44. package/skill/commands/coral.md +23 -0
  45. package/skill/commands/explain.md +77 -0
  46. package/skill/commands/green.md +23 -0
  47. package/skill/commands/inbase.md +7 -5
  48. package/skill/commands/lime.md +23 -0
  49. package/skill/commands/orange.md +23 -0
  50. package/skill/commands/purple.md +23 -0
  51. package/skill/commands/red.md +23 -0
  52. package/skill/commands/skipinbase.md +1 -1
  53. package/skill/commands/violet.md +23 -0
  54. package/skill/commands/yellow.md +23 -0
  55. package/skill/inbase/SKILL.md +124 -76
  56. package/apps/explorer/src/scene/BlockPlacer.tsx +0 -78
  57. package/apps/explorer/src/scene/IslandPlacer.tsx +0 -31
  58. package/apps/explorer/src/scene/SelectionThumbnail.tsx +0 -1069
package/README.md CHANGED
@@ -10,7 +10,7 @@ A first-person 3D map of a codebase. Files become blocks, folders become walkabl
10
10
  <p align="center">
11
11
  <img src="docs/inbase-1.png" alt="First-person walk view of the codebase map" width="47%" />
12
12
  &nbsp;&nbsp;&nbsp;
13
- <img src="docs/inbase-2.png" alt="Map view with 3D overlay" width="47%" />
13
+ <img src="docs/inbase-2.png" alt="Map view of the codebase" width="47%" />
14
14
  </p>
15
15
 
16
16
  Install the package in a project, run `inbase init`, then `inbase run`. Cursor’s LLM then plans and patches through the visual map instead of editing files directly.
@@ -49,13 +49,13 @@ inbase run --target /path/to/your/project
49
49
 
50
50
  Inbase does not call a model itself. The visual coding loop currently supports **Cursor**. The installed skill makes the agent work through the map: it reports a plan, waits on the **HUD** (heads-up display — the overlay panel on the 3D map), edits live files for each invoked step, and records that step as a patch. Those stored patches are the session record and are applied on every step update.
51
51
 
52
- Sessions start in the map: click **Setup LLM session**, type an **initial instruction**, optionally drop **context files** for the chat to read, optionally place a **blueprint** (`Space` for files, `B` for folders), then open a Cursor chat and run **`/inbase`**. That command connects the chat and starts the work. The layout is the source of truth for the chat. Dropped context files stay with that session until it ends. The blueprint is shared across sessions and stays on the map even after those files and folders exist; use **Hide/Show blueprint**, **Clear blueprint**, or **Cleanup blueprint** (drops planned items that already exist). When a session finishes it is discarded; the shared blueprint remains. Restarting the visualizer also starts with no LLM session; leftover session files are not restored.
52
+ `npx inbase run` opens 5 empty chat slots on the map. Open a regular Cursor chat to connect — it takes the next unconnected slot. You can type an **initial instruction**, drop **context files**, and place a **blueprint** (right-click the map to create files and folders) on a waiting slot before or after that chat connects. The layout is the source of truth for the chat. Dropped context files stay with that session until it ends. The **global** (blue) blueprint is shared across sessions; each session color also has a **local** blueprint that only that chat sees. Both stay on the map even after those files and folders exist. Use the color chips to choose which blueprint you are editing, then **Hide**, **Clear**, or **Cleanup** (drops planned items that already exist). When a session finishes it is discarded and a new empty slot is opened; the global blueprint remains. Restarting the visualizer discards leftover sessions and opens 5 new empty slots.
53
53
 
54
- A normal chat request does not open a session. Use `/inbase` after Setup LLM session, or `/skipinbase [request]` to work outside the map. `/inbase` starts the session immediately; `wait-for-blueprint` only reads the optional blueprint, instruction, and attached files.
54
+ A normal chat request connects to the next empty slot. Use `/coral add a login page` (or `/red`, `/amber`, `/lime`, `/orange`, `/violet`) to connect to that color's slot. `/blue` is the global blueprint, not a chat. Use `/explain How does login work?` while the map is open to jump into **explain mode**, or click the **?** next to a file or folder name to have the LLM explain that path and where it fits. The HUD hides, an X exits, and the LLM walks the question step by step. Each step can dim the rest of the map to 50% opacity, click a block to show import relations, and zoom into a folder. **Ask question** on the current step drills into sub-steps (`7.1`, `7.2`) until you return to the next original step. A step can also open the file **info panel**, highlight functions and vars, and draw an arrow that points at a symbol. Use `/skipinbase [request]` to work outside the map. If Inbase is not running, start it with `npx inbase run`. Only 5 chats can be connected at once. `wait-for-blueprint` only reads the optional blueprint, instruction, and attached files.
55
55
 
56
- If several sessions are open, `/inbase` attaches the oldest session that is still waiting. Sessions that already have an LLM are skipped, and the map window does not need to be focused.
56
+ If several slots are waiting, the next Cursor chat attaches the oldest empty session. Sessions that already have an LLM are skipped, and the map window does not need to be focused.
57
57
 
58
- Turn on **Make LLM look where I look** if the agent should prefer the island you are standing on and the blocks you are facing. With **Step by step** on, click **Create proposal** to start a step, then **Accept proposal** when the patch is ready. With it off, the LLM implements the full plan; you can still walk Previous/Next over the diffs, then **Accept proposal**. Send an alternative instruction from the HUD to update the current proposal, or **Stop** to end the session.
58
+ With **Step by step** on, click **Create proposal** to start a step, then **Accept proposal** when the patch is ready. **Explain proposal** sits next to both and has the LLM walk the current plan step or pending patch on the map. With Step by step off, the LLM implements the full plan; you can still walk Previous/Next over the diffs, then **Accept proposal**. Send an alternative instruction from the HUD to update the current proposal, or **Stop** to end the session.
59
59
 
60
60
  When no LLM is currently making changes, turn on **Show branch changes** (or press **G**) to highlight the current git branch against its base — committed, unstaged, and untracked files — instead of LLM patch files. The control is disabled while an LLM session is writing or reviewing a patch.
61
61
 
@@ -72,8 +72,12 @@ session record and are applied on every step update.
72
72
  | `inbase init` | Install the Cursor skill in this repo |
73
73
  | `inbase run` | Scan this repo and start the local map |
74
74
  | `inbase run --port 5174` | Start on another port |
75
+ | `inbase explain start --question "..."` | Open map-only explain mode |
76
+ | `inbase explain report --step "..."` | Publish explanation steps and map focus |
77
+ | `inbase explain wait` | Wait for a question on a step, or until explain mode exits |
78
+ | `inbase explain stop` | Exit explain mode |
75
79
 
76
- Session commands (`attach`, `wait-for-blueprint`, `report-plan`, `wait-for-approval`, `propose-patch`) are used by the Cursor skill. You do not need to run them yourself.
80
+ Session commands (`attach`, `wait-for-blueprint`, `report-plan`, `wait-for-approval`, `propose-patch`, `explain`) are used by the Cursor skill. You do not need to run them yourself.
77
81
 
78
82
  ## Editor support
79
83
 
@@ -100,7 +104,9 @@ npm install
100
104
  npm run dev
101
105
  ```
102
106
 
103
- That still maps `apps/example-target` by default. To map a different project without the CLI:
107
+ That still maps `apps/example-target` by default. In the map, **Look at** switches to the complete repository (and later example apps). That control is only in `npm run dev`, not `inbase run`.
108
+
109
+ To map a different project without the CLI:
104
110
 
105
111
  ```bash
106
112
  VISUAL_CODER_TARGET=/path/to/your/project npm run dev
@@ -14,6 +14,7 @@
14
14
  "dependencies": {
15
15
  "@react-three/drei": "^9.117.3",
16
16
  "@react-three/fiber": "^8.17.10",
17
+ "kokoro-js": "^1.2.1",
17
18
  "react": "^18.3.1",
18
19
  "react-dom": "^18.3.1",
19
20
  "three": "^0.170.0"
@@ -0,0 +1,135 @@
1
+ export const EXPLAIN_FILE: string
2
+
3
+ export type ExplainRelation = {
4
+ from: string
5
+ to: string
6
+ }
7
+
8
+ export type ExplainSymbolKind =
9
+ | 'function'
10
+ | 'variable'
11
+ | 'class'
12
+ | 'file'
13
+ | 'symbol'
14
+
15
+ export type ExplainSymbolRef = {
16
+ kind: ExplainSymbolKind
17
+ name: string
18
+ }
19
+
20
+ export type ExplainPendingQuestion = {
21
+ parent: string
22
+ question: string
23
+ from: string
24
+ fromTitle: string
25
+ }
26
+
27
+ export type ExplainTargetKind =
28
+ | 'file'
29
+ | 'folder'
30
+ | 'function'
31
+ | 'variable'
32
+ | 'class'
33
+
34
+ export type ExplainPendingStart = {
35
+ kind: ExplainTargetKind
36
+ path: string
37
+ name?: string
38
+ question: string
39
+ }
40
+
41
+ export type ExplainStep = {
42
+ index: string
43
+ title: string
44
+ body: string
45
+ asked: string
46
+ files: string[]
47
+ folders: string[]
48
+ select: string | null
49
+ zoom: string | null
50
+ relations: ExplainRelation[]
51
+ importedBy: boolean
52
+ info: boolean
53
+ highlights: ExplainSymbolRef[]
54
+ point: ExplainSymbolRef | null
55
+ }
56
+
57
+ export type ExplainPresentation = 'walk' | 'card'
58
+
59
+ export type ExplainSession = {
60
+ active: boolean
61
+ question: string
62
+ steps: ExplainStep[]
63
+ currentStep: string
64
+ pendingQuestion: ExplainPendingQuestion | null
65
+ pendingStart: ExplainPendingStart | null
66
+ answering: boolean
67
+ presentation: ExplainPresentation
68
+ updatedAt: string | null
69
+ }
70
+
71
+ export function parseExplainSymbolRef(value: string): ExplainSymbolRef | null
72
+ export function emptyExplain(): ExplainSession
73
+ export function normalizeExplainPresentation(value: unknown): ExplainPresentation
74
+ export function isExplainStepId(value: unknown): value is string
75
+ export function explainStepId(value: unknown, fallback?: string): string
76
+ export function isExplainDescendant(id: unknown, parent: unknown): boolean
77
+ export function topLevelExplainStepId(id: unknown): string
78
+ export function isExplainSubStep(id: unknown): boolean
79
+ export function stripExplainSubSteps(steps: ExplainStep[]): ExplainStep[]
80
+ export function normalizeExplain(value: unknown): ExplainSession
81
+ export function readExplain(dataDir: string): ExplainSession
82
+ export function parseExplainTargetKind(value: unknown): ExplainTargetKind | null
83
+ export function explainTargetLabel(input: {
84
+ kind?: string
85
+ path?: string
86
+ name?: string
87
+ }): string
88
+ export function explainTargetQuestion(
89
+ kind: ExplainTargetKind,
90
+ path: string,
91
+ name?: string,
92
+ ): string
93
+ export function startExplain(dataDir: string, question: string): ExplainSession
94
+ export function requestExplainTarget(
95
+ dataDir: string,
96
+ input: {
97
+ kind: ExplainTargetKind
98
+ path: string
99
+ name?: string
100
+ question?: string
101
+ },
102
+ ): ExplainSession
103
+ export function consumeExplainStart(dataDir: string): ExplainPendingStart | null
104
+ export function reportExplain(
105
+ dataDir: string,
106
+ input: { question?: string; parent?: string; steps?: unknown[] },
107
+ ): ExplainSession
108
+ export function setExplainStep(
109
+ dataDir: string,
110
+ step: string | number,
111
+ ): ExplainSession
112
+ export function askExplainQuestion(
113
+ dataDir: string,
114
+ step: string | number,
115
+ question: string,
116
+ ): ExplainSession
117
+ export function consumeExplainQuestion(
118
+ dataDir: string,
119
+ ): ExplainPendingQuestion | null
120
+ export function stopExplain(dataDir: string): ExplainSession
121
+ export function parseExplainArgs(args: string[]): {
122
+ question: string
123
+ parent: string
124
+ steps: ExplainStep[]
125
+ }
126
+ export function parseExplainCli(args: string[]):
127
+ | { action: 'stop' }
128
+ | { action: 'wait' }
129
+ | { action: 'start'; question: string }
130
+ | {
131
+ action: 'report'
132
+ question: string
133
+ parent: string
134
+ steps: ExplainStep[]
135
+ }