@actioneer/ads 0.2.0 → 0.2.2
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/bin/ads-init.mjs +209 -19
- package/llms.txt +129 -0
- package/manifest.json +1229 -7
- package/package.json +1 -1
package/bin/ads-init.mjs
CHANGED
|
@@ -17,14 +17,15 @@
|
|
|
17
17
|
* • drop a consumer-mode `ads-lint.config.mjs`
|
|
18
18
|
* (`libraryPackage: "@actioneer/ads"`, `libraryRoot: null`)
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
20
|
+
* The pure write-plan (`planInit`) and the package-manager detection are covered
|
|
21
|
+
* by unit tests in ads-init.test.mjs; the applier's IO is exercised end-to-end by
|
|
22
|
+
* a manual run and the release rehearsal.
|
|
22
23
|
*/
|
|
23
24
|
|
|
24
25
|
import fs from "node:fs";
|
|
25
26
|
import path from "node:path";
|
|
26
27
|
import { execFileSync } from "node:child_process";
|
|
27
|
-
import {
|
|
28
|
+
import { fileURLToPath } from "node:url";
|
|
28
29
|
|
|
29
30
|
const PKG = "@actioneer/ads";
|
|
30
31
|
const STYLE_IMPORT = `@import "${PKG}/styles.css";`;
|
|
@@ -39,6 +40,7 @@ const STYLE_IMPORT = `@import "${PKG}/styles.css";`;
|
|
|
39
40
|
* @property {string|null} layoutPath repo-relative path to the root layout (or null)
|
|
40
41
|
* @property {string|null} layoutContent
|
|
41
42
|
* @property {boolean} hasAdsLintConfig
|
|
43
|
+
* @property {"npm"|"pnpm"|"yarn"|"bun"} [packageManager] detected consumer PM (default npm)
|
|
42
44
|
*
|
|
43
45
|
* @typedef {Object} Edit
|
|
44
46
|
* @property {"install"|"write-file"|"edit-file"|"manual"} type
|
|
@@ -50,8 +52,45 @@ const STYLE_IMPORT = `@import "${PKG}/styles.css";`;
|
|
|
50
52
|
* @property {number} [findIndex] edit-file: positional replace offset (disambiguates repeated tokens)
|
|
51
53
|
* @property {string} [addImport] edit-file: import line to prepend if absent
|
|
52
54
|
* @property {string[]} [packages] install: package specifiers
|
|
55
|
+
* @property {"npm"|"pnpm"|"yarn"|"bun"} [manager] install: package manager to shell out to
|
|
53
56
|
*/
|
|
54
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Detect the consumer's package manager so `init` installs with THEIR tool
|
|
60
|
+
* rather than always shelling out to `npm` (which strands pnpm/yarn/bun users
|
|
61
|
+
* with a stray package-lock.json + a mixed lockfile). Precedence, most→least
|
|
62
|
+
* authoritative: the corepack `packageManager` field, the invoking PM's user
|
|
63
|
+
* agent (set when run via `pnpm dlx` / `yarn dlx` / `bunx`), then a lockfile on
|
|
64
|
+
* disk. Defaults to npm.
|
|
65
|
+
* @param {{packageManagerField?:string|null, userAgent?:string|null, lockfiles?:string[]}} [signals]
|
|
66
|
+
* @returns {"npm"|"pnpm"|"yarn"|"bun"}
|
|
67
|
+
*/
|
|
68
|
+
export function detectPackageManager({ packageManagerField, userAgent, lockfiles } = {}) {
|
|
69
|
+
const field = /^(pnpm|yarn|bun|npm)(@|$)/.exec(packageManagerField ?? "");
|
|
70
|
+
if (field) return field[1];
|
|
71
|
+
const ua = /^(pnpm|yarn|bun)\//.exec(userAgent ?? "");
|
|
72
|
+
if (ua) return ua[1];
|
|
73
|
+
const locks = new Set(lockfiles ?? []);
|
|
74
|
+
if (locks.has("pnpm-lock.yaml")) return "pnpm";
|
|
75
|
+
if (locks.has("yarn.lock")) return "yarn";
|
|
76
|
+
if (locks.has("bun.lockb") || locks.has("bun.lock")) return "bun";
|
|
77
|
+
return "npm";
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The install invocation for a given manager: npm uses `install`, the rest use
|
|
82
|
+
* `add`.
|
|
83
|
+
* @param {"npm"|"pnpm"|"yarn"|"bun"} manager
|
|
84
|
+
* @param {string[]} packages
|
|
85
|
+
* @returns {[string, string[]]} [command, args]
|
|
86
|
+
*/
|
|
87
|
+
export function installCommand(manager, packages) {
|
|
88
|
+
const verb = manager === "npm" ? "install" : "add";
|
|
89
|
+
return [manager, [verb, ...packages]];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const LOCKFILES = ["package-lock.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"];
|
|
93
|
+
|
|
55
94
|
/** @param {RepoState} state @returns {Edit[]} */
|
|
56
95
|
export function planInit(state) {
|
|
57
96
|
const edits = [];
|
|
@@ -59,7 +98,8 @@ export function planInit(state) {
|
|
|
59
98
|
// 1. Install the package (+ motion peer for the reduced-motion provider).
|
|
60
99
|
const missing = ["@actioneer/ads", "motion"].filter((p) => !state.dependencies?.[p]);
|
|
61
100
|
if (missing.length) {
|
|
62
|
-
|
|
101
|
+
const manager = state.packageManager ?? "npm";
|
|
102
|
+
edits.push({ type: "install", title: `install ${missing.join(", ")}`, packages: missing, manager });
|
|
63
103
|
}
|
|
64
104
|
|
|
65
105
|
// 2. Inject the styles.css import IMMEDIATELY AFTER `@import "tailwindcss"`.
|
|
@@ -214,6 +254,15 @@ const CANDIDATE_CSS = [
|
|
|
214
254
|
];
|
|
215
255
|
const CANDIDATE_LAYOUT = ["app/layout.tsx", "src/app/layout.tsx", "app/layout.jsx", "src/app/layout.jsx"];
|
|
216
256
|
|
|
257
|
+
// The load-bearing anchor: ADS styles must import into the SAME CSS graph as
|
|
258
|
+
// tailwindcss, right after it (styles.css before tailwindcss leaves @theme
|
|
259
|
+
// inert). Detection keys off this so a non-standard stylesheet is still found.
|
|
260
|
+
const TAILWIND_IMPORT_RE = /@import\s+["']tailwindcss["']/;
|
|
261
|
+
// Dirs the stylesheet scan never descends into.
|
|
262
|
+
const SCAN_IGNORE = new Set([
|
|
263
|
+
"node_modules", ".git", ".next", "dist", "dist-lib", "build", "out", "coverage", ".turbo", ".vercel", ".cache",
|
|
264
|
+
]);
|
|
265
|
+
|
|
217
266
|
function toPosix(p) {
|
|
218
267
|
return p.split(path.sep).join("/");
|
|
219
268
|
}
|
|
@@ -221,6 +270,81 @@ function fileExistsInState(state, relPosix) {
|
|
|
221
270
|
return state._existing?.has(relPosix) ?? false;
|
|
222
271
|
}
|
|
223
272
|
|
|
273
|
+
/**
|
|
274
|
+
* Find the global stylesheet to wire ADS styles into. Because the import order
|
|
275
|
+
* is load-bearing, detection PREFERS the stylesheet that already imports
|
|
276
|
+
* tailwindcss — first among the conventional locations, then ANYWHERE in the
|
|
277
|
+
* project (bounded scan) so a non-standard path (e.g. `src/index.css`,
|
|
278
|
+
* `app/tailwind.css`) is auto-wired instead of degrading to a hand-edit note.
|
|
279
|
+
* Falls back to the first conventional file that exists (→ manual, with anchor
|
|
280
|
+
* guidance), else null.
|
|
281
|
+
* @returns {{path: string|null, content: string|null}}
|
|
282
|
+
*/
|
|
283
|
+
export function detectGlobalCss(cwd) {
|
|
284
|
+
const read = (rel) => {
|
|
285
|
+
const abs = path.join(cwd, rel);
|
|
286
|
+
return fs.existsSync(abs) ? fs.readFileSync(abs, "utf8") : null;
|
|
287
|
+
};
|
|
288
|
+
// 1. Conventional location that already imports tailwindcss (the anchor).
|
|
289
|
+
for (const p of CANDIDATE_CSS) {
|
|
290
|
+
const c = read(p);
|
|
291
|
+
if (c != null && TAILWIND_IMPORT_RE.test(c)) return { path: p, content: c };
|
|
292
|
+
}
|
|
293
|
+
// 2. Any .css in the project importing tailwindcss (covers non-standard paths).
|
|
294
|
+
const scanned = scanForTailwindCss(cwd);
|
|
295
|
+
if (scanned) return scanned;
|
|
296
|
+
// 3. A conventional file exists but has no tailwindcss anchor → manual path.
|
|
297
|
+
for (const p of CANDIDATE_CSS) {
|
|
298
|
+
const c = read(p);
|
|
299
|
+
if (c != null) return { path: p, content: c };
|
|
300
|
+
}
|
|
301
|
+
return { path: null, content: null };
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/** Bounded walk for the shallowest .css that imports tailwindcss. */
|
|
305
|
+
function scanForTailwindCss(cwd, maxDepth = 5) {
|
|
306
|
+
const hits = [];
|
|
307
|
+
const walk = (rel, depth) => {
|
|
308
|
+
if (depth > maxDepth) return;
|
|
309
|
+
let entries;
|
|
310
|
+
try {
|
|
311
|
+
entries = fs.readdirSync(path.join(cwd, rel || "."), { withFileTypes: true });
|
|
312
|
+
} catch {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
for (const e of entries) {
|
|
316
|
+
if (e.name.startsWith(".")) continue;
|
|
317
|
+
const childRel = rel ? `${rel}/${e.name}` : e.name;
|
|
318
|
+
if (e.isDirectory()) {
|
|
319
|
+
if (!SCAN_IGNORE.has(e.name)) walk(childRel, depth + 1);
|
|
320
|
+
} else if (e.name.endsWith(".css")) {
|
|
321
|
+
let c;
|
|
322
|
+
try {
|
|
323
|
+
c = fs.readFileSync(path.join(cwd, childRel), "utf8");
|
|
324
|
+
} catch {
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (TAILWIND_IMPORT_RE.test(c)) hits.push({ path: toPosix(childRel), content: c });
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
walk("", 0);
|
|
332
|
+
// Shallowest path wins (the app entry over a nested one); stable tiebreak.
|
|
333
|
+
hits.sort((a, b) => a.path.split("/").length - b.path.split("/").length || a.path.localeCompare(b.path));
|
|
334
|
+
return hits[0] ?? null;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Re-check the load-bearing outcome after init: is `@import "…/styles.css"`
|
|
339
|
+
* actually present in the detected global stylesheet? Drives the end-of-run
|
|
340
|
+
* summary so a missed/deferred styles import can't scroll past unnoticed.
|
|
341
|
+
* @returns {{ok: boolean, path: string|null}}
|
|
342
|
+
*/
|
|
343
|
+
export function verifyStylesWired(cwd) {
|
|
344
|
+
const css = detectGlobalCss(cwd);
|
|
345
|
+
return { ok: css.content != null && css.content.includes(STYLE_IMPORT), path: css.path };
|
|
346
|
+
}
|
|
347
|
+
|
|
224
348
|
function readRepoState(cwd) {
|
|
225
349
|
const read = (rel) => {
|
|
226
350
|
const abs = path.join(cwd, rel);
|
|
@@ -230,7 +354,13 @@ function readRepoState(cwd) {
|
|
|
230
354
|
const pkg = pkgRaw ? JSON.parse(pkgRaw) : {};
|
|
231
355
|
const dependencies = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };
|
|
232
356
|
|
|
233
|
-
const
|
|
357
|
+
const packageManager = detectPackageManager({
|
|
358
|
+
packageManagerField: pkg.packageManager ?? null,
|
|
359
|
+
userAgent: process.env.npm_config_user_agent ?? null,
|
|
360
|
+
lockfiles: LOCKFILES.filter((f) => fs.existsSync(path.join(cwd, f))),
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
const css = detectGlobalCss(cwd);
|
|
234
364
|
const layoutPath = CANDIDATE_LAYOUT.find((p) => fs.existsSync(path.join(cwd, p))) ?? null;
|
|
235
365
|
|
|
236
366
|
const _existing = new Set();
|
|
@@ -240,12 +370,13 @@ function readRepoState(cwd) {
|
|
|
240
370
|
|
|
241
371
|
return {
|
|
242
372
|
dependencies,
|
|
243
|
-
globalCssPath,
|
|
244
|
-
globalCssContent:
|
|
373
|
+
globalCssPath: css.path,
|
|
374
|
+
globalCssContent: css.content,
|
|
245
375
|
layoutPath,
|
|
246
376
|
layoutContent: layoutPath ? read(layoutPath) : null,
|
|
247
377
|
hasAdsLintConfig:
|
|
248
378
|
fs.existsSync(path.join(cwd, "ads-lint.config.mjs")) || fs.existsSync(path.join(cwd, "ads-lint.config.js")),
|
|
379
|
+
packageManager,
|
|
249
380
|
_existing,
|
|
250
381
|
};
|
|
251
382
|
}
|
|
@@ -254,8 +385,9 @@ function applyEdit(cwd, edit) {
|
|
|
254
385
|
const abs = edit.path ? path.join(cwd, edit.path) : null;
|
|
255
386
|
switch (edit.type) {
|
|
256
387
|
case "install": {
|
|
257
|
-
|
|
258
|
-
|
|
388
|
+
const [cmd, args] = installCommand(edit.manager ?? "npm", edit.packages);
|
|
389
|
+
console.log(` → ${cmd} ${args.join(" ")}`);
|
|
390
|
+
execFileSync(cmd, args, { cwd, stdio: "inherit" });
|
|
259
391
|
return;
|
|
260
392
|
}
|
|
261
393
|
case "write-file": {
|
|
@@ -288,6 +420,47 @@ function applyEdit(cwd, edit) {
|
|
|
288
420
|
}
|
|
289
421
|
}
|
|
290
422
|
|
|
423
|
+
/**
|
|
424
|
+
* End-of-run summary. The styles import carries EVERY token (colors, type, and
|
|
425
|
+
* the animation curves/speeds), so its outcome gets promoted out of the
|
|
426
|
+
* scrolling edit log into a verified ✓ / ⚠ block that can't be missed — plus any
|
|
427
|
+
* remaining manual steps and the import hint.
|
|
428
|
+
*/
|
|
429
|
+
function printSummary(cwd, edits) {
|
|
430
|
+
const wired = verifyStylesWired(cwd);
|
|
431
|
+
const bar = "─".repeat(70);
|
|
432
|
+
|
|
433
|
+
console.log("");
|
|
434
|
+
if (wired.ok) {
|
|
435
|
+
console.log(`✓ ADS styles wired — \`${STYLE_IMPORT}\` is in ${wired.path}.`);
|
|
436
|
+
console.log(` That one import carries every ADS token: colors, typography, and the`);
|
|
437
|
+
console.log(` animation curves/speeds.`);
|
|
438
|
+
} else {
|
|
439
|
+
console.log(bar);
|
|
440
|
+
console.log(`⚠ ACTION REQUIRED — ADS styles are NOT imported yet.`);
|
|
441
|
+
console.log(``);
|
|
442
|
+
console.log(` Nothing will be themed until you add this to your global stylesheet,`);
|
|
443
|
+
console.log(` immediately AFTER the tailwindcss import (the order is load-bearing):`);
|
|
444
|
+
console.log(``);
|
|
445
|
+
console.log(` @import "tailwindcss";`);
|
|
446
|
+
console.log(` ${STYLE_IMPORT}`);
|
|
447
|
+
console.log(``);
|
|
448
|
+
console.log(` Without it NO tokens load — colors, typography, and every animation`);
|
|
449
|
+
console.log(` curve/speed will be missing.`);
|
|
450
|
+
console.log(bar);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// Surface any non-styles manual step (e.g. the layout <Providers> wrap) too —
|
|
454
|
+
// the styles step is already covered by the block above.
|
|
455
|
+
const otherManual = edits.filter((e) => e.type === "manual" && !/styles\.css/.test(e.title));
|
|
456
|
+
if (otherManual.length) {
|
|
457
|
+
console.log(`\n Remaining manual step(s):`);
|
|
458
|
+
for (const m of otherManual) console.log(` • ${m.title}`);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
console.log(`\n Then import components: \`import { Button } from "${PKG}";\``);
|
|
462
|
+
}
|
|
463
|
+
|
|
291
464
|
function main() {
|
|
292
465
|
const cmd = process.argv[2];
|
|
293
466
|
const cwd = process.cwd();
|
|
@@ -301,19 +474,36 @@ function main() {
|
|
|
301
474
|
|
|
302
475
|
if (edits.length === 0) {
|
|
303
476
|
console.log(`${PKG} init: nothing to do — already configured.`);
|
|
304
|
-
|
|
477
|
+
} else {
|
|
478
|
+
console.log(`${PKG} init: applying ${edits.length} edit(s)…`);
|
|
479
|
+
for (const edit of edits) applyEdit(cwd, edit);
|
|
480
|
+
console.log(`\n${PKG} init: done.`);
|
|
305
481
|
}
|
|
306
482
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
483
|
+
// Always verify + summarize the load-bearing styles import (fixes #2: a
|
|
484
|
+
// deferred/missed styles import can no longer scroll past unnoticed).
|
|
485
|
+
printSummary(cwd, edits);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* True when this file is the process entry point (keeps planInit importable
|
|
490
|
+
* without triggering the applier). Compares REAL filesystem paths on both sides:
|
|
491
|
+
* npm installs the bin as a symlink (node_modules/.bin/ads -> …/ads-init.mjs),
|
|
492
|
+
* so process.argv[1] is the symlink while import.meta.url is realpath-resolved —
|
|
493
|
+
* a raw URL/string compare mismatches and `npx @actioneer/ads init` silently
|
|
494
|
+
* no-ops for every consumer. realpath'ing both sides also makes install paths
|
|
495
|
+
* with spaces or non-ASCII compare correctly.
|
|
496
|
+
*/
|
|
497
|
+
function invokedAsCli() {
|
|
498
|
+
const entry = process.argv[1];
|
|
499
|
+
if (!entry) return false;
|
|
500
|
+
try {
|
|
501
|
+
return fs.realpathSync(entry) === fs.realpathSync(fileURLToPath(import.meta.url));
|
|
502
|
+
} catch {
|
|
503
|
+
return false;
|
|
504
|
+
}
|
|
310
505
|
}
|
|
311
506
|
|
|
312
|
-
|
|
313
|
-
// Compare via pathToFileURL so an install path with spaces or non-ASCII (e.g.
|
|
314
|
-
// "/Users/My Name/…") still matches — import.meta.url is percent-encoded, so a
|
|
315
|
-
// raw `file://${process.argv[1]}` concat would silently fail to match and the
|
|
316
|
-
// CLI would no-op.
|
|
317
|
-
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
507
|
+
if (invokedAsCli()) {
|
|
318
508
|
main();
|
|
319
509
|
}
|
package/llms.txt
CHANGED
|
@@ -622,3 +622,132 @@ ADS targets landscape tablet (1024) → laptop (1440) → wide display (1920+);
|
|
|
622
622
|
- [VoiceVariant] — TypeScript type
|
|
623
623
|
- [useReasoning] — React hook
|
|
624
624
|
- [Tool] — utility
|
|
625
|
+
|
|
626
|
+
### Chat
|
|
627
|
+
|
|
628
|
+
- [ACTIONEER_FILE_ACCEPT] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
629
|
+
- [AssistantActionBar] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
630
|
+
- [AssistantMessage] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
631
|
+
- [AssistantRuntimeProvider] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
632
|
+
- [AttachmentPrimitive] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
633
|
+
- [BranchPicker] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
634
|
+
- [Composer] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
635
|
+
- [ComposerAddAttachment] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
636
|
+
- [ComposerAddDocument] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
637
|
+
- [ComposerAddImage] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
638
|
+
- [ComposerAttachments] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
639
|
+
- [ComposerContextProvider] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
640
|
+
- [ComposerDeepResearch] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
641
|
+
- [ComposerHarness] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
642
|
+
- [ComposerPlaceholdersProvider] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
643
|
+
- [ComposerPrimitive] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
644
|
+
- [ComposerQuotePreview] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
645
|
+
- [ComposerQuotePreviewDismiss] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
646
|
+
- [ComposerQuotePreviewIcon] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
647
|
+
- [ComposerQuotePreviewRoot] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
648
|
+
- [ComposerQuotePreviewText] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
649
|
+
- [ComposerTriggerPopover] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
650
|
+
- [CONTEXT_MIME] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
651
|
+
- [DeepResearchProvider] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
652
|
+
- [DirectiveText] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
653
|
+
- [EditComposer] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
654
|
+
- [EMPTY_COMPONENTS] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
655
|
+
- [ErrorRoot] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
656
|
+
- [ErrorText] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
657
|
+
- [File] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
658
|
+
- [FileDownload] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
659
|
+
- [FileIconDisplay] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
660
|
+
- [FileName] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
661
|
+
- [FileRoot] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
662
|
+
- [FileSize] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
663
|
+
- [FollowUpSuggestion] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
664
|
+
- [HARNESS_MIME] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
665
|
+
- [Image] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
666
|
+
- [ImageActions] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
667
|
+
- [ImageContentFilterError] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
668
|
+
- [ImageFilename] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
669
|
+
- [ImageGenerating] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
670
|
+
- [ImagePreview] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
671
|
+
- [ImageRoot] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
672
|
+
- [ImageZoom] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
673
|
+
- [MarkdownText] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
674
|
+
- [MessageError] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
675
|
+
- [MessagePrimitive] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
676
|
+
- [MessageTiming] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
677
|
+
- [OpenUiLibraryProvider] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
678
|
+
- [QuoteBlock] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
679
|
+
- [QuoteBlockIcon] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
680
|
+
- [QuoteBlockRoot] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
681
|
+
- [QuoteBlockText] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
682
|
+
- [RenderAnswerToolUI] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
683
|
+
- [SelectionToolbar] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
684
|
+
- [SelectionToolbarCopy] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
685
|
+
- [SelectionToolbarPrimitive] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
686
|
+
- [SelectionToolbarQuote] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
687
|
+
- [SelectionToolbarRoot] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
688
|
+
- [SmartMessageText] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
689
|
+
- [Source] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
690
|
+
- [SourceIcon] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
691
|
+
- [Sources] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
692
|
+
- [SourceTitle] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
693
|
+
- [Thread] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
694
|
+
- [ThreadFollowupSuggestions] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
695
|
+
- [ThreadMessage] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
696
|
+
- [ThreadPrimitive] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
697
|
+
- [ThreadSuggestionItem] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
698
|
+
- [ThreadSuggestions] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
699
|
+
- [ToolFallback] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
700
|
+
- [ToolFallbackApproval] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
701
|
+
- [ToolFallbackArgs] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
702
|
+
- [ToolFallbackContent] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
703
|
+
- [ToolFallbackError] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
704
|
+
- [ToolFallbackResult] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
705
|
+
- [ToolFallbackRoot] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
706
|
+
- [ToolFallbackTrigger] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
707
|
+
- [ToolGroup] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
708
|
+
- [ToolGroupContent] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
709
|
+
- [ToolGroupRoot] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
710
|
+
- [ToolGroupTrigger] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
711
|
+
- [TooltipIconButton] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
712
|
+
- [UserActionBar] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
713
|
+
- [UserMessage] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
714
|
+
- [UserMessageAttachments] — component [docs](https://ads.actioneer.dev/#/demo/ask)
|
|
715
|
+
- [ChatModelAdapter] — TypeScript type
|
|
716
|
+
- [ContextNode] — TypeScript type
|
|
717
|
+
- [CreateDirectiveTextOptions] — TypeScript type
|
|
718
|
+
- [DeepResearchState] — TypeScript type
|
|
719
|
+
- [FileRootProps] — TypeScript type
|
|
720
|
+
- [FollowUpSuggestionProps] — TypeScript type
|
|
721
|
+
- [ImageActionsProps] — TypeScript type
|
|
722
|
+
- [ImageRootProps] — TypeScript type
|
|
723
|
+
- [LocalRuntimeOptions] — TypeScript type
|
|
724
|
+
- [SourceProps] — TypeScript type
|
|
725
|
+
- [StageUsageHandler] — TypeScript type
|
|
726
|
+
- [ThreadComponents] — TypeScript type
|
|
727
|
+
- [ThreadGroupPart] — TypeScript type
|
|
728
|
+
- [ThreadMessageLike] — TypeScript type
|
|
729
|
+
- [ThreadProps] — TypeScript type
|
|
730
|
+
- [ToolCallMessagePartProps] — TypeScript type
|
|
731
|
+
- [ToolFallbackRootProps] — TypeScript type
|
|
732
|
+
- [ToolGroupRootProps] — TypeScript type
|
|
733
|
+
- [TooltipIconButtonProps] — TypeScript type
|
|
734
|
+
- [useAssistantRuntime] — React hook
|
|
735
|
+
- [useAuiState] — React hook
|
|
736
|
+
- [useLocalRuntime] — React hook
|
|
737
|
+
- [ActioneerFileAttachmentAdapter] — utility
|
|
738
|
+
- [ComposerAddContext] — utility
|
|
739
|
+
- [CompositeAttachmentAdapter] — utility
|
|
740
|
+
- [ContextAttachmentAdapter] — utility
|
|
741
|
+
- [createDirectiveText] — utility
|
|
742
|
+
- [fileVariants] — utility
|
|
743
|
+
- [formatFileSize] — utility
|
|
744
|
+
- [getBase64Size] — utility
|
|
745
|
+
- [getMimeTypeIcon] — utility
|
|
746
|
+
- [HarnessAttachmentAdapter] — utility
|
|
747
|
+
- [imageVariants] — utility
|
|
748
|
+
- [isNewChatView] — utility
|
|
749
|
+
- [makeAssistantToolUI] — utility
|
|
750
|
+
- [SimpleImageAttachmentAdapter] — utility
|
|
751
|
+
- [sourceVariants] — utility
|
|
752
|
+
- [ThreadComponentsContext] — utility
|
|
753
|
+
- [toolGroupVariants] — utility
|