@stnd/launcher 1.0.0 → 1.0.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/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # @stnd/launcher
2
+
3
+ ## 1.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Auto-bumped @stnd/launcher due to modified code.
8
+ - Updated dependencies
9
+ - Updated dependencies
10
+ - Updated dependencies
11
+ - Updated dependencies
12
+ - Updated dependencies
13
+ - Updated dependencies
14
+ - @stnd/account@0.1.2
15
+ - @stnd/client@0.5.1
16
+ - @stnd/icon@0.2.1
17
+ - @stnd/log@0.5.1
18
+ - @stnd/store@0.5.1
19
+ - @stnd/ui@0.5.2
package/Launcher.svelte CHANGED
@@ -25,7 +25,7 @@
25
25
  import { get } from "svelte/store";
26
26
  import { fade, blurFade, scaleBlurFade } from "@stnd/ui/transitions.js";
27
27
  import { quintOut } from "svelte/easing";
28
- import { inject } from "@stnd/store";
28
+ import { inject, has } from "@stnd/store";
29
29
  import { registerShortcut } from "@stnd/client/keyboard";
30
30
  import Log from "@stnd/log";
31
31
 
@@ -36,6 +36,15 @@
36
36
  // Props exist only for backward compat or one-off overrides.
37
37
  let { WelcomeView = null, load = null, hideLogin = false } = $props();
38
38
 
39
+ // Login only makes sense if an app actually wired up authentication —
40
+ // otherwise this is the same assumption-bleed as a hardcoded "ask AI"
41
+ // item: a button pointing at a "::login" view that doesn't exist for
42
+ // apps with no account system at all (presence-of-data = mode).
43
+ let hasAuthProvider = $derived(
44
+ has("user") ||
45
+ (typeof window !== "undefined" && !!window.__INITIAL_USER__),
46
+ );
47
+
39
48
  // Check global window variable as fallback (set via window.__HIDE_LAUNCHER_LOGIN__)
40
49
  let shouldHideLogin = $derived(
41
50
  hideLogin ||
@@ -569,9 +578,17 @@
569
578
  </header>
570
579
 
571
580
  <!-- Body -->
581
+ <!-- Deliberately NOT a `.rhythm` container. Rhythm is a prose-flow system:
582
+ it spaces sibling blocks in a document. This is chrome, and its child
583
+ is a self-contained view. As a rhythm container it reached into view
584
+ internals at any depth (the base rule is unscoped by design — see the
585
+ audit note in _standard-05-rhythm.scss), handing margins to markup
586
+ that never asked for them, and forced `display: flow-root` on the
587
+ shell. Views that want prose flow declare `rhythm` themselves; ten of
588
+ the twelve already did. -->
572
589
  <div
573
590
  bind:this={itemsContainer}
574
- class="std-launcher-body rhythm mt-0 {coreWindowSize.height}"
591
+ class="std-launcher-body mt-0 {coreWindowSize.height}"
575
592
  >
576
593
  {#if ActiveViewComponent}
577
594
  <div
@@ -680,7 +697,7 @@
680
697
  {currentUser.name || currentUser.username || currentUser.email}
681
698
  </span>
682
699
  </div>
683
- {:else if !shouldHideLogin}
700
+ {:else if hasAuthProvider && !shouldHideLogin}
684
701
  <button
685
702
  class="no-decoration smaller ghost text-subtle"
686
703
  onclick={() => launcherView("::login")}
@@ -894,18 +911,31 @@
894
911
  .std-launcher-body {
895
912
  overflow-y: auto;
896
913
  transition: all var(--transition-fast);
914
+
915
+ /* The shell↔view contract. The shell insets every view by this much; a view
916
+ that wants to reach the frame (a full-bleed horizon, an input bar sitting
917
+ on the edge) cancels it with `margin: calc(var(--launcher-pad) * -1)`.
918
+ Naming it is the point: views used to hardcode `var(--space)` to undo a
919
+ padding they could only guess, so the two drifted apart and content got
920
+ clipped at the frame. One name, one source of truth. */
921
+ --launcher-pad: var(--space);
897
922
  }
898
923
 
899
924
  .std-launcher-view > :first-child {
900
- padding: var(--space);
925
+ padding: var(--launcher-pad);
901
926
  }
902
927
 
928
+ /* Height is bounded at BOTH ends on purpose. A pure `vh` cap measured the
929
+ window while the content measured itself — on a short viewport the welcome
930
+ view (~16rem) was cut off mid-descender, on a tall one the panel floated in
931
+ empty space. The rem floor guarantees the common views fit; the vh term
932
+ keeps it proportional; the rem ceiling stops it swallowing a large screen. */
903
933
  .std-launcher-body.standard {
904
- max-height: 30vh;
934
+ max-height: clamp(17rem, 40vh, 26rem);
905
935
  }
906
936
 
907
937
  .std-launcher-body.large {
908
- max-height: 70vh;
938
+ max-height: clamp(24rem, 70vh, 44rem);
909
939
  }
910
940
 
911
941
  .std-launcher-body.fill {
package/README.md CHANGED
@@ -2,21 +2,24 @@
2
2
  title: "@stnd/launcher"
3
3
  aliases: []
4
4
  created: 2026-07-05 07:42
5
- modified: 2026-07-05 19:23
5
+ modified: 2026-09-16T17:28:40.341Z
6
6
  last_audited: 2026-07-14
7
7
  audit_interval_days: 90
8
8
  next_audit: 2026-10-12
9
9
  audit_priority: 3
10
10
  maturity: tree
11
11
  mode: read
12
- publish: false
12
+ publish: true
13
13
  status: active
14
14
  tags:
15
15
  - package
16
16
  - stnd
17
17
  theme: kernel
18
18
  type: package
19
- visibility: private
19
+ visibility: public
20
+ garden-url: https://standard.garden/@francis/readme
21
+ garden-short: https://stnd.gd/wAgx4e
22
+ permalink: readme
20
23
  ---
21
24
 
22
25
  # @[stnd](../README)/launcher
package/launcher.ts CHANGED
@@ -167,7 +167,7 @@ export function register(
167
167
  const errorMsg =
168
168
  `[Launcher] Fatal Collision: Trigger "${trigger}" already registered by "${r.commands[existingIndex].moduleId || "core"}". ` +
169
169
  `Attempting to register again from "${meta.moduleId || "unknown"}". ` +
170
- `See: https://stnd.build/manual/5-reference/launcher-trigger-collision`;
170
+ `See: https://stnd.build/manual/diagnostic/launcher-trigger-collision`;
171
171
  log.error(errorMsg);
172
172
  throw new Error(errorMsg);
173
173
  }
@@ -415,18 +415,20 @@ export function computeMatches(
415
415
 
416
416
  const finalMatches = [...matches, ...searchResults];
417
417
 
418
- // Si une requête de recherche textuelle est saisie, injecter l'option de poser une question à l'IA du jardin
418
+ // An "ask AI" fallback item, shown first for any non-command query — this
419
+ // package has no opinion on what "AI" means, or whether an app has one.
420
+ // An app that wants it provides a builder via the runtime store (see
421
+ // @stnd/store), the same pattern `search` already uses: default is a
422
+ // no-op that yields nothing, so apps that don't opt in show nothing.
419
423
  if (query.trim() && !isCommand) {
420
- const aiPromptItem: LauncherResult = {
421
- title: "Demander à l'IA du Jardin",
422
- desc: `Obtenir une réponse basée sur vos notes pour : "${query}"`,
423
- icon: "ph:sparkle",
424
- type: "view",
425
- trigger: "::ask",
426
- action: () => launcherView("::ask", { question: query }),
427
- };
428
- // Placer l'option IA en premier
429
- finalMatches.unshift(aiPromptItem);
424
+ const buildAskPrompt = inject(
425
+ "askPrompt",
426
+ (_query: string): LauncherResult | null => null,
427
+ );
428
+ const aiPromptItem = buildAskPrompt(query);
429
+ if (aiPromptItem) {
430
+ finalMatches.unshift(aiPromptItem);
431
+ }
430
432
  }
431
433
 
432
434
  return finalMatches;
package/package.json CHANGED
@@ -1,6 +1,9 @@
1
1
  {
2
2
  "name": "@stnd/launcher",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
4
7
  "type": "module",
5
8
  "svelte": "./Launcher.svelte",
6
9
  "main": "launcher.ts",
@@ -15,11 +18,14 @@
15
18
  "./*": "./*"
16
19
  },
17
20
  "dependencies": {
18
- "svelte": "5.56.4",
19
- "wrangler": "^4.105.0",
20
- "@stnd/icon": "0.2.0",
21
- "@stnd/log": "0.5.0",
22
- "@stnd/store": "0.5.0"
21
+ "svelte": "5.57.0",
22
+ "wrangler": "^4.129.0",
23
+ "@stnd/account": "0.1.2",
24
+ "@stnd/client": "0.5.1",
25
+ "@stnd/icon": "0.2.1",
26
+ "@stnd/log": "0.5.1",
27
+ "@stnd/store": "0.5.1",
28
+ "@stnd/ui": "0.5.2"
23
29
  },
24
30
  "peerDependencies": {
25
31
  "astro": ">=5.0.0"