@fugood/bricks-project 2.25.0-beta.41 → 2.25.0-beta.43
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/compile/config-diff.ts +108 -0
- package/compile/index.ts +23 -1
- package/package.json +6 -2
- package/package.json.bak +6 -2
- package/skills/bricks-ctor/SKILL.md +2 -0
- package/skills/bricks-ctor/references/architecture-patterns.md +6 -0
- package/skills/bricks-ctor/references/source-editing-tools.md +81 -0
- package/skills/bricks-design/SKILL.md +14 -24
- package/skills/bricks-ux/SKILL.md +14 -20
- package/tools/mcp-env.ts +13 -0
- package/tools/mcp-server.ts +8 -0
- package/tools/mcp-tools/_verify.ts +45 -0
- package/tools/mcp-tools/compile.ts +2 -0
- package/tools/mcp-tools/data-calc-editing.ts +1425 -0
- package/tools/mcp-tools/entry-editing.ts +2398 -0
- package/tools/postinstall.ts +80 -3
- package/utils/data.ts +3 -5
package/tools/postinstall.ts
CHANGED
|
@@ -69,8 +69,15 @@ const projectMcpServer = {
|
|
|
69
69
|
args: [`${cwd}/node_modules/@fugood/bricks-ctor/tools/mcp-server.ts`],
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
// Codex cancels MCP tool calls it cannot prompt approval for (e.g. `codex exec`),
|
|
73
|
+
// so the project-local server's tools must be pre-approved in its config entry.
|
|
74
|
+
const codexProjectMcpServer = {
|
|
75
|
+
...projectMcpServer,
|
|
76
|
+
default_tools_approval_mode: 'approve',
|
|
77
|
+
}
|
|
78
|
+
|
|
72
79
|
type CodexMcpConfig = {
|
|
73
|
-
mcp_servers: Record<string, typeof projectMcpServer>
|
|
80
|
+
mcp_servers: Record<string, typeof codexProjectMcpServer | typeof projectMcpServer>
|
|
74
81
|
}
|
|
75
82
|
|
|
76
83
|
// Claude Code and AGENTS.md projects both use the shared project .mcp.json file.
|
|
@@ -196,11 +203,81 @@ if (hasClaudeCode || hasAgentsMd) {
|
|
|
196
203
|
await setupSkills()
|
|
197
204
|
}
|
|
198
205
|
|
|
206
|
+
type ClaudeSettings = {
|
|
207
|
+
autoMode?: {
|
|
208
|
+
environment?: string[]
|
|
209
|
+
allow?: string[]
|
|
210
|
+
soft_deny?: string[]
|
|
211
|
+
hard_deny?: string[]
|
|
212
|
+
}
|
|
213
|
+
[key: string]: unknown
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Trusted infrastructure for auto mode's classifier. `$defaults` keeps the
|
|
217
|
+
// built-in environment (the working repo and its git remotes); the extra
|
|
218
|
+
// entries stop routine syncs to the BRICKS backend from being treated as
|
|
219
|
+
// external exfiltration. See https://code.claude.com/docs/en/auto-mode-config
|
|
220
|
+
const autoModeEnvironment = [
|
|
221
|
+
'$defaults',
|
|
222
|
+
'Organization: BRICKS (bricks.tools). Primary use: building BRICKS apps/modules with the bricks CLI and the local bricks-ctor MCP server.',
|
|
223
|
+
'Trusted internal domains: all *.bricks.tools services — api.bricks.tools (project GraphQL API), bank.bricks.tools (config & asset Bank API), cdn.bricks.tools (asset CDN), plus the control/display/activity services. This project syncs its config and assets to these endpoints.',
|
|
224
|
+
]
|
|
225
|
+
|
|
226
|
+
// `.claude/settings.local.json` is per-developer local config; keep it untracked.
|
|
227
|
+
const ensureSettingsLocalGitignored = async () => {
|
|
228
|
+
const gitignorePath = path.join(cwd, '.gitignore')
|
|
229
|
+
const entry = '.claude/settings.local.json'
|
|
230
|
+
const coveredBy = new Set([entry, '.claude', '.claude/', '.claude/*', '*.local.json'])
|
|
231
|
+
|
|
232
|
+
let content = ''
|
|
233
|
+
if (await exists(gitignorePath)) {
|
|
234
|
+
content = await readFile(gitignorePath, 'utf-8')
|
|
235
|
+
if (content.split('\n').some((line) => coveredBy.has(line.trim()))) return
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const separator = content.length === 0 ? '' : content.endsWith('\n') ? '\n' : '\n\n'
|
|
239
|
+
await writeFile(gitignorePath, `${content}${separator}# Claude Code local settings\n${entry}\n`)
|
|
240
|
+
console.log(`Added ${entry} to .gitignore`)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Pre-configure auto mode once, on initial setup. We only seed the classifier's
|
|
244
|
+
// trusted infrastructure — not `permissions.defaultMode: 'auto'`, which Claude
|
|
245
|
+
// Code ignores from project/local settings (a repo can't grant itself auto mode;
|
|
246
|
+
// it only takes effect from ~/.claude/settings.json). An existing autoMode block
|
|
247
|
+
// is left untouched so reinstalls never clobber a developer's customizations.
|
|
248
|
+
const setupClaudeAutoMode = async () => {
|
|
249
|
+
const settingsPath = path.join(cwd, '.claude', 'settings.local.json')
|
|
250
|
+
|
|
251
|
+
let settings: ClaudeSettings = {}
|
|
252
|
+
if (await exists(settingsPath)) {
|
|
253
|
+
try {
|
|
254
|
+
settings = JSON.parse(await readFile(settingsPath, 'utf-8'))
|
|
255
|
+
} catch {
|
|
256
|
+
console.warn(`Skipping auto mode setup; ${settingsPath} is not valid JSON`)
|
|
257
|
+
return
|
|
258
|
+
}
|
|
259
|
+
if (settings.autoMode) return
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
settings.autoMode = { environment: autoModeEnvironment }
|
|
263
|
+
|
|
264
|
+
await mkdir(path.dirname(settingsPath), { recursive: true })
|
|
265
|
+
await writeFile(settingsPath, `${JSON.stringify(settings, null, 2)}\n`)
|
|
266
|
+
console.log(`Set up auto mode in ${settingsPath}`)
|
|
267
|
+
|
|
268
|
+
await ensureSettingsLocalGitignored()
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (hasClaudeCode) {
|
|
272
|
+
// Pre-configure auto mode's trusted infrastructure for Claude Code projects.
|
|
273
|
+
await setupClaudeAutoMode()
|
|
274
|
+
}
|
|
275
|
+
|
|
199
276
|
if (hasAgentsMd) {
|
|
200
277
|
// Codex stores its project-local MCP config in .codex/config.toml.
|
|
201
278
|
const defaultCodexMcpConfig = {
|
|
202
279
|
mcp_servers: {
|
|
203
|
-
'bricks-ctor':
|
|
280
|
+
'bricks-ctor': codexProjectMcpServer,
|
|
204
281
|
},
|
|
205
282
|
}
|
|
206
283
|
|
|
@@ -212,7 +289,7 @@ if (hasAgentsMd) {
|
|
|
212
289
|
const parsed = TOML.parse(configStr) as Partial<CodexMcpConfig>
|
|
213
290
|
if (!parsed?.mcp_servers) throw new Error('mcp_servers is not defined')
|
|
214
291
|
mcpConfig = { mcp_servers: parsed.mcp_servers }
|
|
215
|
-
mcpConfig.mcp_servers['bricks-ctor'] =
|
|
292
|
+
mcpConfig.mcp_servers['bricks-ctor'] = codexProjectMcpServer
|
|
216
293
|
delete mcpConfig.mcp_servers['bricks-project']
|
|
217
294
|
} catch {
|
|
218
295
|
mcpConfig = defaultCodexMcpConfig
|
package/utils/data.ts
CHANGED
|
@@ -7,14 +7,12 @@ export const linkData: (dataGetter: () => Data) => DataLink = (dataGetter) => ({
|
|
|
7
7
|
data: dataGetter,
|
|
8
8
|
})
|
|
9
9
|
|
|
10
|
-
const idOpts = {
|
|
11
|
-
snapshotMode: process.env.BRICKS_SNAPSHOT_MODE === '1',
|
|
12
|
-
}
|
|
13
|
-
|
|
14
10
|
export const createCanvasIdRef: (canvasGetter: () => Canvas) => Data<string> = (canvasGetter) => {
|
|
15
11
|
const data: Data<string> = {
|
|
16
12
|
__typename: 'Data',
|
|
17
|
-
|
|
13
|
+
// Stable by default (utils/id.ts) so recompiling unchanged source yields an
|
|
14
|
+
// identical config; the legacy snapshotMode opt-out made this id churn per compile.
|
|
15
|
+
id: makeId('data'),
|
|
18
16
|
type: 'string',
|
|
19
17
|
routing: 'read-only',
|
|
20
18
|
kind: {
|