basalt-ui 1.9.0 → 1.10.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/AGENTS.md +1 -0
- package/CHANGELOG.md +8 -0
- package/README.md +64 -34
- package/agent/rules/basalt-agent.md +49 -6
- package/configs/oxlint-plugin.js +279 -0
- package/configs/oxlint-plugin.test.ts +216 -1
- package/configs/oxlint.json +5 -2
- package/dist/agent/use-agent-thread-runs.d.ts.map +1 -1
- package/dist/agent/use-agent-thread-runs.js +1 -0
- package/dist/agent-chat/index.d.ts +4 -3
- package/dist/agent-chat/index.d.ts.map +1 -1
- package/dist/cli/index.d.ts +33 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +131 -0
- package/dist/surfaces.d.ts +10 -0
- package/dist/surfaces.d.ts.map +1 -1
- package/dist/surfaces.js +21 -0
- package/llms.txt +9 -2
- package/package.json +6 -1
- package/src/agent/ai-sdk-transport.test.ts +269 -0
- package/src/agent/parts.test.ts +261 -0
- package/src/agent/thread.test.ts +147 -0
- package/src/agent/use-agent-stream.test.tsx +231 -0
- package/src/agent/use-agent-thread-runs.resume.test.tsx +261 -0
- package/src/agent/use-agent-thread-runs.test.tsx +398 -0
- package/src/agent/use-agent-thread-runs.ts +7 -1
- package/src/agent/use-agent-thread-runs.wedge.test.tsx +299 -0
- package/src/agent-chat/index.ts +4 -3
- package/src/charts/primitives/ChartFrame.test.tsx +8 -5
- package/src/cli/index.ts +285 -0
- package/src/dashboard/stat-card.test.tsx +5 -3
- package/src/provider/index.test.tsx +6 -5
- package/src/surfaces.ts +22 -0
- package/src/theme/use-basalt-spacing.test.tsx +7 -4
- package/src/tokens/build-fonts-css.test.ts +3 -2
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* binary and returns the parsed set of `basalt/<rule>` diagnostics it printed.
|
|
9
9
|
*/
|
|
10
10
|
import { afterEach, beforeEach, describe, expect, it } from 'bun:test'
|
|
11
|
-
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
|
|
11
|
+
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
|
12
12
|
import { tmpdir } from 'node:os'
|
|
13
13
|
import { dirname, resolve } from 'node:path'
|
|
14
14
|
|
|
@@ -31,6 +31,9 @@ beforeEach(() => {
|
|
|
31
31
|
'basalt/visx-boundary': 'error',
|
|
32
32
|
'basalt/visx-tooltip': 'error',
|
|
33
33
|
'basalt/token-layer-boundary': 'error',
|
|
34
|
+
'basalt/agent-resume-guard': 'error',
|
|
35
|
+
'basalt/agent-no-raw-usechat': 'error',
|
|
36
|
+
'basalt/ai-sdk-major': 'error',
|
|
34
37
|
},
|
|
35
38
|
}),
|
|
36
39
|
)
|
|
@@ -232,3 +235,215 @@ describe('rule independence', () => {
|
|
|
232
235
|
expect(rules).toContain('visx-tooltip')
|
|
233
236
|
})
|
|
234
237
|
})
|
|
238
|
+
|
|
239
|
+
// ── agent-resume-guard ───────────────────────────────────────────────────────
|
|
240
|
+
// The two agent rules honour a SEPARATE escape token, `basalt-agent-allow`, not `theme-allow` — a
|
|
241
|
+
// color exemption must never be able to switch off a streaming guard. The `theme-allow` fixture
|
|
242
|
+
// below proves the wrong token does not suppress the finding.
|
|
243
|
+
|
|
244
|
+
describe('basalt/agent-resume-guard', () => {
|
|
245
|
+
it('flags useChat({ resume: true })', () => {
|
|
246
|
+
const { code, rules } = run(`const c = useChat({ id, resume: true })\n`)
|
|
247
|
+
expect(code).toBe(1)
|
|
248
|
+
expect(rules).toContain('agent-resume-guard')
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
it('does NOT flag useChat({ resume: false })', () => {
|
|
252
|
+
const { code, rules } = run(`const c = useChat({ id, resume: false })\n`)
|
|
253
|
+
expect(code).toBe(0)
|
|
254
|
+
expect(rules).not.toContain('agent-resume-guard')
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
it('does NOT flag a bare useChat({ id }) with no resume key', () => {
|
|
258
|
+
const { code, rules } = run(`const c = useChat({ id })\n`)
|
|
259
|
+
expect(code).toBe(0)
|
|
260
|
+
expect(rules).not.toContain('agent-resume-guard')
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
it('flags chat.resumeStream() called from an effect', () => {
|
|
264
|
+
const { code, rules } = run(`useEffect(() => { chat.resumeStream() }, [])\n`)
|
|
265
|
+
expect(code).toBe(1)
|
|
266
|
+
expect(rules).toContain('agent-resume-guard')
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
it('does NOT flag chat.resumeStream() marked basalt-agent-allow', () => {
|
|
270
|
+
const { code, rules } = run(`// basalt-agent-allow\nchat.resumeStream()\n`)
|
|
271
|
+
expect(code).toBe(0)
|
|
272
|
+
expect(rules).not.toContain('agent-resume-guard')
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
it('STILL flags chat.resumeStream() marked only theme-allow (wrong escape token)', () => {
|
|
276
|
+
const { code, rules } = run(`// theme-allow\nchat.resumeStream()\n`)
|
|
277
|
+
expect(code).toBe(1)
|
|
278
|
+
expect(rules).toContain('agent-resume-guard')
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
it('does NOT flag an unrelated call like runs.start(id, text)', () => {
|
|
282
|
+
const { code, rules } = run(`runs.start(id, text)\n`)
|
|
283
|
+
expect(code).toBe(0)
|
|
284
|
+
expect(rules).not.toContain('agent-resume-guard')
|
|
285
|
+
})
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
// ── agent-no-raw-usechat ─────────────────────────────────────────────────────
|
|
289
|
+
|
|
290
|
+
describe('basalt/agent-no-raw-usechat', () => {
|
|
291
|
+
it('flags importing useChat from @ai-sdk/react', () => {
|
|
292
|
+
const { code, rules } = run(`import { useChat } from '@ai-sdk/react'\n`, 'lib.ts')
|
|
293
|
+
expect(code).toBe(1)
|
|
294
|
+
expect(rules).toContain('agent-no-raw-usechat')
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
it('flags importing useCompletion from @ai-sdk/react', () => {
|
|
298
|
+
const { code, rules } = run(`import { useCompletion } from '@ai-sdk/react'\n`, 'lib.ts')
|
|
299
|
+
expect(code).toBe(1)
|
|
300
|
+
expect(rules).toContain('agent-no-raw-usechat')
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
it('does NOT flag a type-only import of UIMessage from the same module', () => {
|
|
304
|
+
const { code, rules } = run(`import type { UIMessage } from '@ai-sdk/react'\n`, 'lib.ts')
|
|
305
|
+
expect(code).toBe(0)
|
|
306
|
+
expect(rules).not.toContain('agent-no-raw-usechat')
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
it('does NOT flag an unrelated import from ai', () => {
|
|
310
|
+
const { code, rules } = run(`import { DefaultChatTransport } from 'ai'\n`, 'lib.ts')
|
|
311
|
+
expect(code).toBe(0)
|
|
312
|
+
expect(rules).not.toContain('agent-no-raw-usechat')
|
|
313
|
+
})
|
|
314
|
+
|
|
315
|
+
it('does NOT flag useChat imported from a local module', () => {
|
|
316
|
+
const { code, rules } = run(`import { useChat } from './my-hooks'\n`, 'lib.ts')
|
|
317
|
+
expect(code).toBe(0)
|
|
318
|
+
expect(rules).not.toContain('agent-no-raw-usechat')
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
// The matcher covers TWO source specifiers (RAW_USE_CHAT_SOURCES: '@ai-sdk/react' AND
|
|
322
|
+
// 'ai/react') — every fixture above only exercises '@ai-sdk/react'; this pins the other half.
|
|
323
|
+
it("flags importing useChat from 'ai/react' (the other matched source)", () => {
|
|
324
|
+
const { code, rules } = run(`import { useChat } from 'ai/react'\n`, 'lib.ts')
|
|
325
|
+
expect(code).toBe(1)
|
|
326
|
+
expect(rules).toContain('agent-no-raw-usechat')
|
|
327
|
+
})
|
|
328
|
+
|
|
329
|
+
it('does NOT flag an import marked basalt-agent-allow', () => {
|
|
330
|
+
const { code, rules } = run(
|
|
331
|
+
`// basalt-agent-allow\nimport { useChat } from '@ai-sdk/react'\n`,
|
|
332
|
+
'lib.ts',
|
|
333
|
+
)
|
|
334
|
+
expect(code).toBe(0)
|
|
335
|
+
expect(rules).not.toContain('agent-no-raw-usechat')
|
|
336
|
+
})
|
|
337
|
+
|
|
338
|
+
it('STILL flags an import marked only theme-allow (wrong escape token)', () => {
|
|
339
|
+
const { code, rules } = run(
|
|
340
|
+
`// theme-allow\nimport { useChat } from '@ai-sdk/react'\n`,
|
|
341
|
+
'lib.ts',
|
|
342
|
+
)
|
|
343
|
+
expect(code).toBe(1)
|
|
344
|
+
expect(rules).toContain('agent-no-raw-usechat')
|
|
345
|
+
})
|
|
346
|
+
})
|
|
347
|
+
|
|
348
|
+
// ── ai-sdk-major ─────────────────────────────────────────────────────────────
|
|
349
|
+
// The lint rule compares the LINTED FILE's nearest package.json against basalt-ui's own declared
|
|
350
|
+
// `ai` peer major (read from packages/basalt-ui/package.json — the real file, since the plugin
|
|
351
|
+
// resolves it relative to its own module location regardless of where it's invoked from). basalt-ui
|
|
352
|
+
// declares "ai": "^7.0.15" (major 7) in both devDependencies and peerDependencies.
|
|
353
|
+
|
|
354
|
+
describe('basalt/ai-sdk-major', () => {
|
|
355
|
+
it("flags when the nearest package.json declares a different ai major (5 vs basalt's 7)", () => {
|
|
356
|
+
writeFileSync(resolve(dir, 'package.json'), JSON.stringify({ dependencies: { ai: '5.0.196' } }))
|
|
357
|
+
const { code, rules } = run(`import { streamText } from 'ai'\n`, 'lib.ts')
|
|
358
|
+
expect(code).toBe(1)
|
|
359
|
+
expect(rules).toContain('ai-sdk-major')
|
|
360
|
+
})
|
|
361
|
+
|
|
362
|
+
it('does NOT flag when the nearest package.json declares the same major (^7.0.18)', () => {
|
|
363
|
+
writeFileSync(resolve(dir, 'package.json'), JSON.stringify({ dependencies: { ai: '^7.0.18' } }))
|
|
364
|
+
const { code, rules } = run(`import { streamText } from 'ai'\n`, 'lib.ts')
|
|
365
|
+
expect(code).toBe(0)
|
|
366
|
+
expect(rules).not.toContain('ai-sdk-major')
|
|
367
|
+
})
|
|
368
|
+
|
|
369
|
+
it('does NOT flag when there is no ai in the nearest package.json', () => {
|
|
370
|
+
writeFileSync(resolve(dir, 'package.json'), JSON.stringify({ dependencies: {} }))
|
|
371
|
+
const { code, rules } = run(`import { streamText } from 'ai'\n`, 'lib.ts')
|
|
372
|
+
expect(code).toBe(0)
|
|
373
|
+
expect(rules).not.toContain('ai-sdk-major')
|
|
374
|
+
})
|
|
375
|
+
|
|
376
|
+
it('does NOT flag an unrelated import even with a skewed nearest package.json', () => {
|
|
377
|
+
writeFileSync(resolve(dir, 'package.json'), JSON.stringify({ dependencies: { ai: '5.0.196' } }))
|
|
378
|
+
const { code, rules } = run(`import { useState } from 'react'\n`, 'lib.ts')
|
|
379
|
+
expect(code).toBe(0)
|
|
380
|
+
expect(rules).not.toContain('ai-sdk-major')
|
|
381
|
+
})
|
|
382
|
+
|
|
383
|
+
// The matcher covers TWO forms (source === 'ai' OR source.startsWith('@ai-sdk/')) — every
|
|
384
|
+
// fixture above only exercises the bare 'ai' specifier; this pins the scoped-package half.
|
|
385
|
+
it("flags a scoped '@ai-sdk/*' import when the nearest package.json declares a different ai major", () => {
|
|
386
|
+
writeFileSync(resolve(dir, 'package.json'), JSON.stringify({ dependencies: { ai: '5.0.196' } }))
|
|
387
|
+
const { code, rules } = run(`import { openai } from '@ai-sdk/openai'\n`, 'lib.ts')
|
|
388
|
+
expect(code).toBe(1)
|
|
389
|
+
expect(rules).toContain('ai-sdk-major')
|
|
390
|
+
})
|
|
391
|
+
|
|
392
|
+
it("does NOT flag a scoped '@ai-sdk/*' import when the nearest package.json declares the same major", () => {
|
|
393
|
+
writeFileSync(resolve(dir, 'package.json'), JSON.stringify({ dependencies: { ai: '^7.0.18' } }))
|
|
394
|
+
const { code, rules } = run(`import { openai } from '@ai-sdk/openai'\n`, 'lib.ts')
|
|
395
|
+
expect(code).toBe(0)
|
|
396
|
+
expect(rules).not.toContain('ai-sdk-major')
|
|
397
|
+
})
|
|
398
|
+
|
|
399
|
+
// Unlike the other rules in this file, ai-sdk-major honours `basalt-agent-allow` — the SAME
|
|
400
|
+
// token as its two agent-chat siblings above — not `theme-allow`. A skewed producer/consumer
|
|
401
|
+
// import that is genuinely intentional (see doctor's `aiMajorSkewReason`) can mark the line.
|
|
402
|
+
it('does NOT flag an import marked basalt-agent-allow, even with a skewed nearest package.json', () => {
|
|
403
|
+
writeFileSync(resolve(dir, 'package.json'), JSON.stringify({ dependencies: { ai: '5.0.196' } }))
|
|
404
|
+
const { code, rules } = run(
|
|
405
|
+
`// basalt-agent-allow\nimport { streamText } from 'ai'\n`,
|
|
406
|
+
'lib.ts',
|
|
407
|
+
)
|
|
408
|
+
expect(code).toBe(0)
|
|
409
|
+
expect(rules).not.toContain('ai-sdk-major')
|
|
410
|
+
})
|
|
411
|
+
|
|
412
|
+
it('STILL flags an import marked only theme-allow (wrong escape token)', () => {
|
|
413
|
+
writeFileSync(resolve(dir, 'package.json'), JSON.stringify({ dependencies: { ai: '5.0.196' } }))
|
|
414
|
+
const { code, rules } = run(`// theme-allow\nimport { streamText } from 'ai'\n`, 'lib.ts')
|
|
415
|
+
expect(code).toBe(1)
|
|
416
|
+
expect(rules).toContain('ai-sdk-major')
|
|
417
|
+
})
|
|
418
|
+
})
|
|
419
|
+
|
|
420
|
+
// ── raw-scroll-container — promotion (off → warn shipped) ────────────────────
|
|
421
|
+
|
|
422
|
+
describe('basalt/raw-scroll-container promotion', () => {
|
|
423
|
+
it('ships "warn" (not "off") in the consumer preset', () => {
|
|
424
|
+
const shipped = JSON.parse(
|
|
425
|
+
readFileSync(resolve(import.meta.dirname, 'oxlint.json'), 'utf8'),
|
|
426
|
+
) as { rules: Record<string, unknown> }
|
|
427
|
+
expect(shipped.rules['basalt/raw-scroll-container']).toBe('warn')
|
|
428
|
+
})
|
|
429
|
+
|
|
430
|
+
it('stays "warn" repo-local', () => {
|
|
431
|
+
const repoLocal = JSON.parse(
|
|
432
|
+
readFileSync(resolve(import.meta.dirname, '..', '..', '..', '.oxlintrc.json'), 'utf8'),
|
|
433
|
+
) as { rules: Record<string, unknown> }
|
|
434
|
+
expect(repoLocal.rules['basalt/raw-scroll-container']).toBe('warn')
|
|
435
|
+
})
|
|
436
|
+
|
|
437
|
+
it('still flags a raw overflow:auto style property at the shipped level', () => {
|
|
438
|
+
writeFileSync(
|
|
439
|
+
resolve(dir, '.oxlintrc.json'),
|
|
440
|
+
JSON.stringify({
|
|
441
|
+
plugins: [],
|
|
442
|
+
jsPlugins: [PLUGIN_PATH],
|
|
443
|
+
rules: { 'basalt/raw-scroll-container': 'warn' },
|
|
444
|
+
}),
|
|
445
|
+
)
|
|
446
|
+
const { rules } = run(`const s = { overflowY: 'auto' }\n`, 'lib.ts')
|
|
447
|
+
expect(rules).toContain('raw-scroll-container')
|
|
448
|
+
})
|
|
449
|
+
})
|
package/configs/oxlint.json
CHANGED
|
@@ -20,9 +20,12 @@
|
|
|
20
20
|
"basalt/raw-size-literal": "warn",
|
|
21
21
|
"basalt/card-inset": "error",
|
|
22
22
|
"basalt/chart-in-raw-surface": "error",
|
|
23
|
-
"basalt/raw-scroll-container": "
|
|
23
|
+
"basalt/raw-scroll-container": "warn",
|
|
24
24
|
"basalt/visx-boundary": "error",
|
|
25
|
-
"basalt/visx-tooltip": "error"
|
|
25
|
+
"basalt/visx-tooltip": "error",
|
|
26
|
+
"basalt/agent-resume-guard": "warn",
|
|
27
|
+
"basalt/agent-no-raw-usechat": "warn",
|
|
28
|
+
"basalt/ai-sdk-major": "warn"
|
|
26
29
|
},
|
|
27
30
|
"overrides": [
|
|
28
31
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-agent-thread-runs.d.ts","sourceRoot":"","sources":["../../src/agent/use-agent-thread-runs.ts"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAgB,eAAe,EAAE,MAAM,WAAW,CAAA;AAE9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACxC,OAAO,KAAK,EAA6B,YAAY,EAAE,MAAM,UAAU,CAAA;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAIjD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,cAAc,CAAC,KAAK,GAAG,SAAS,IAAI;IAC9C,yFAAyF;IACzF,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,CAAA;CACxB,CAAA;AAID,MAAM,MAAM,sBAAsB,CAAC,KAAK,GAAG,SAAS,IAAI;IACtD;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,SAAS,EACd,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,GAC7B,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;IACzD,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;IACnC,uFAAuF;IACvF,QAAQ,CAAC,cAAc,EAAE,eAAe,CAAC,KAAK,CAAC,CAAA;IAC/C;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,EAAE,CAAA;CAClD,CAAA;AAID,MAAM,MAAM,wBAAwB,CAAC,KAAK,GAAG,SAAS,IAAI;IACxD,6FAA6F;IAC7F,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;IACzD,2FAA2F;IAC3F,QAAQ,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACzD;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,iEAAiE;IACjE,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IACzC,uDAAuD;IACvD,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAC7B,CAAA;AA0ID;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,GAAG,SAAS,EAAE,EACpD,SAAS,EACT,KAAK,EACL,cAAc,EACd,WAAW,GACZ,EAAE,sBAAsB,CAAC,KAAK,CAAC,GAAG,wBAAwB,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"use-agent-thread-runs.d.ts","sourceRoot":"","sources":["../../src/agent/use-agent-thread-runs.ts"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAgB,eAAe,EAAE,MAAM,WAAW,CAAA;AAE9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACxC,OAAO,KAAK,EAA6B,YAAY,EAAE,MAAM,UAAU,CAAA;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAIjD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,cAAc,CAAC,KAAK,GAAG,SAAS,IAAI;IAC9C,yFAAyF;IACzF,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,CAAA;CACxB,CAAA;AAID,MAAM,MAAM,sBAAsB,CAAC,KAAK,GAAG,SAAS,IAAI;IACtD;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,SAAS,EACd,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,GAC7B,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;IACzD,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;IACnC,uFAAuF;IACvF,QAAQ,CAAC,cAAc,EAAE,eAAe,CAAC,KAAK,CAAC,CAAA;IAC/C;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,EAAE,CAAA;CAClD,CAAA;AAID,MAAM,MAAM,wBAAwB,CAAC,KAAK,GAAG,SAAS,IAAI;IACxD,6FAA6F;IAC7F,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;IACzD,2FAA2F;IAC3F,QAAQ,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACzD;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,iEAAiE;IACjE,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IACzC,uDAAuD;IACvD,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAC7B,CAAA;AA0ID;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,GAAG,SAAS,EAAE,EACpD,SAAS,EACT,KAAK,EACL,cAAc,EACd,WAAW,GACZ,EAAE,sBAAsB,CAAC,KAAK,CAAC,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAmLjE"}
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* Mantine-styled thread-chat components over the headless `basalt-ui/agent` layer, capped by the
|
|
3
3
|
* flagship `ThreadWorkspace` composite.
|
|
4
4
|
*
|
|
5
|
-
* This module is Mantine-coupled by design and
|
|
6
|
-
*
|
|
5
|
+
* This module is Mantine-coupled by design and ships its own `basalt-ui/agent-chat` subpath
|
|
6
|
+
* (also re-exported from the root entry, unchanged for existing consumers) — unlike
|
|
7
|
+
* `basalt-ui/agent`, which stays headless so it can be styled by any consumer.
|
|
7
8
|
*
|
|
8
9
|
* @example
|
|
9
|
-
* import { ThreadWorkspace } from 'basalt-ui'
|
|
10
|
+
* import { ThreadWorkspace } from 'basalt-ui/agent-chat'
|
|
10
11
|
* import { createThreadsStore, edenTransport, heuristicOutcome } from 'basalt-ui/agent'
|
|
11
12
|
*/
|
|
12
13
|
export { ThreadWorkspace } from './thread-workspace.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent-chat/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent-chat/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAG9D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAGpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACzD,YAAY,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAGnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACzD,YAAY,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAGnE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG/C,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACxE,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA"}
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -126,6 +126,25 @@ export type BasaltConfig = {
|
|
|
126
126
|
* { exemptRules: { 'inline-display': ['agent'] } } // inline-display never fires under src/agent/**
|
|
127
127
|
*/
|
|
128
128
|
exemptRules?: Partial<Record<GuardKind, string[]>>;
|
|
129
|
+
/**
|
|
130
|
+
* Declares an intentional `ai` package major-version skew across workspace packages, exempting
|
|
131
|
+
* `doctor`'s `ai-major-parity` hard check. The value IS the reason — a bare `true` is rejected,
|
|
132
|
+
* because the whole point of this key is that the pairing is written down, not just switched off.
|
|
133
|
+
* A written declaration is the pin `basalt/ai-sdk-major`'s own comment notes is otherwise missing.
|
|
134
|
+
*
|
|
135
|
+
* Semantics: absent (or present but not a non-empty string) → the skew still hard-fails exactly as
|
|
136
|
+
* without this key. A non-empty string with a skew present → `doctor` passes, echoing both the
|
|
137
|
+
* skew and this reason. A non-empty string with NO skew present → `doctor` warns that the
|
|
138
|
+
* exemption is stale and can be deleted (an exemption nobody re-checks is how a real, later skew
|
|
139
|
+
* slips through unnoticed).
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* // apps/api streams on ai@5; apps/dashboard parses on ai@7; a producer-side TransformStream
|
|
143
|
+
* // neutralizes the one enum value that differs between the two majors.
|
|
144
|
+
* { aiMajorSkewReason: 'apps/api pinned to ai@5, apps/dashboard on ai@7 — the skew is neutralized '
|
|
145
|
+
* + 'by a producer-side TransformStream in apps/api/src/stream-transform.ts' }
|
|
146
|
+
*/
|
|
147
|
+
aiMajorSkewReason?: string;
|
|
129
148
|
};
|
|
130
149
|
/**
|
|
131
150
|
* Theme guard — thin FS walker over the headless `../guard` core. Reads BasaltConfig, builds a
|
|
@@ -324,6 +343,17 @@ type DoctorResult = {
|
|
|
324
343
|
*
|
|
325
344
|
* Hard failures (exit non-zero):
|
|
326
345
|
* 1. .basalt/manifest.json exists (init was run).
|
|
346
|
+
* 6. `ai-major-parity`: every workspace package that declares the `ai` package agrees on its
|
|
347
|
+
* major version. `basalt/ai-sdk-major` (the oxlint plugin rule) cannot catch this — it checks
|
|
348
|
+
* a linted file's NEAREST package.json, so a lint run scoped to one workspace package only
|
|
349
|
+
* ever sees that package's own `ai` major and is perfectly happy; the cross-package skew (one
|
|
350
|
+
* package streaming on `ai@5`, another parsing it on `ai@7`) only a repo-wide manifest walk
|
|
351
|
+
* can see. Skipped entirely when `cwd` has no `workspaces` field or none of its packages
|
|
352
|
+
* declare `ai`. A detected skew is exempt-able via `basalt.aiMajorSkewReason` (a non-empty
|
|
353
|
+
* reason string, not a bare `true`) in the consumer's package.json — an intentional
|
|
354
|
+
* producer/consumer split neutralized by a transform is a locked decision, not a defect, and
|
|
355
|
+
* the written reason IS the pin that a permanently-failing guard would otherwise lack. Missing
|
|
356
|
+
* or invalid (empty/non-string) still hard-fails exactly as if the key were absent.
|
|
327
357
|
*
|
|
328
358
|
* Warnings (non-fatal):
|
|
329
359
|
* 2. The installed node_modules/basalt-ui version matches the manifest's basaltVersion
|
|
@@ -335,6 +365,9 @@ type DoctorResult = {
|
|
|
335
365
|
* `bunx basalt-ui` npm fetch; best-effort, skipped if node_modules is absent).
|
|
336
366
|
* 5. `basaltAppPlugin`'s (basalt-ui/vite) default icon filenames exist under public/ (only when
|
|
337
367
|
* a public/ dir exists at all — skipped otherwise).
|
|
368
|
+
* 7. A declared `basalt.aiMajorSkewReason` when the ai majors currently AGREE — the exemption is
|
|
369
|
+
* stale and can be deleted; an exemption nobody revisits is how a real, later skew slips
|
|
370
|
+
* through unnoticed.
|
|
338
371
|
*
|
|
339
372
|
* Returns the exit code: 0 = all good, 1 = one or more hard failures.
|
|
340
373
|
*/
|
package/dist/cli/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAwB,SAAS,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAE9E,OAAO,EAAE,UAAU,EAAE,WAAW,EAA2C,MAAM,aAAa,CAAA;AAI9F,yEAAyE;AACzE,MAAM,MAAM,YAAY,GAAG;IACzB,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,4FAA4F;IAC5F,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,uGAAuG;IACvG,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;wFACoF;IACpF,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAA;IACpD,6FAA6F;IAC7F,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -783,7 +783,105 @@ function checkCoverage() {
|
|
|
783
783
|
}
|
|
784
784
|
return 1;
|
|
785
785
|
}
|
|
786
|
+
function subdirNames(base, options = {}) {
|
|
787
|
+
let entries;
|
|
788
|
+
try {
|
|
789
|
+
entries = readdirSync(base);
|
|
790
|
+
} catch {
|
|
791
|
+
return [];
|
|
792
|
+
}
|
|
793
|
+
return entries.filter((name) => {
|
|
794
|
+
if (name === "node_modules") return false;
|
|
795
|
+
if (options.skipDotDirs && name.startsWith(".")) return false;
|
|
796
|
+
try {
|
|
797
|
+
return statSync(resolve(base, name)).isDirectory();
|
|
798
|
+
} catch {
|
|
799
|
+
return false;
|
|
800
|
+
}
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
function expandPatternSegments(baseDir, segments) {
|
|
804
|
+
if (segments.length === 0) return [baseDir];
|
|
805
|
+
const [head, ...rest] = segments;
|
|
806
|
+
if (head === "**") {
|
|
807
|
+
const matches = expandPatternSegments(baseDir, rest);
|
|
808
|
+
for (const name of subdirNames(baseDir, { skipDotDirs: true })) {
|
|
809
|
+
matches.push(...expandPatternSegments(resolve(baseDir, name), segments));
|
|
810
|
+
}
|
|
811
|
+
return matches;
|
|
812
|
+
}
|
|
813
|
+
const names = head === "*" ? subdirNames(baseDir, { skipDotDirs: true }) : subdirNames(baseDir).filter((n) => n === head);
|
|
814
|
+
return names.flatMap((name) => expandPatternSegments(resolve(baseDir, name), rest));
|
|
815
|
+
}
|
|
816
|
+
function expandWorkspaceGlobs(cwd, patterns) {
|
|
817
|
+
const expand = (pattern) => expandPatternSegments(
|
|
818
|
+
cwd,
|
|
819
|
+
pattern.split("/").filter((s) => s.length > 0)
|
|
820
|
+
);
|
|
821
|
+
const excluded = new Set(
|
|
822
|
+
patterns.filter((pattern) => pattern.startsWith("!")).flatMap((pattern) => expand(pattern.replace(/^!+/, "")))
|
|
823
|
+
);
|
|
824
|
+
const dirs = [];
|
|
825
|
+
for (const pattern of patterns) {
|
|
826
|
+
if (pattern.startsWith("!")) continue;
|
|
827
|
+
for (const abs of expand(pattern)) {
|
|
828
|
+
if (excluded.has(abs)) continue;
|
|
829
|
+
if (existsSync(resolve(abs, "package.json"))) dirs.push(abs);
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
return dirs;
|
|
833
|
+
}
|
|
834
|
+
function collectWorkspacePackages(cwd) {
|
|
835
|
+
const raw = readIfExists(resolve(cwd, "package.json"));
|
|
836
|
+
if (raw === null) return { packages: [], hasWorkspacesField: false };
|
|
837
|
+
let parsed;
|
|
838
|
+
try {
|
|
839
|
+
parsed = JSON.parse(raw);
|
|
840
|
+
} catch {
|
|
841
|
+
return { packages: [], hasWorkspacesField: false };
|
|
842
|
+
}
|
|
843
|
+
const patterns = isStringArray(parsed.workspaces) ? parsed.workspaces : parsed.workspaces !== null && typeof parsed.workspaces === "object" && isStringArray(parsed.workspaces.packages) ? parsed.workspaces.packages : null;
|
|
844
|
+
if (patterns === null) return { packages: [], hasWorkspacesField: false };
|
|
845
|
+
const rootName = parsed.name && parsed.name.length > 0 ? `${parsed.name} (root)` : "(root)";
|
|
846
|
+
const workspacePackages = expandWorkspaceGlobs(cwd, patterns).map((dir) => ({
|
|
847
|
+
name: readPackageName(dir),
|
|
848
|
+
dir
|
|
849
|
+
}));
|
|
850
|
+
return {
|
|
851
|
+
packages: [{ name: rootName, dir: cwd }, ...workspacePackages],
|
|
852
|
+
hasWorkspacesField: true
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
function isStringArray(value) {
|
|
856
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
857
|
+
}
|
|
858
|
+
function majorOf(range) {
|
|
859
|
+
if (typeof range !== "string") return null;
|
|
860
|
+
const match = range.match(/\d+/);
|
|
861
|
+
return match === null ? null : Number(match[0]);
|
|
862
|
+
}
|
|
863
|
+
function aiMajorAt(dir) {
|
|
864
|
+
const raw = readIfExists(resolve(dir, "package.json"));
|
|
865
|
+
if (raw === null) return null;
|
|
866
|
+
try {
|
|
867
|
+
const pkg = JSON.parse(raw);
|
|
868
|
+
return majorOf(
|
|
869
|
+
pkg.dependencies?.["ai"] ?? pkg.devDependencies?.["ai"] ?? pkg.peerDependencies?.["ai"]
|
|
870
|
+
);
|
|
871
|
+
} catch {
|
|
872
|
+
return null;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
function resolveAiMajorSkewReason(cfg) {
|
|
876
|
+
const raw = cfg.aiMajorSkewReason;
|
|
877
|
+
if (raw === void 0) return { reason: null, presentButInvalid: false };
|
|
878
|
+
if (typeof raw === "string" && raw.trim().length > 0) {
|
|
879
|
+
return { reason: raw, presentButInvalid: false };
|
|
880
|
+
}
|
|
881
|
+
return { reason: null, presentButInvalid: true };
|
|
882
|
+
}
|
|
786
883
|
function doctor(cwd = process.cwd()) {
|
|
884
|
+
const cfg = readBasaltConfig(cwd);
|
|
787
885
|
const result = { hardFailures: 0, warnings: 0 };
|
|
788
886
|
const lines = [`
|
|
789
887
|
basalt-ui doctor \u2014 ${cwd}
|
|
@@ -881,6 +979,39 @@ basalt-ui doctor \u2014 ${cwd}
|
|
|
881
979
|
pass("public/ has all of basaltAppPlugin's default icon files");
|
|
882
980
|
}
|
|
883
981
|
}
|
|
982
|
+
const workspaceWalk = collectWorkspacePackages(cwd);
|
|
983
|
+
const aiMajors = workspaceWalk.packages.map((pkg) => ({ name: pkg.name, major: aiMajorAt(pkg.dir) })).filter((entry) => entry.major !== null);
|
|
984
|
+
const { reason: aiMajorSkewReason, presentButInvalid: aiMajorSkewReasonInvalid } = resolveAiMajorSkewReason(cfg);
|
|
985
|
+
if (aiMajors.length > 0) {
|
|
986
|
+
const distinctMajors = new Set(aiMajors.map((entry) => entry.major));
|
|
987
|
+
if (distinctMajors.size > 1) {
|
|
988
|
+
const summary = aiMajors.map((entry) => `${entry.name}@ai${entry.major}`).join(", ");
|
|
989
|
+
if (aiMajorSkewReason !== null) {
|
|
990
|
+
pass(
|
|
991
|
+
`ai package major version mismatch across workspace packages: ${summary} \u2014 exempted via basalt.aiMajorSkewReason: "${aiMajorSkewReason}"`
|
|
992
|
+
);
|
|
993
|
+
} else if (aiMajorSkewReasonInvalid) {
|
|
994
|
+
fail(
|
|
995
|
+
`ai package major version mismatch across workspace packages: ${summary} \u2014 basalt.aiMajorSkewReason is present but is not a non-empty string (a bare \`true\` is not accepted); the exemption must carry a written reason, e.g. \`aiMajorSkewReason: "apps/api on ai@5, apps/dashboard on ai@7, neutralized by a producer-side TransformStream"\`.`
|
|
996
|
+
);
|
|
997
|
+
} else {
|
|
998
|
+
fail(`ai package major version mismatch across workspace packages: ${summary}`);
|
|
999
|
+
}
|
|
1000
|
+
} else {
|
|
1001
|
+
const [major] = distinctMajors;
|
|
1002
|
+
if (aiMajorSkewReason !== null) {
|
|
1003
|
+
warn(
|
|
1004
|
+
`basalt.aiMajorSkewReason ("${aiMajorSkewReason}") is declared but the ai package major already matches across all ${aiMajors.length} workspace package(s) declaring it (ai@${major}) \u2014 the exemption is no longer needed and can be deleted.`
|
|
1005
|
+
);
|
|
1006
|
+
} else {
|
|
1007
|
+
pass(
|
|
1008
|
+
`ai package major matches across ${aiMajors.length} workspace package(s) declaring it (ai@${major})`
|
|
1009
|
+
);
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
} else if (workspaceWalk.hasWorkspacesField) {
|
|
1013
|
+
pass("ai-major-parity: no workspace package declares the ai dependency \u2014 nothing to compare");
|
|
1014
|
+
}
|
|
884
1015
|
lines.push("");
|
|
885
1016
|
if (result.hardFailures === 0 && result.warnings === 0) {
|
|
886
1017
|
lines.push("All checks passed.");
|
package/dist/surfaces.d.ts
CHANGED
|
@@ -291,6 +291,16 @@ export declare const SURFACES: {
|
|
|
291
291
|
};
|
|
292
292
|
readonly forbiddenImports: readonly [ForbiddenImport, ForbiddenImport, ForbiddenImport];
|
|
293
293
|
};
|
|
294
|
+
readonly './agent-chat': {
|
|
295
|
+
readonly kind: "doctrine";
|
|
296
|
+
readonly layer: "mantine-coupled";
|
|
297
|
+
readonly rule: "agent";
|
|
298
|
+
readonly skill: readonly ["basalt-app"];
|
|
299
|
+
readonly guardKinds: readonly [];
|
|
300
|
+
readonly description: "Mantine-styled thread-chat components over basalt-ui/agent: ThreadWorkspace, ThreadFeed, ThreadOutcomeCard, ThreadDetailPanel, Composer, ThreadTranscript, threadPartRenderers (Mantine-coupled). remend and motion are required, not optional — ThreadTranscript imports content/markdown.tsx (remend eagerly), and ThreadFeed/ThreadDetailPanel import motion/react eagerly, so this subpath fails to resolve without both installed even though peerDependenciesMeta marks them optional (npm has no per-subpath optionality).";
|
|
301
|
+
readonly optionalPeers: readonly ["ai", "motion", "remend", "use-stick-to-bottom", "react-markdown", "remark-gfm", "shiki", "@shikijs/langs", "@shikijs/themes", "beautiful-mermaid"];
|
|
302
|
+
readonly forbiddenImports: readonly [];
|
|
303
|
+
};
|
|
294
304
|
readonly './content': {
|
|
295
305
|
readonly kind: "doctrine";
|
|
296
306
|
readonly layer: "mantine-coupled";
|
package/dist/surfaces.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"surfaces.d.ts","sourceRoot":"","sources":["../src/surfaces.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAI9C;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAChB,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,OAAO,GACP,OAAO,GACP,OAAO,GACP,eAAe,GACf,UAAU,GACV,MAAM,GACN,OAAO,GACP,SAAS,GACT,KAAK,CAAA;AAET;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,eAAe,GAAG,eAAe,CAAA;AAExE;;;;GAIG;AACH,MAAM,MAAM,KAAK,GAAG,iBAAiB,GAAG,UAAU,GAAG,YAAY,GAAG,cAAc,CAAA;AAElF;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,wFAAwF;IACxF,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;IAChC,oFAAoF;IACpF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,oFAAoF;IACpF,QAAQ,CAAC,WAAW,CAAC,EAAE,IAAI,CAAA;IAC3B,2FAA2F;IAC3F,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAA;CACzB,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAA;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;CACrC,CAAA;AAID,KAAK,WAAW,GAAG;IACjB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,gBAAgB,EAAE,SAAS,eAAe,EAAE,CAAA;IACrD,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,YAAY,EAAE,CAAA;IAChD;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE;QACf,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;QACnC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;KACjC,CAAA;IACD;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAC3C,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG;IACvC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,iGAAiG;IACjG,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;IACpC,2FAA2F;IAC3F,QAAQ,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,CAAA;CAC1C,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG;IACtC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAA;IACtB,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,CAAA;CAC5B,CAAA;AAED,kEAAkE;AAClE,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,WAAW,CAAA;AA8BpD;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ
|
|
1
|
+
{"version":3,"file":"surfaces.d.ts","sourceRoot":"","sources":["../src/surfaces.ts"],"names":[],"mappings":"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"}
|
package/dist/surfaces.js
CHANGED
|
@@ -197,6 +197,27 @@ const SURFACES = {
|
|
|
197
197
|
// @visx/* ban dropped — `basalt/visx-boundary` now bans it universally outside charts.
|
|
198
198
|
forbiddenImports: [...MANTINE_BANS]
|
|
199
199
|
},
|
|
200
|
+
"./agent-chat": {
|
|
201
|
+
kind: "doctrine",
|
|
202
|
+
layer: "mantine-coupled",
|
|
203
|
+
rule: "agent",
|
|
204
|
+
skill: ["basalt-app"],
|
|
205
|
+
guardKinds: [],
|
|
206
|
+
description: "Mantine-styled thread-chat components over basalt-ui/agent: ThreadWorkspace, ThreadFeed, ThreadOutcomeCard, ThreadDetailPanel, Composer, ThreadTranscript, threadPartRenderers (Mantine-coupled). remend and motion are required, not optional \u2014 ThreadTranscript imports content/markdown.tsx (remend eagerly), and ThreadFeed/ThreadDetailPanel import motion/react eagerly, so this subpath fails to resolve without both installed even though peerDependenciesMeta marks them optional (npm has no per-subpath optionality).",
|
|
207
|
+
optionalPeers: [
|
|
208
|
+
"ai",
|
|
209
|
+
"motion",
|
|
210
|
+
"remend",
|
|
211
|
+
"use-stick-to-bottom",
|
|
212
|
+
"react-markdown",
|
|
213
|
+
"remark-gfm",
|
|
214
|
+
"shiki",
|
|
215
|
+
"@shikijs/langs",
|
|
216
|
+
"@shikijs/themes",
|
|
217
|
+
"beautiful-mermaid"
|
|
218
|
+
],
|
|
219
|
+
forbiddenImports: []
|
|
220
|
+
},
|
|
200
221
|
"./content": {
|
|
201
222
|
kind: "doctrine",
|
|
202
223
|
layer: "mantine-coupled",
|
package/llms.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# basalt-ui v1.
|
|
1
|
+
# basalt-ui v1.10.0
|
|
2
2
|
# Opinionated framework for Mantine-based React apps — theme, app shell, visx charts, toolchain presets
|
|
3
3
|
#
|
|
4
4
|
# basalt-ui is an opinionated framework for Mantine-based React apps.
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
# ./tokens.css subpath. Guide: docs/FRAMEWORK-FREE.md in the repo.
|
|
20
20
|
|
|
21
21
|
Package: basalt-ui
|
|
22
|
-
Version: 1.
|
|
22
|
+
Version: 1.10.0
|
|
23
23
|
|
|
24
24
|
## basalt-ui
|
|
25
25
|
Import: import { ... } from 'basalt-ui'
|
|
@@ -119,6 +119,13 @@ Layer: headless
|
|
|
119
119
|
Rule: basalt-agent
|
|
120
120
|
OptionalPeers: ai@^7.0.15, use-stick-to-bottom@^1.1.6
|
|
121
121
|
|
|
122
|
+
## basalt-ui/agent-chat
|
|
123
|
+
Import: import { ... } from 'basalt-ui/agent-chat'
|
|
124
|
+
Description: Mantine-styled thread-chat components over basalt-ui/agent: ThreadWorkspace, ThreadFeed, ThreadOutcomeCard, ThreadDetailPanel, Composer, ThreadTranscript, threadPartRenderers (Mantine-coupled). remend and motion are required, not optional — ThreadTranscript imports content/markdown.tsx (remend eagerly), and ThreadFeed/ThreadDetailPanel import motion/react eagerly, so this subpath fails to resolve without both installed even though peerDependenciesMeta marks them optional (npm has no per-subpath optionality).
|
|
125
|
+
Layer: mantine-coupled
|
|
126
|
+
Rule: basalt-agent
|
|
127
|
+
OptionalPeers: ai@^7.0.15, motion@12.42.0, remend@1.3.0, use-stick-to-bottom@^1.1.6, react-markdown@^10.1.0, remark-gfm@^4.0.1, shiki@^4.3.0, @shikijs/langs@^4.3.1, @shikijs/themes@^4.3.1, beautiful-mermaid@^1.1.0
|
|
128
|
+
|
|
122
129
|
## basalt-ui/content
|
|
123
130
|
Import: import { ... } from 'basalt-ui/content'
|
|
124
131
|
Description: Prose (article/chat typography), CodeBlock (shiki, optional peer), Callout, TableOfContents, ReadingProgress, Markdown (react-markdown + remark-gfm, optional peers, streaming-aware), MermaidDiagram (beautiful-mermaid, optional peer), mdxComponents/createMdxComponents, ArticleLayout (docs-page frame), ArticleCard/ArticleGrid (overview cards), Article model (sortArticles/filterArticles/formatArticleDate), ArticleFilterBar (category/tags filter UI), toArticleActions (Spotlight projector, @mantine/spotlight type-only), GuideLink/GuideDrawer (contextual-help drawer) — the content/prose surface
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "basalt-ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "Opinionated framework for Mantine-based React apps — theme, app shell, visx charts, toolchain presets",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"charts",
|
|
@@ -104,6 +104,10 @@
|
|
|
104
104
|
"types": "./dist/agent/index.d.ts",
|
|
105
105
|
"import": "./dist/agent/index.js"
|
|
106
106
|
},
|
|
107
|
+
"./agent-chat": {
|
|
108
|
+
"types": "./dist/agent-chat/index.d.ts",
|
|
109
|
+
"import": "./dist/agent-chat/index.js"
|
|
110
|
+
},
|
|
107
111
|
"./content": {
|
|
108
112
|
"types": "./dist/content/index.d.ts",
|
|
109
113
|
"import": "./dist/content/index.js"
|
|
@@ -128,6 +132,7 @@
|
|
|
128
132
|
"scripts": {
|
|
129
133
|
"build": "tsup && tsc --emitDeclarationOnly --declarationMap && bun scripts/copy-assets.mjs && bun scripts/gen-tokens-css.mjs && bun scripts/fix-esm-extensions.mjs",
|
|
130
134
|
"typecheck": "tsc --noEmit",
|
|
135
|
+
"test": "cd ../.. && bun test packages/basalt-ui",
|
|
131
136
|
"pack-test": "bash scripts/pack-test.sh",
|
|
132
137
|
"prepack": "bun run build",
|
|
133
138
|
"clean": "rm -rf dist"
|