@jkwd/inbase 0.1.9 → 0.1.11

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/bin/session.mjs CHANGED
@@ -26,81 +26,201 @@ function usage(name, example) {
26
26
  process.exit(1)
27
27
  }
28
28
 
29
- export async function startSession(args) {
30
- const { store, config } = await loadExplorer()
31
- const sessionId = takeFlagValue(args, '--session')
32
- const feature = takeFlagValue(args, '--feature')
33
- if (!sessionId) usage('start-session', '--session <cursor-chat-id> [--feature "name"]')
29
+ function printAck(kind, detail) {
30
+ console.log(`VISUAL_CODER_ACK ${kind}: ${detail}`)
31
+ }
32
+
33
+ function createManifestGate(manifestPath) {
34
+ const dir = path.dirname(manifestPath)
35
+ let wake = () => {}
36
+ let watcher = null
37
+ try {
38
+ watcher = fs.watch(dir, () => wake())
39
+ } catch {
40
+ watcher = null
41
+ }
42
+ return {
43
+ wait(ms) {
44
+ return new Promise((resolve) => {
45
+ const timer = setTimeout(resolve, ms)
46
+ wake = () => {
47
+ clearTimeout(timer)
48
+ resolve()
49
+ }
50
+ })
51
+ },
52
+ close() {
53
+ watcher?.close()
54
+ },
55
+ }
56
+ }
57
+
58
+ function signalAck(store, dataDir, sessionId, kind, detail) {
59
+ printAck(kind, detail)
60
+ try {
61
+ store.recordSessionAck(dataDir, sessionId, kind, detail)
62
+ } catch {
63
+ // Session folder may already be gone.
64
+ }
65
+ }
66
+
67
+ function waitingMessage(sessionId, manifest) {
68
+ if (manifest.phase === 'plan_ready') {
69
+ return `Waiting for the user to invoke step ${manifest.currentStep}...`
70
+ }
71
+ if (manifest.phase === 'review' && manifest.diffs?.at(-1)) {
72
+ return manifest.stepByStep === false
73
+ ? `Waiting for the user to accept the proposal after ${manifest.diffs.at(-1).id}...`
74
+ : `Waiting for the user to accept the proposal on ${manifest.diffs.at(-1).id}...`
75
+ }
76
+ return `Waiting for the visual workflow in session ${sessionId}...`
77
+ }
78
+
79
+ function emitStopped(store, dataDir, sessionId) {
80
+ if (store && dataDir && sessionId) {
81
+ signalAck(store, dataDir, sessionId, 'stopped', 'the workflow was stopped')
82
+ } else {
83
+ printAck('stopped', 'the workflow was stopped')
84
+ }
85
+ console.error(
86
+ 'VISUAL_CODER_STOPPED The workflow was stopped. Do not modify project files.',
87
+ )
88
+ process.exit(2)
89
+ }
34
90
 
35
- const manifest = store.startSession(config.dataDir, { sessionId, feature })
36
- if (manifest.phase === 'blueprint_ask' || manifest.phase === 'blueprint') {
91
+ function emitApprovalHandshake(store, dataDir, sessionId, manifest, initialDiff) {
92
+ const current = initialDiff
93
+ ? manifest?.diffs.find((entry) => entry.id === initialDiff.id)
94
+ : null
95
+ if (!manifest || manifest.phase === 'stopped' || current?.status === 'rejected') {
96
+ emitStopped(store, dataDir, sessionId)
97
+ return
98
+ }
99
+ if (manifest.phase === 'finished') {
100
+ signalAck(store, dataDir, sessionId, 'finished', 'the final step was accepted')
37
101
  console.log(
38
- `VISUAL_CODER_BLUEPRINT_WAIT Session ${sessionId} is visible in the visualizer (${manifest.phase}). Wait with inbase wait-for-blueprint before drafting the plan.`,
102
+ `VISUAL_CODER_FINISHED The final step was applied. Feature is done. Run inbase propose-patch --session ${sessionId} --clear, then tell the user it is finished.`,
39
103
  )
40
- } else {
104
+ process.exit(5)
105
+ }
106
+ if (manifest.phase === 'working') {
107
+ const next = manifest.steps.find((step) => step.index === manifest.currentStep)
108
+ const title = next?.title
109
+ signalAck(
110
+ store,
111
+ dataDir,
112
+ sessionId,
113
+ 'execute',
114
+ title
115
+ ? `step ${manifest.currentStep} — ${title}`
116
+ : `step ${manifest.currentStep}`,
117
+ )
118
+ const continuing = (manifest.diffs?.length ?? 0) > 0
41
119
  console.log(
42
- `VISUAL_CODER_PREPARING Session ${sessionId} is visible in the visualizer (${manifest.phase}). Draft the plan next with inbase report-plan.`,
120
+ continuing
121
+ ? `VISUAL_CODER_EXECUTE Step ${manifest.currentStep} is invoked${title ? `: ${title}` : ''}. Continue immediately: edit live files for this step only, then inbase propose-patch --session ${sessionId} with no patch file. Do not explore, re-plan, or run wait-for-blueprint.`
122
+ : `VISUAL_CODER_EXECUTE Step ${manifest.currentStep} is invoked${title ? `: ${title}` : ''}. Re-read this session's blueprint.json before implementing; the user can place files and islands on any step. Edit the live project files for this step only (Write, StrReplace, Delete). Then record the step with inbase propose-patch --session ${sessionId} — no patch file. Inbase diffs those edits against the invoke snapshot and stores the patch. Do not write a unified diff yourself.`,
43
123
  )
124
+ process.exit(0)
125
+ }
126
+ if (manifest.phase === 'replanning') {
127
+ signalAck(
128
+ store,
129
+ dataDir,
130
+ sessionId,
131
+ 'replan',
132
+ `revise the plan from step ${manifest.currentStep}`,
133
+ )
134
+ const instruction = manifest.pendingInstruction
135
+ ? `\nVISUAL_CODER_INSTRUCTION_START\n${manifest.pendingInstruction}\nVISUAL_CODER_INSTRUCTION_END`
136
+ : ''
137
+ console.log(
138
+ `VISUAL_CODER_REPLAN Keep accepted patch files before step ${manifest.currentStep}. Disk is baseline + accepted patches. Do not edit project files until the next EXECUTE. The session blueprint remains leading; if this instruction would differ from it, ask the user before replacing the plan. Report the revised tail with inbase report-plan, then wait for invocation.${instruction}`,
139
+ )
140
+ process.exit(4)
44
141
  }
45
142
  }
46
143
 
144
+ export async function startSession(args) {
145
+ const { store, config } = await loadExplorer()
146
+ const sessionId = takeFlagValue(args, '--session')
147
+ const name = takeFlagValue(args, '--name') || takeFlagValue(args, '--feature')
148
+ const feature = takeFlagValue(args, '--feature')
149
+ if (!sessionId || !name) {
150
+ usage('start-session', '--session <cursor-chat-id> --name "short name"')
151
+ }
152
+
153
+ const manifest = store.startSession(config.dataDir, { sessionId, name, feature })
154
+ console.log(
155
+ `VISUAL_CODER_BLUEPRINT_WAIT Session ${manifest.name || sessionId} is visible in the visualizer (${manifest.phase}). Wait with inbase wait-for-blueprint before drafting the plan. A running visualizer does not skip this handshake.`,
156
+ )
157
+ }
158
+
159
+ export async function attachSession(args) {
160
+ const { store, config } = await loadExplorer()
161
+ const sessionId = takeFlagValue(args, '--session')
162
+ const manifest = store.attachSession(config.dataDir, sessionId)
163
+ console.log(`VISUAL_CODER_SESSION ${manifest.sessionId}`)
164
+ printAck('attached', manifest.name || manifest.sessionId)
165
+ console.log(
166
+ `VISUAL_CODER_ATTACHED Attached to the focused visualizer session ${manifest.name || manifest.sessionId} (${manifest.phase}). Use --session ${manifest.sessionId} for every later command. Run inbase wait-for-blueprint --session ${manifest.sessionId} to read the optional blueprint and instruction; it does not wait.`,
167
+ )
168
+ }
169
+
47
170
  export async function waitForBlueprint(args) {
48
171
  const { store, config } = await loadExplorer()
49
172
  const sessionId = takeFlagValue(args, '--session')
50
- const timeoutMs = Number(takeFlagValue(args, '--timeout') ?? 600000)
51
- if (!sessionId) usage('wait-for-blueprint', '--session <cursor-chat-id> [--timeout ms]')
173
+ if (!sessionId) usage('wait-for-blueprint', '--session <cursor-chat-id>')
52
174
 
53
- const started = Date.now()
54
- const initial = store.readManifest(config.dataDir, sessionId)
55
175
  if (store.isWorkflowStopped(config.dataDir, sessionId)) {
56
- console.error(
57
- 'VISUAL_CODER_STOPPED The workflow was stopped. Do not modify project files.',
58
- )
59
- process.exit(2)
176
+ emitStopped(store, config.dataDir, sessionId)
60
177
  }
178
+ const initial = store.readManifest(config.dataDir, sessionId)
61
179
  if (!initial) {
62
180
  console.error(`No workflow session found for ${sessionId}`)
63
181
  process.exit(1)
64
182
  }
65
183
 
66
- if (initial.phase === 'blueprint_ask' || initial.phase === 'blueprint') {
67
- console.log(
68
- initial.phase === 'blueprint_ask'
69
- ? 'Waiting for the user to choose Setup blueprint: Yes or No...'
70
- : 'Waiting for the user to send the blueprint...',
71
- )
72
- } else {
73
- console.log(`Blueprint handshake already finished for session ${sessionId}.`)
184
+ store.touchSessionConnection(config.dataDir, sessionId)
185
+ store.maybeStartVisualizerHandshake(config.dataDir, sessionId)
186
+ const manifest = store.readManifest(config.dataDir, sessionId)
187
+ if (!manifest || manifest.phase === 'stopped') {
188
+ emitStopped(store, config.dataDir, sessionId)
74
189
  }
75
190
 
76
- while (Date.now() - started < timeoutMs) {
77
- store.touchSessionConnection(config.dataDir, sessionId)
78
- const manifest = store.readManifest(config.dataDir, sessionId)
79
- if (!manifest || manifest.phase === 'stopped') {
80
- console.error(
81
- 'VISUAL_CODER_STOPPED The workflow was stopped. Do not modify project files.',
82
- )
83
- process.exit(2)
84
- }
85
- if (manifest.phase !== 'blueprint_ask' && manifest.phase !== 'blueprint') {
86
- const blueprint = store.readBlueprint(config.dataDir, sessionId)
87
- const blocks = blueprint.userCreatedBlocks ?? []
88
- const islands = blueprint.userCreatedIslands ?? []
89
- console.log(
90
- blueprint.enabled
91
- ? `VISUAL_CODER_BLUEPRINT_READY The user sent ${blocks.length} file(s) and ${islands.length} island(s) for this chat. The blueprint is leading: create those paths and honor addedFunctions, addedVariables, and addedImports even if they are not on disk. Do not omit, rename, relocate, or replace them. Extra new files not in the blueprint are a deviation. If you would differ from the blueprint, ask the user first; do not silently deviate.`
92
- : 'VISUAL_CODER_BLUEPRINT_READY The user skipped the blueprint. Continue without user-placed files or islands.',
93
- )
94
- console.log('VISUAL_CODER_BLUEPRINT_START')
95
- console.log(JSON.stringify(blueprint, null, 2))
96
- console.log('VISUAL_CODER_BLUEPRINT_END')
97
- process.exit(0)
98
- }
99
- await new Promise((resolve) => setTimeout(resolve, 500))
191
+ const blueprint = store.readBlueprint(config.dataDir, sessionId)
192
+ const blocks = blueprint.userCreatedBlocks ?? []
193
+ const islands = blueprint.userCreatedIslands ?? []
194
+ signalAck(
195
+ store,
196
+ config.dataDir,
197
+ sessionId,
198
+ 'blueprint',
199
+ blueprint.enabled
200
+ ? `${blocks.length} file(s), ${islands.length} island(s)`
201
+ : 'none',
202
+ )
203
+ console.log(
204
+ blueprint.enabled
205
+ ? `VISUAL_CODER_BLUEPRINT_READY The session started with ${blocks.length} file(s) and ${islands.length} island(s). The blueprint is leading: create those paths and honor addedFunctions, addedVariables, and addedImports even if they are not on disk. Do not omit, rename, relocate, or replace them. Extra new files not in the blueprint are a deviation. If you would differ from the blueprint, ask the user first; do not silently deviate. The user can still place files and islands on later steps; re-read this session's blueprint.json before each step.`
206
+ : 'VISUAL_CODER_BLUEPRINT_READY The session started without a blueprint. They can still place files and islands on later steps; re-read this session\'s blueprint.json before each step. Continue without user-placed files until that file is enabled.',
207
+ )
208
+ console.log('VISUAL_CODER_BLUEPRINT_START')
209
+ console.log(JSON.stringify(blueprint, null, 2))
210
+ console.log('VISUAL_CODER_BLUEPRINT_END')
211
+ const instruction =
212
+ typeof manifest.initialInstruction === 'string'
213
+ ? manifest.initialInstruction.trim()
214
+ : ''
215
+ if (instruction) {
216
+ console.log(
217
+ 'Honor the user\'s initial instruction between VISUAL_CODER_INSTRUCTION_START and END together with the blueprint.',
218
+ )
219
+ console.log('VISUAL_CODER_INSTRUCTION_START')
220
+ console.log(instruction)
221
+ console.log('VISUAL_CODER_INSTRUCTION_END')
100
222
  }
101
-
102
- console.error('Timed out waiting for the blueprint handshake. Do not modify files.')
103
- process.exit(3)
223
+ process.exit(0)
104
224
  }
105
225
 
106
226
  export async function reportPlan(args) {
@@ -123,10 +243,11 @@ export async function reportPlan(args) {
123
243
  sessionId,
124
244
  feature,
125
245
  stepTitles: stepsParsed.values,
246
+ targetRoot: config.targetRoot,
126
247
  })
127
248
  console.log(
128
249
  manifest.phase === 'working'
129
- ? `VISUAL_CODER_PLAN_READY Reported ${manifest.steps.length} plan step(s) for session ${sessionId}. Step by step is off, so step ${manifest.currentStep} is already invoked. Implement it, then wait again.`
250
+ ? `VISUAL_CODER_PLAN_READY Reported ${manifest.steps.length} plan step(s) for session ${sessionId}. Step by step is off, so step ${manifest.currentStep} is already invoked. Edit the live files for that step, then inbase propose-patch --session ${sessionId} with no patch file.`
130
251
  : `VISUAL_CODER_PLAN_READY Reported ${manifest.steps.length} plan step(s) for session ${sessionId}. Wait for the user to invoke step ${manifest.currentStep}.`,
131
252
  )
132
253
  }
@@ -141,72 +262,36 @@ export async function waitForApproval(args) {
141
262
  const initial = store.readManifest(config.dataDir, sessionId)
142
263
  const initialDiff = initial?.diffs?.at(-1)
143
264
  if (store.isWorkflowStopped(config.dataDir, sessionId)) {
144
- console.error(
145
- 'VISUAL_CODER_STOPPED The workflow was stopped. Do not modify project files.',
146
- )
147
- process.exit(2)
265
+ emitStopped(store, config.dataDir, sessionId)
148
266
  }
149
267
  if (!initial) {
150
268
  console.error(`No workflow session found for ${sessionId}`)
151
269
  process.exit(1)
152
270
  }
153
271
  store.autoAdvance(config.dataDir, sessionId, config.targetRoot)
154
- const afterAdvance = store.readManifest(config.dataDir, sessionId) ?? initial
155
- console.log(
156
- afterAdvance.phase === 'plan_ready'
157
- ? `Waiting for the user to invoke step ${afterAdvance.currentStep}...`
158
- : afterAdvance.phase === 'review' && afterAdvance.diffs?.at(-1)
159
- ? afterAdvance.stepByStep === false
160
- ? `Waiting for the finish step after ${afterAdvance.diffs.at(-1).id}...`
161
- : `Waiting for the user to run the next step after ${afterAdvance.diffs.at(-1).id}...`
162
- : `Waiting for the visual workflow in session ${sessionId}...`,
163
- )
164
-
165
- while (Date.now() - started < timeoutMs) {
166
- store.touchSessionConnection(config.dataDir, sessionId)
167
- store.autoAdvance(config.dataDir, sessionId, config.targetRoot)
168
- const manifest = store.readManifest(config.dataDir, sessionId)
169
- if (!manifest) {
170
- console.error(
171
- 'VISUAL_CODER_STOPPED The workflow was stopped. Do not modify project files.',
172
- )
173
- process.exit(2)
174
- }
175
- const current = initialDiff
176
- ? manifest.diffs.find((entry) => entry.id === initialDiff.id)
177
- : null
178
272
 
179
- if (manifest.phase === 'finished') {
180
- console.log(
181
- `VISUAL_CODER_FINISHED The final step was applied. Feature is done. Run inbase propose-patch --session ${sessionId} --clear, then tell the user it is finished.`,
182
- )
183
- process.exit(5)
184
- }
185
- if (manifest.phase === 'working') {
186
- const next = manifest.steps.find((step) => step.index === manifest.currentStep)
187
- console.log(
188
- `VISUAL_CODER_EXECUTE Step ${manifest.currentStep} is invoked${next ? `: ${next.title}` : ''}. Implement only this step, publish its incremental diff with inbase propose-patch --session ${sessionId}, then wait again.`,
189
- )
190
- process.exit(0)
191
- }
192
- if (manifest.phase === 'replanning') {
193
- const instruction = manifest.pendingInstruction
194
- ? `\nVISUAL_CODER_INSTRUCTION_START\n${manifest.pendingInstruction}\nVISUAL_CODER_INSTRUCTION_END`
195
- : ''
196
- console.log(
197
- `VISUAL_CODER_REPLAN Keep accepted steps before step ${manifest.currentStep}. Replace the plan from step ${manifest.currentStep} onward using the instruction below. The session blueprint remains leading; if this instruction would differ from it, ask the user before replacing the plan. Report the revised tail with inbase report-plan, then wait for invocation.${instruction}`,
198
- )
199
- process.exit(4)
273
+ const { manifest: manifestPath } = store.sessionPaths(config.dataDir, sessionId)
274
+ const gate = createManifestGate(manifestPath)
275
+ let lastWaiting = null
276
+ try {
277
+ while (Date.now() - started < timeoutMs) {
278
+ store.touchSessionConnection(config.dataDir, sessionId)
279
+ store.autoAdvance(config.dataDir, sessionId, config.targetRoot)
280
+ const manifest = store.readManifest(config.dataDir, sessionId)
281
+ emitApprovalHandshake(store, config.dataDir, sessionId, manifest, initialDiff)
282
+ if (!manifest) continue
283
+ const waiting = waitingMessage(sessionId, manifest)
284
+ if (waiting !== lastWaiting) {
285
+ console.log(waiting)
286
+ lastWaiting = waiting
287
+ }
288
+ await gate.wait(50)
200
289
  }
201
- if (manifest.phase === 'stopped' || current?.status === 'rejected') {
202
- console.error(
203
- 'VISUAL_CODER_STOPPED The workflow was stopped. Do not modify project files.',
204
- )
205
- process.exit(2)
206
- }
207
- await new Promise((resolve) => setTimeout(resolve, 500))
290
+ } finally {
291
+ gate.close()
208
292
  }
209
293
 
294
+ signalAck(store, config.dataDir, sessionId, 'timeout', 'no visualizer signal')
210
295
  console.error('Timed out waiting for visualizer review. Do not modify files.')
211
296
  process.exit(3)
212
297
  }
@@ -229,39 +314,44 @@ export async function proposePatch(args) {
229
314
  process.exit(0)
230
315
  }
231
316
 
232
- if (!sessionId || !patchFile) {
233
- usage('propose-patch', '--session <cursor-chat-id> <file.patch|->')
317
+ if (!sessionId) {
318
+ usage('propose-patch', '--session <cursor-chat-id> [file.patch|-]')
234
319
  }
235
320
 
236
- let patchText = ''
321
+ let patchText
237
322
  if (patchFile && patchFile !== '-') {
238
323
  patchText = fs.readFileSync(path.resolve(cwd, patchFile), 'utf8')
239
324
  } else if (patchFile === '-') {
240
325
  patchText = fs.readFileSync(0, 'utf8')
241
326
  }
242
327
 
243
- if (!patchText.trim()) {
244
- console.error('No unified diff provided. Pass a .patch file or use stdin.')
328
+ if (patchFile && !patchText.trim()) {
329
+ console.error('No unified diff provided. Pass a .patch file, use stdin, or omit the file to record live edits.')
245
330
  process.exit(1)
246
331
  }
247
332
 
248
- const parsed = patchLib.parseUnifiedPatch(patchText)
249
- if (parsed.entries.length === 0) {
250
- console.error('Patch did not contain any file changes.')
333
+ let recorded
334
+ try {
335
+ recorded = store.appendDiff(config.dataDir, config.targetRoot, {
336
+ sessionId,
337
+ ...(patchText !== undefined ? { patchText } : {}),
338
+ })
339
+ } catch (error) {
340
+ console.error(error instanceof Error ? error.message : error)
251
341
  process.exit(1)
252
342
  }
343
+ const { entry, manifest } = recorded
253
344
 
254
- const { entry, manifest } = store.appendDiff(config.dataDir, config.targetRoot, {
255
- sessionId,
256
- patchText,
257
- })
345
+ const parsed = patchLib.parseUnifiedPatch(
346
+ store.readDiff(config.dataDir, sessionId, entry),
347
+ )
258
348
 
259
349
  const last = entry.step >= manifest.steps.length
260
350
  console.log(
261
351
  manifest.phase === 'working'
262
- ? `VISUAL_CODER_STEP_READY Published diff ${entry.id} for session ${sessionId}, step ${entry.step}/${manifest.steps.length}: ${parsed.files.length} changed, ${parsed.creates.length} added. Step by step is off, so the next step is already invoked. Wait again.`
352
+ ? `VISUAL_CODER_STEP_READY Recorded live edits as patch ${entry.id} for session ${sessionId}, step ${entry.step}/${manifest.steps.length}: ${parsed.files.length} changed, ${parsed.creates.length} added. Do not keep editing until the next EXECUTE. Step by step is off, so the next step is already invoked. Wait again.`
263
353
  : last
264
- ? `VISUAL_CODER_STEP_READY Published diff ${entry.id} for session ${sessionId}, step ${entry.step}/${manifest.steps.length}: ${parsed.files.length} changed, ${parsed.creates.length} added. Walk the diffs, then Complete to finish.`
265
- : `VISUAL_CODER_STEP_READY Published diff ${entry.id} for session ${sessionId}, step ${entry.step}/${manifest.steps.length}: ${parsed.files.length} changed, ${parsed.creates.length} added. Wait for Continue or an alternative instruction.`,
354
+ ? `VISUAL_CODER_STEP_READY Recorded live edits as patch ${entry.id} for session ${sessionId}, step ${entry.step}/${manifest.steps.length}: ${parsed.files.length} changed, ${parsed.creates.length} added. Do not keep editing. Walk the diffs, then Accept proposal to finish.`
355
+ : `VISUAL_CODER_STEP_READY Recorded live edits as patch ${entry.id} for session ${sessionId}, step ${entry.step}/${manifest.steps.length}: ${parsed.files.length} changed, ${parsed.creates.length} added. Immediately run wait-for-approval. Do not explore or plan. Accept proposal invokes the next step; when EXECUTE returns, implement that step at once.`,
266
356
  )
267
357
  }
package/package.json CHANGED
@@ -1,7 +1,19 @@
1
1
  {
2
2
  "name": "@jkwd/inbase",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "A first-person 3D map of a codebase, with a visual coding workflow for Cursor.",
5
+ "license": "MIT",
6
+ "author": "Joris Kuijper",
7
+ "keywords": [
8
+ "inbase",
9
+ "codebase",
10
+ "visualization",
11
+ "3d",
12
+ "first-person",
13
+ "cursor",
14
+ "devtools",
15
+ "llm"
16
+ ],
5
17
  "repository": {
6
18
  "type": "git",
7
19
  "url": "https://github.com/jk-wd/inbase"
@@ -10,6 +22,9 @@
10
22
  "bugs": {
11
23
  "url": "https://github.com/jk-wd/inbase/issues"
12
24
  },
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
13
28
  "type": "module",
14
29
  "bin": {
15
30
  "inbase": "bin/inbase.mjs"
@@ -28,6 +43,8 @@
28
43
  "apps/explorer/src/*.css",
29
44
  "apps/explorer/src/scene",
30
45
  "apps/explorer/src/ui",
46
+ "apps/explorer/scripts/branch-changes.d.ts",
47
+ "apps/explorer/scripts/branch-changes.mjs",
31
48
  "apps/explorer/scripts/js-source.mjs",
32
49
  "apps/explorer/scripts/open-editor.d.ts",
33
50
  "apps/explorer/scripts/open-editor.mjs",
@@ -37,7 +54,8 @@
37
54
  "apps/explorer/scripts/session-store.d.ts",
38
55
  "apps/explorer/scripts/session-store.mjs",
39
56
  "apps/explorer/scripts/target-config.d.ts",
40
- "apps/explorer/scripts/target-config.mjs"
57
+ "apps/explorer/scripts/target-config.mjs",
58
+ "apps/explorer/scripts/tree-diff.mjs"
41
59
  ],
42
60
  "workspaces": [
43
61
  "apps/*"
@@ -0,0 +1,17 @@
1
+ ---
2
+ description: Attach this chat to the focused Inbase visualizer session
3
+ ---
4
+
5
+ The user invoked `/inbase`. This is how a chat joins the visualizer session that **Setup LLM session** already created.
6
+
7
+ Do **not** ask for a session id. Do **not** run `inbase start-session`. Do **not** print the "direct chat interaction not allowed" message.
8
+
9
+ 1. Attach to the focused visualizer session:
10
+
11
+ ```bash
12
+ npx inbase attach
13
+ ```
14
+
15
+ 2. Read `VISUAL_CODER_SESSION` from the output. That id is the session to use for every later `inbase` command.
16
+
17
+ 3. Continue the Inbase visual edits skill from `wait-for-blueprint` onward with that `--session` id. `/inbase` already started the session. `wait-for-blueprint` only reads the optional blueprint and instruction; it does not wait.
@@ -0,0 +1,9 @@
1
+ ---
2
+ description: Bypass Inbase and do the request directly in this chat
3
+ ---
4
+
5
+ The user invoked `/skipinbase`. Do **not** start or attach an Inbase visual session. Do **not** print the "direct chat interaction not allowed" message.
6
+
7
+ Fulfill this request directly, without the Inbase plan/patch loop:
8
+
9
+ $ARGUMENTS