@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/LICENSE +21 -0
- package/README.md +23 -7
- package/apps/explorer/package.json +1 -0
- package/apps/explorer/scripts/branch-changes.d.ts +24 -0
- package/apps/explorer/scripts/branch-changes.mjs +237 -0
- package/apps/explorer/scripts/js-source.mjs +12 -15
- package/apps/explorer/scripts/patch-lib.d.ts +6 -0
- package/apps/explorer/scripts/patch-lib.mjs +6 -0
- package/apps/explorer/scripts/scan-target.mjs +46 -13
- package/apps/explorer/scripts/session-store.d.ts +64 -1
- package/apps/explorer/scripts/session-store.mjs +369 -88
- package/apps/explorer/scripts/tree-diff.mjs +121 -0
- package/apps/explorer/src/App.tsx +215 -86
- package/apps/explorer/src/agentIntent.ts +78 -0
- package/apps/explorer/src/branchChanges.ts +54 -0
- package/apps/explorer/src/index.css +152 -10
- package/apps/explorer/src/scene/FileBlock.tsx +55 -5
- package/apps/explorer/src/types.ts +46 -0
- package/apps/explorer/src/ui/HUD.tsx +670 -158
- package/apps/explorer/src/userContext.ts +11 -0
- package/apps/explorer/vite.config.ts +65 -5
- package/bin/inbase.mjs +23 -4
- package/bin/project.mjs +62 -4
- package/bin/session.mjs +215 -125
- package/package.json +20 -2
- package/skill/commands/inbase.md +17 -0
- package/skill/commands/skipinbase.md +9 -0
- package/skill/inbase/SKILL.md +142 -89
package/bin/session.mjs
CHANGED
|
@@ -26,81 +26,201 @@ function usage(name, example) {
|
|
|
26
26
|
process.exit(1)
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
36
|
-
|
|
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
|
-
`
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
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
|
-
|
|
202
|
-
|
|
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
|
|
233
|
-
usage('propose-patch', '--session <cursor-chat-id>
|
|
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
|
|
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
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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
|
|
255
|
-
sessionId,
|
|
256
|
-
|
|
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
|
|
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
|
|
265
|
-
: `VISUAL_CODER_STEP_READY
|
|
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.
|
|
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
|