@fugood/bricks-project 2.25.0-beta.42 → 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.
@@ -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': projectMcpServer,
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'] = projectMcpServer
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
- id: makeId('data', idOpts),
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: {