@actioneer/ads 0.2.0 → 0.2.1

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 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
- * Per the DES-13 testing decision, the write-plan is exercised end-to-end by a
21
- * manual run rather than dedicated unit tests this pass.
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 { pathToFileURL } from "node:url";
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
- edits.push({ type: "install", title: `install ${missing.join(", ")}`, packages: missing });
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"`.
@@ -230,6 +270,12 @@ function readRepoState(cwd) {
230
270
  const pkg = pkgRaw ? JSON.parse(pkgRaw) : {};
231
271
  const dependencies = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };
232
272
 
273
+ const packageManager = detectPackageManager({
274
+ packageManagerField: pkg.packageManager ?? null,
275
+ userAgent: process.env.npm_config_user_agent ?? null,
276
+ lockfiles: LOCKFILES.filter((f) => fs.existsSync(path.join(cwd, f))),
277
+ });
278
+
233
279
  const globalCssPath = CANDIDATE_CSS.find((p) => fs.existsSync(path.join(cwd, p))) ?? null;
234
280
  const layoutPath = CANDIDATE_LAYOUT.find((p) => fs.existsSync(path.join(cwd, p))) ?? null;
235
281
 
@@ -246,6 +292,7 @@ function readRepoState(cwd) {
246
292
  layoutContent: layoutPath ? read(layoutPath) : null,
247
293
  hasAdsLintConfig:
248
294
  fs.existsSync(path.join(cwd, "ads-lint.config.mjs")) || fs.existsSync(path.join(cwd, "ads-lint.config.js")),
295
+ packageManager,
249
296
  _existing,
250
297
  };
251
298
  }
@@ -254,8 +301,9 @@ function applyEdit(cwd, edit) {
254
301
  const abs = edit.path ? path.join(cwd, edit.path) : null;
255
302
  switch (edit.type) {
256
303
  case "install": {
257
- console.log(` → npm install ${edit.packages.join(" ")}`);
258
- execFileSync("npm", ["install", ...edit.packages], { cwd, stdio: "inherit" });
304
+ const [cmd, args] = installCommand(edit.manager ?? "npm", edit.packages);
305
+ console.log(` → ${cmd} ${args.join(" ")}`);
306
+ execFileSync(cmd, args, { cwd, stdio: "inherit" });
259
307
  return;
260
308
  }
261
309
  case "write-file": {
@@ -309,11 +357,25 @@ function main() {
309
357
  console.log(`\n${PKG} init: done. Import components with \`import { Button } from "${PKG}";\``);
310
358
  }
311
359
 
312
- // Only run the applier when invoked as a CLI (keeps planInit importable/pure).
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) {
360
+ /**
361
+ * True when this file is the process entry point (keeps planInit importable
362
+ * without triggering the applier). Compares REAL filesystem paths on both sides:
363
+ * npm installs the bin as a symlink (node_modules/.bin/ads -> …/ads-init.mjs),
364
+ * so process.argv[1] is the symlink while import.meta.url is realpath-resolved —
365
+ * a raw URL/string compare mismatches and `npx @actioneer/ads init` silently
366
+ * no-ops for every consumer. realpath'ing both sides also makes install paths
367
+ * with spaces or non-ASCII compare correctly.
368
+ */
369
+ function invokedAsCli() {
370
+ const entry = process.argv[1];
371
+ if (!entry) return false;
372
+ try {
373
+ return fs.realpathSync(entry) === fs.realpathSync(fileURLToPath(import.meta.url));
374
+ } catch {
375
+ return false;
376
+ }
377
+ }
378
+
379
+ if (invokedAsCli()) {
318
380
  main();
319
381
  }
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