@jkwd/inbase 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.
- package/README.md +76 -0
- package/apps/explorer/index.html +12 -0
- package/apps/explorer/package.json +28 -0
- package/apps/explorer/scripts/js-source.mjs +188 -0
- package/apps/explorer/scripts/patch-lib.d.ts +115 -0
- package/apps/explorer/scripts/patch-lib.mjs +472 -0
- package/apps/explorer/scripts/scan-target.mjs +188 -0
- package/apps/explorer/scripts/session-store.d.ts +156 -0
- package/apps/explorer/scripts/session-store.mjs +809 -0
- package/apps/explorer/scripts/target-config.d.ts +8 -0
- package/apps/explorer/scripts/target-config.mjs +42 -0
- package/apps/explorer/src/App.tsx +941 -0
- package/apps/explorer/src/agentIntent.ts +182 -0
- package/apps/explorer/src/codebase.ts +15 -0
- package/apps/explorer/src/index.css +632 -0
- package/apps/explorer/src/layout.ts +508 -0
- package/apps/explorer/src/main.tsx +16 -0
- package/apps/explorer/src/scene/BlockPlacer.tsx +87 -0
- package/apps/explorer/src/scene/Bridge.tsx +290 -0
- package/apps/explorer/src/scene/FileBlock.tsx +256 -0
- package/apps/explorer/src/scene/FolderArea.tsx +96 -0
- package/apps/explorer/src/scene/IslandPlacer.tsx +40 -0
- package/apps/explorer/src/scene/MapSelectBorder.tsx +57 -0
- package/apps/explorer/src/scene/MapView.tsx +247 -0
- package/apps/explorer/src/scene/Player.tsx +245 -0
- package/apps/explorer/src/scene/RelationLines.tsx +223 -0
- package/apps/explorer/src/scene/SelectionController.tsx +89 -0
- package/apps/explorer/src/scene/UserContextTracker.tsx +152 -0
- package/apps/explorer/src/scene/World.tsx +323 -0
- package/apps/explorer/src/theme.ts +111 -0
- package/apps/explorer/src/types.ts +245 -0
- package/apps/explorer/src/ui/CanvasErrorBoundary.tsx +38 -0
- package/apps/explorer/src/ui/HUD.tsx +1090 -0
- package/apps/explorer/src/ui/NameInput.tsx +45 -0
- package/apps/explorer/src/userContext.ts +73 -0
- package/apps/explorer/src/userCreated.ts +354 -0
- package/apps/explorer/src/vite-env.d.ts +1 -0
- package/apps/explorer/tsconfig.json +21 -0
- package/apps/explorer/vite.config.ts +295 -0
- package/bin/inbase.mjs +170 -0
- package/bin/project.mjs +94 -0
- package/bin/session.mjs +241 -0
- package/package.json +63 -0
- package/skill/inbase/SKILL.md +167 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AgentIntent,
|
|
3
|
+
PatchImport,
|
|
4
|
+
PatchImportAddition,
|
|
5
|
+
PatchSymbolAddition,
|
|
6
|
+
UserCreatedBlock,
|
|
7
|
+
UserCreatedIsland,
|
|
8
|
+
WorkflowAction,
|
|
9
|
+
} from './types'
|
|
10
|
+
import { parseUserCreatedBlocks, parseUserCreatedIslands } from './userCreated'
|
|
11
|
+
|
|
12
|
+
function normalizeImports(value: unknown): PatchImport[] {
|
|
13
|
+
if (!Array.isArray(value)) return []
|
|
14
|
+
return value.filter((edge): edge is PatchImport => {
|
|
15
|
+
if (!edge || typeof edge !== 'object') return false
|
|
16
|
+
const from = (edge as PatchImport).from
|
|
17
|
+
const to = (edge as PatchImport).to
|
|
18
|
+
return typeof from === 'string' && typeof to === 'string'
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function normalizeSymbolAdditions(value: unknown): PatchSymbolAddition[] {
|
|
23
|
+
if (!Array.isArray(value)) return []
|
|
24
|
+
return value.filter((item): item is PatchSymbolAddition => {
|
|
25
|
+
if (!item || typeof item !== 'object') return false
|
|
26
|
+
const name = (item as PatchSymbolAddition).name
|
|
27
|
+
const file = (item as PatchSymbolAddition).file
|
|
28
|
+
return typeof name === 'string' && typeof file === 'string'
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function normalizeImportAdditions(value: unknown): PatchImportAddition[] {
|
|
33
|
+
if (!Array.isArray(value)) return []
|
|
34
|
+
return value.filter((item): item is PatchImportAddition => {
|
|
35
|
+
if (!item || typeof item !== 'object') return false
|
|
36
|
+
const name = (item as PatchImportAddition).name
|
|
37
|
+
const from = (item as PatchImportAddition).from
|
|
38
|
+
const file = (item as PatchImportAddition).file
|
|
39
|
+
return (
|
|
40
|
+
typeof name === 'string' &&
|
|
41
|
+
typeof from === 'string' &&
|
|
42
|
+
typeof file === 'string'
|
|
43
|
+
)
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const emptyIntent: AgentIntent = {
|
|
48
|
+
updatedAt: null,
|
|
49
|
+
showMap: false,
|
|
50
|
+
status: 'idle',
|
|
51
|
+
feature: null,
|
|
52
|
+
steps: [],
|
|
53
|
+
step: null,
|
|
54
|
+
files: [],
|
|
55
|
+
creates: [],
|
|
56
|
+
deletes: [],
|
|
57
|
+
createFolders: [],
|
|
58
|
+
createLines: {},
|
|
59
|
+
imports: [],
|
|
60
|
+
addedFunctions: [],
|
|
61
|
+
addedVariables: [],
|
|
62
|
+
addedImports: [],
|
|
63
|
+
reason: null,
|
|
64
|
+
sessionId: null,
|
|
65
|
+
diffId: null,
|
|
66
|
+
parentDiffId: null,
|
|
67
|
+
chainIndex: null,
|
|
68
|
+
chain: [],
|
|
69
|
+
isActiveDiff: false,
|
|
70
|
+
preview: false,
|
|
71
|
+
phase: null,
|
|
72
|
+
working: false,
|
|
73
|
+
creationMode: false,
|
|
74
|
+
canEnterBlueprint: false,
|
|
75
|
+
blueprintSessionId: null,
|
|
76
|
+
userCreatedBlocks: [],
|
|
77
|
+
userCreatedIslands: [],
|
|
78
|
+
blueprintFunctions: [],
|
|
79
|
+
blueprintVariables: [],
|
|
80
|
+
blueprintImports: [],
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function normalize(data: Partial<AgentIntent> | null | undefined): AgentIntent {
|
|
84
|
+
return {
|
|
85
|
+
updatedAt: data?.updatedAt ?? null,
|
|
86
|
+
showMap: Boolean(data?.showMap),
|
|
87
|
+
status: data?.status ?? 'idle',
|
|
88
|
+
feature: data?.feature ?? null,
|
|
89
|
+
steps: Array.isArray(data?.steps) ? data.steps : [],
|
|
90
|
+
step: typeof data?.step === 'number' ? data.step : null,
|
|
91
|
+
files: Array.isArray(data?.files) ? data.files : [],
|
|
92
|
+
creates: Array.isArray(data?.creates) ? data.creates : [],
|
|
93
|
+
deletes: Array.isArray(data?.deletes) ? data.deletes : [],
|
|
94
|
+
createFolders: Array.isArray(data?.createFolders) ? data.createFolders : [],
|
|
95
|
+
createLines:
|
|
96
|
+
data?.createLines && typeof data.createLines === 'object'
|
|
97
|
+
? data.createLines
|
|
98
|
+
: {},
|
|
99
|
+
imports: normalizeImports(data?.imports),
|
|
100
|
+
addedFunctions: normalizeSymbolAdditions(data?.addedFunctions),
|
|
101
|
+
addedVariables: normalizeSymbolAdditions(data?.addedVariables),
|
|
102
|
+
addedImports: normalizeImportAdditions(data?.addedImports),
|
|
103
|
+
reason: data?.reason ?? null,
|
|
104
|
+
sessionId: data?.sessionId ?? null,
|
|
105
|
+
diffId: data?.diffId ?? null,
|
|
106
|
+
parentDiffId: data?.parentDiffId ?? null,
|
|
107
|
+
chainIndex: typeof data?.chainIndex === 'number' ? data.chainIndex : null,
|
|
108
|
+
chain: Array.isArray(data?.chain) ? data.chain : [],
|
|
109
|
+
isActiveDiff: Boolean(data?.isActiveDiff),
|
|
110
|
+
preview: Boolean(data?.preview),
|
|
111
|
+
phase: data?.phase ?? null,
|
|
112
|
+
working: Boolean(data?.working),
|
|
113
|
+
creationMode: Boolean(data?.creationMode),
|
|
114
|
+
canEnterBlueprint: Boolean(data?.canEnterBlueprint),
|
|
115
|
+
blueprintSessionId:
|
|
116
|
+
typeof data?.blueprintSessionId === 'string'
|
|
117
|
+
? data.blueprintSessionId
|
|
118
|
+
: null,
|
|
119
|
+
userCreatedBlocks: parseUserCreatedBlocks(data?.userCreatedBlocks),
|
|
120
|
+
userCreatedIslands: parseUserCreatedIslands(data?.userCreatedIslands),
|
|
121
|
+
blueprintFunctions: normalizeSymbolAdditions(data?.blueprintFunctions),
|
|
122
|
+
blueprintVariables: normalizeSymbolAdditions(data?.blueprintVariables),
|
|
123
|
+
blueprintImports: normalizeImportAdditions(data?.blueprintImports),
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export async function fetchAgentIntent(diffId?: string): Promise<AgentIntent> {
|
|
128
|
+
const query = new URLSearchParams({ t: String(Date.now()) })
|
|
129
|
+
if (diffId) query.set('diffId', diffId)
|
|
130
|
+
const response = await fetch(`/api/agent-intent?${query}`)
|
|
131
|
+
if (!response.ok) return emptyIntent
|
|
132
|
+
return normalize((await response.json()) as AgentIntent)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export async function performAgentAction(
|
|
136
|
+
action: WorkflowAction,
|
|
137
|
+
sessionId: string,
|
|
138
|
+
options: {
|
|
139
|
+
diffId?: string
|
|
140
|
+
instruction?: string
|
|
141
|
+
step?: number
|
|
142
|
+
userCreatedBlocks?: UserCreatedBlock[]
|
|
143
|
+
userCreatedIslands?: UserCreatedIsland[]
|
|
144
|
+
addedFunctions?: PatchSymbolAddition[]
|
|
145
|
+
addedVariables?: PatchSymbolAddition[]
|
|
146
|
+
addedImports?: PatchImportAddition[]
|
|
147
|
+
} = {},
|
|
148
|
+
) {
|
|
149
|
+
const response = await fetch('/api/agent-intent', {
|
|
150
|
+
method: 'POST',
|
|
151
|
+
headers: { 'Content-Type': 'application/json' },
|
|
152
|
+
body: JSON.stringify({ action, sessionId, ...options }),
|
|
153
|
+
})
|
|
154
|
+
if (!response.ok) {
|
|
155
|
+
const detail = await response.text()
|
|
156
|
+
throw new Error(detail || 'Could not record visualizer decision')
|
|
157
|
+
}
|
|
158
|
+
return normalize((await response.json()) as AgentIntent)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function persistSessionBlueprint(
|
|
162
|
+
sessionId: string,
|
|
163
|
+
payload: {
|
|
164
|
+
userCreatedBlocks: UserCreatedBlock[]
|
|
165
|
+
userCreatedIslands: UserCreatedIsland[]
|
|
166
|
+
addedFunctions?: PatchSymbolAddition[]
|
|
167
|
+
addedVariables?: PatchSymbolAddition[]
|
|
168
|
+
addedImports?: PatchImportAddition[]
|
|
169
|
+
},
|
|
170
|
+
) {
|
|
171
|
+
fetch('/api/agent-intent', {
|
|
172
|
+
method: 'POST',
|
|
173
|
+
headers: { 'Content-Type': 'application/json' },
|
|
174
|
+
body: JSON.stringify({
|
|
175
|
+
action: 'blueprint_update',
|
|
176
|
+
sessionId,
|
|
177
|
+
...payload,
|
|
178
|
+
}),
|
|
179
|
+
}).catch(() => {
|
|
180
|
+
// Keep local drafts if the session handshake is no longer open.
|
|
181
|
+
})
|
|
182
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CodebaseGraph } from './types'
|
|
2
|
+
|
|
3
|
+
export async function fetchCodebase(): Promise<CodebaseGraph | null> {
|
|
4
|
+
try {
|
|
5
|
+
const response = await fetch(`/api/codebase?t=${Date.now()}`)
|
|
6
|
+
if (!response.ok) return null
|
|
7
|
+
const data = (await response.json()) as CodebaseGraph
|
|
8
|
+
if (!data || !Array.isArray(data.files) || !Array.isArray(data.folders)) {
|
|
9
|
+
return null
|
|
10
|
+
}
|
|
11
|
+
return data
|
|
12
|
+
} catch {
|
|
13
|
+
return null
|
|
14
|
+
}
|
|
15
|
+
}
|