sh3-core 0.5.2 → 0.5.5
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.
Potentially problematic release.
This version of sh3-core might be problematic. Click here for more details.
- package/dist/Shell.svelte +6 -3
- package/dist/admin/AuthSettingsView.svelte +105 -0
- package/dist/admin/AuthSettingsView.svelte.d.ts +3 -0
- package/dist/admin/SystemView.svelte +73 -0
- package/dist/admin/SystemView.svelte.d.ts +3 -0
- package/dist/admin/UsersView.svelte +189 -0
- package/dist/admin/UsersView.svelte.d.ts +3 -0
- package/dist/admin/adminApp.d.ts +7 -0
- package/dist/admin/adminApp.js +24 -0
- package/dist/admin/adminShard.svelte.d.ts +4 -0
- package/dist/admin/adminShard.svelte.js +52 -0
- package/dist/api.d.ts +2 -1
- package/dist/api.js +1 -1
- package/dist/apps/lifecycle.d.ts +6 -1
- package/dist/apps/lifecycle.js +28 -4
- package/dist/apps/registry.svelte.d.ts +5 -2
- package/dist/apps/registry.svelte.js +6 -7
- package/dist/apps/types.d.ts +13 -0
- package/dist/auth/GuestBanner.svelte +144 -0
- package/dist/auth/GuestBanner.svelte.d.ts +3 -0
- package/dist/auth/SignInWall.svelte +213 -0
- package/dist/auth/SignInWall.svelte.d.ts +8 -0
- package/dist/auth/auth.svelte.d.ts +42 -31
- package/dist/auth/auth.svelte.js +106 -89
- package/dist/auth/index.d.ts +2 -1
- package/dist/auth/index.js +1 -1
- package/dist/auth/types.d.ts +41 -0
- package/dist/auth/types.js +6 -0
- package/dist/build.js +70 -16
- package/dist/createShell.d.ts +2 -2
- package/dist/createShell.js +78 -33
- package/dist/diagnostic/DiagnosticPromptModal.svelte +1 -1
- package/dist/host-entry.d.ts +2 -1
- package/dist/host-entry.js +2 -2
- package/dist/host.d.ts +0 -2
- package/dist/host.js +11 -25
- package/dist/layout/DragPreview.svelte +1 -1
- package/dist/overlays/ModalFrame.svelte +1 -1
- package/dist/overlays/PopupFrame.svelte +1 -1
- package/dist/overlays/ToastItem.svelte +1 -1
- package/dist/primitives/TabbedPanel.svelte +1 -1
- package/dist/registry/installer.js +0 -2
- package/dist/shards/activate.svelte.d.ts +13 -6
- package/dist/shards/activate.svelte.js +19 -8
- package/dist/shards/types.d.ts +11 -0
- package/dist/shell-shard/ShellHome.svelte +32 -118
- package/dist/store/InstalledView.svelte +7 -7
- package/dist/store/StoreView.svelte +16 -16
- package/dist/store/storeApp.js +1 -1
- package/dist/store/storeShard.svelte.js +5 -4
- package/dist/tokens.css +14 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/host.js
CHANGED
|
@@ -22,10 +22,12 @@ import { shellShard } from './shell-shard/shellShard.svelte';
|
|
|
22
22
|
import { storeShard } from './store/storeShard.svelte';
|
|
23
23
|
import { __setBackend } from './state/zones.svelte';
|
|
24
24
|
import { loadInstalledPackages } from './registry/installer';
|
|
25
|
-
import {
|
|
25
|
+
import { setLocalOwner } from './auth/index';
|
|
26
26
|
import { storeApp } from './store/storeApp';
|
|
27
27
|
import { diagnosticShard } from './diagnostic/diagnosticShard.svelte';
|
|
28
28
|
import { diagnosticApp } from './diagnostic/diagnosticApp';
|
|
29
|
+
import { adminShard } from './admin/adminShard.svelte';
|
|
30
|
+
import { adminApp } from './admin/adminApp';
|
|
29
31
|
export { __setBackend };
|
|
30
32
|
export { setLocalOwner };
|
|
31
33
|
export { __setTenantId, __setDocumentBackend } from './documents/config';
|
|
@@ -35,43 +37,27 @@ export function registerShard(shard) {
|
|
|
35
37
|
export { registerApp };
|
|
36
38
|
export async function bootstrap(config) {
|
|
37
39
|
const exShards = new Set(config === null || config === void 0 ? void 0 : config.excludeShards);
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// cannot claim reserved IDs like __shell__ or sh3-store.
|
|
41
|
-
const frameworkShards = [shellShard, storeShard, diagnosticShard];
|
|
40
|
+
// 1. Framework-owned shards
|
|
41
|
+
const frameworkShards = [shellShard, storeShard, diagnosticShard, adminShard];
|
|
42
42
|
for (const shard of frameworkShards) {
|
|
43
43
|
if (!exShards.has(shard.manifest.id)) {
|
|
44
44
|
registerShardInternal(shard);
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
-
// 2. Framework-shipped
|
|
48
|
-
const frameworkApps = [storeApp, diagnosticApp];
|
|
47
|
+
// 2. Framework-shipped apps
|
|
48
|
+
const frameworkApps = [storeApp, diagnosticApp, adminApp];
|
|
49
49
|
for (const app of frameworkApps) {
|
|
50
|
-
|
|
51
|
-
registerApp(app);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
// 3. Auth — if the host already called setLocalOwner() (Tauri / dev),
|
|
55
|
-
// skip server verification. Otherwise verify the stored admin key
|
|
56
|
-
// against the server (3s timeout, fails open).
|
|
57
|
-
if (!isAdmin()) {
|
|
58
|
-
await initAuth();
|
|
50
|
+
registerApp(app);
|
|
59
51
|
}
|
|
60
|
-
//
|
|
61
|
-
// from IndexedDB. Runs after framework shards but before activation
|
|
62
|
-
// so installed packages participate in the self-starting pass.
|
|
52
|
+
// 3. Load any packages installed in a previous session from IndexedDB
|
|
63
53
|
await loadInstalledPackages();
|
|
64
|
-
//
|
|
65
|
-
// field is defined). Iteration order is insertion order, which
|
|
66
|
-
// puts __shell__ first and glob-discovered shards after — exactly
|
|
67
|
-
// what we need.
|
|
54
|
+
// 4. Activate every self-starting shard
|
|
68
55
|
for (const [id, shard] of registeredShards) {
|
|
69
56
|
if (shard.autostart) {
|
|
70
57
|
await activateShard(id);
|
|
71
58
|
}
|
|
72
59
|
}
|
|
73
|
-
//
|
|
74
|
-
// registered app, launch it; otherwise leave the shell on home.
|
|
60
|
+
// 5. Read the last-active app from the user zone
|
|
75
61
|
const lastId = readLastApp();
|
|
76
62
|
if (lastId && registeredApps.has(lastId)) {
|
|
77
63
|
await launchApp(lastId);
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
background: var(--shell-grad-bg-elevated, var(--shell-bg-elevated));
|
|
50
50
|
color: var(--shell-fg);
|
|
51
51
|
border: 1px solid var(--shell-accent);
|
|
52
|
-
border-radius:
|
|
52
|
+
border-radius: var(--shell-radius-sm);
|
|
53
53
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
|
|
54
54
|
font-size: 12px;
|
|
55
55
|
font-family: var(--shell-font-ui);
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
background: var(--shell-grad-bg-elevated, var(--shell-bg-elevated));
|
|
77
77
|
color: var(--shell-fg);
|
|
78
78
|
border: 1px solid var(--shell-border-strong);
|
|
79
|
-
border-radius:
|
|
79
|
+
border-radius: var(--shell-radius);
|
|
80
80
|
min-width: 320px;
|
|
81
81
|
max-width: min(640px, 90vw);
|
|
82
82
|
max-height: 90vh;
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
background: var(--shell-grad-bg-elevated, var(--shell-bg-elevated));
|
|
77
77
|
color: var(--shell-fg);
|
|
78
78
|
border: 1px solid var(--shell-border-strong);
|
|
79
|
-
border-radius:
|
|
79
|
+
border-radius: var(--shell-radius-sm);
|
|
80
80
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
|
|
81
81
|
min-width: 120px;
|
|
82
82
|
outline: none;
|
|
@@ -97,8 +97,6 @@ export async function installPackage(bundle, meta) {
|
|
|
97
97
|
registerApp(app);
|
|
98
98
|
}
|
|
99
99
|
catch (err) {
|
|
100
|
-
// Registration failure (e.g. duplicate id) -- the package is persisted
|
|
101
|
-
// but not usable until reload. Log and continue.
|
|
102
100
|
console.warn(`[sh3] Package "${meta.id}" installed but registration failed (will retry on next boot):`, err instanceof Error ? err.message : err);
|
|
103
101
|
hotLoaded = false;
|
|
104
102
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Shard } from './types';
|
|
1
|
+
import type { Shard, ShardContext } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* Reactive registry of every shard known to the host. Keys are shard ids.
|
|
4
4
|
* Populated once at boot by the glob-discovery loop in main.ts (through
|
|
@@ -10,12 +10,14 @@ import type { Shard } from './types';
|
|
|
10
10
|
export declare const registeredShards: Map<string, Shard>;
|
|
11
11
|
export declare const activeShards: Map<string, Shard>;
|
|
12
12
|
/**
|
|
13
|
-
* Register a shard with the framework so it can later be
|
|
14
|
-
* the shard in `registeredShards` but does not run
|
|
15
|
-
* at app launch (or
|
|
13
|
+
* Register (or re-register) a shard with the framework so it can later be
|
|
14
|
+
* activated. Records the shard in `registeredShards` but does not run
|
|
15
|
+
* `activate` — that happens at app launch (or for self-starting shards).
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* If a shard with the same id already exists it is silently replaced,
|
|
18
|
+
* which is the expected path during package updates. If the old shard was
|
|
19
|
+
* active it is deactivated first so the new version can be cleanly
|
|
20
|
+
* activated on next launch.
|
|
19
21
|
*/
|
|
20
22
|
export declare function registerShard(shard: Shard): void;
|
|
21
23
|
/**
|
|
@@ -43,3 +45,8 @@ export declare function deactivateShard(id: string): void;
|
|
|
43
45
|
* @param id - The `ShardManifest.id` to check.
|
|
44
46
|
*/
|
|
45
47
|
export declare function isActive(id: string): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Return the ShardContext for an active shard, or undefined if not active.
|
|
50
|
+
* Used by lifecycle.ts to pass context to `shard.resume()`.
|
|
51
|
+
*/
|
|
52
|
+
export declare function getShardContext(id: string): ShardContext | undefined;
|
|
@@ -39,17 +39,19 @@ export const registeredShards = $state(new Map());
|
|
|
39
39
|
const active = new Map();
|
|
40
40
|
export const activeShards = $state(new Map());
|
|
41
41
|
/**
|
|
42
|
-
* Register a shard with the framework so it can later be
|
|
43
|
-
* the shard in `registeredShards` but does not run
|
|
44
|
-
* at app launch (or
|
|
42
|
+
* Register (or re-register) a shard with the framework so it can later be
|
|
43
|
+
* activated. Records the shard in `registeredShards` but does not run
|
|
44
|
+
* `activate` — that happens at app launch (or for self-starting shards).
|
|
45
45
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
46
|
+
* If a shard with the same id already exists it is silently replaced,
|
|
47
|
+
* which is the expected path during package updates. If the old shard was
|
|
48
|
+
* active it is deactivated first so the new version can be cleanly
|
|
49
|
+
* activated on next launch.
|
|
48
50
|
*/
|
|
49
51
|
export function registerShard(shard) {
|
|
50
52
|
const id = shard.manifest.id;
|
|
51
|
-
if (registeredShards.has(id)) {
|
|
52
|
-
|
|
53
|
+
if (registeredShards.has(id) && activeShards.has(id)) {
|
|
54
|
+
deactivateShard(id);
|
|
53
55
|
}
|
|
54
56
|
registeredShards.set(id, shard);
|
|
55
57
|
}
|
|
@@ -73,7 +75,7 @@ export async function activateShard(id) {
|
|
|
73
75
|
// and is now being required by an app). Idempotent — no error.
|
|
74
76
|
return;
|
|
75
77
|
}
|
|
76
|
-
const entry = { shard, viewIds: new Set(), cleanupFns: [] };
|
|
78
|
+
const entry = { shard, ctx: undefined, viewIds: new Set(), cleanupFns: [] };
|
|
77
79
|
// envState holds the reactive env data for this shard.
|
|
78
80
|
// Must be declared with $state at variable declaration time (Svelte 5 rule).
|
|
79
81
|
const envState = $state({
|
|
@@ -122,6 +124,7 @@ export async function activateShard(id) {
|
|
|
122
124
|
? createZoneManager()
|
|
123
125
|
: undefined,
|
|
124
126
|
};
|
|
127
|
+
entry.ctx = ctx;
|
|
125
128
|
active.set(id, entry);
|
|
126
129
|
activeShards.set(id, shard);
|
|
127
130
|
await shard.activate(ctx);
|
|
@@ -173,3 +176,11 @@ export function deactivateShard(id) {
|
|
|
173
176
|
export function isActive(id) {
|
|
174
177
|
return active.has(id);
|
|
175
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* Return the ShardContext for an active shard, or undefined if not active.
|
|
181
|
+
* Used by lifecycle.ts to pass context to `shard.resume()`.
|
|
182
|
+
*/
|
|
183
|
+
export function getShardContext(id) {
|
|
184
|
+
var _a;
|
|
185
|
+
return (_a = active.get(id)) === null || _a === void 0 ? void 0 : _a.ctx;
|
|
186
|
+
}
|
package/dist/shards/types.d.ts
CHANGED
|
@@ -193,4 +193,15 @@ export interface Shard {
|
|
|
193
193
|
autostart?(ctx: ShardContext): void | Promise<void>;
|
|
194
194
|
/** Optional cleanup hook called when the shard is deactivated. Release timers, subscriptions, and external resources here. */
|
|
195
195
|
deactivate?(): void | Promise<void>;
|
|
196
|
+
/**
|
|
197
|
+
* Called when the owning app is suspended (Home button). The shard
|
|
198
|
+
* remains active; its views and state are preserved. Return `false`
|
|
199
|
+
* (sync or async) to cancel the navigation.
|
|
200
|
+
*/
|
|
201
|
+
suspend?(): void | false | Promise<void | false>;
|
|
202
|
+
/**
|
|
203
|
+
* Called when the owning app resumes from Home. Receives the same
|
|
204
|
+
* `ShardContext` that `activate` received.
|
|
205
|
+
*/
|
|
206
|
+
resume?(ctx: ShardContext): void | Promise<void>;
|
|
196
207
|
}
|
|
@@ -2,37 +2,18 @@
|
|
|
2
2
|
/*
|
|
3
3
|
* Shell home — the view shown when no app is active. Sections:
|
|
4
4
|
* 1. User apps — always visible
|
|
5
|
-
* 2. Admin apps — visible when
|
|
6
|
-
* 3. Elevate prompt — shown when not elevated
|
|
5
|
+
* 2. Admin apps — visible when user has admin role
|
|
7
6
|
*/
|
|
8
7
|
|
|
9
8
|
import { listRegisteredApps, launchApp, isAdmin, VERSION } from '../api';
|
|
10
|
-
import {
|
|
9
|
+
import { logout, isAuthenticated, getUser } from '../auth/index';
|
|
11
10
|
|
|
12
11
|
const apps = $derived(listRegisteredApps());
|
|
13
12
|
const userApps = $derived(apps.filter(m => !m.admin));
|
|
14
13
|
const adminApps = $derived(apps.filter(m => m.admin));
|
|
15
14
|
const elevated = $derived(isAdmin());
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
let elevateError = $state<string | null>(null);
|
|
19
|
-
let elevating = $state(false);
|
|
20
|
-
|
|
21
|
-
async function handleElevate() {
|
|
22
|
-
if (!keyInput.trim() || elevating) return;
|
|
23
|
-
elevating = true;
|
|
24
|
-
elevateError = null;
|
|
25
|
-
const ok = await elevate(keyInput.trim());
|
|
26
|
-
if (!ok) {
|
|
27
|
-
elevateError = 'Invalid API key';
|
|
28
|
-
}
|
|
29
|
-
keyInput = '';
|
|
30
|
-
elevating = false;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function handleDeescalate() {
|
|
34
|
-
deescalate();
|
|
35
|
-
}
|
|
15
|
+
const authenticated = $derived(isAuthenticated());
|
|
16
|
+
const user = $derived(getUser());
|
|
36
17
|
</script>
|
|
37
18
|
|
|
38
19
|
<div class="shell-home">
|
|
@@ -40,9 +21,10 @@
|
|
|
40
21
|
<h1>SH3</h1>
|
|
41
22
|
<span class="shell-home-version">v{VERSION}</span>
|
|
42
23
|
<span class="shell-home-alpha">alpha</span>
|
|
43
|
-
{#if
|
|
44
|
-
<
|
|
45
|
-
|
|
24
|
+
{#if authenticated && user}
|
|
25
|
+
<span class="shell-home-user">{user.displayName}</span>
|
|
26
|
+
<button type="button" class="shell-home-deescalate" onclick={() => logout()}>
|
|
27
|
+
Sign out
|
|
46
28
|
</button>
|
|
47
29
|
{/if}
|
|
48
30
|
</header>
|
|
@@ -70,54 +52,26 @@
|
|
|
70
52
|
</section>
|
|
71
53
|
{/if}
|
|
72
54
|
|
|
73
|
-
{#if elevated}
|
|
74
|
-
{#if adminApps.length > 0}
|
|
75
|
-
<section class="shell-home-section">
|
|
76
|
-
<h2 class="shell-home-section-title">Admin</h2>
|
|
77
|
-
<ul class="shell-home-list">
|
|
78
|
-
{#each adminApps as manifest (manifest.id)}
|
|
79
|
-
<li class="shell-home-entry">
|
|
80
|
-
<div class="shell-home-entry-label">{manifest.label}</div>
|
|
81
|
-
<div class="shell-home-entry-meta">
|
|
82
|
-
{manifest.id} · v{manifest.version}
|
|
83
|
-
</div>
|
|
84
|
-
<button
|
|
85
|
-
type="button"
|
|
86
|
-
class="shell-home-launch"
|
|
87
|
-
onclick={() => launchApp(manifest.id)}
|
|
88
|
-
>
|
|
89
|
-
Launch
|
|
90
|
-
</button>
|
|
91
|
-
</li>
|
|
92
|
-
{/each}
|
|
93
|
-
</ul>
|
|
94
|
-
</section>
|
|
95
|
-
{/if}
|
|
96
|
-
{:else}
|
|
55
|
+
{#if elevated && adminApps.length > 0}
|
|
97
56
|
<section class="shell-home-section">
|
|
98
|
-
<h2 class="shell-home-section-title">Admin
|
|
99
|
-
<
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
</button>
|
|
117
|
-
</form>
|
|
118
|
-
{#if elevateError}
|
|
119
|
-
<div class="shell-home-elevate-error">{elevateError}</div>
|
|
120
|
-
{/if}
|
|
57
|
+
<h2 class="shell-home-section-title">Admin</h2>
|
|
58
|
+
<ul class="shell-home-list">
|
|
59
|
+
{#each adminApps as manifest (manifest.id)}
|
|
60
|
+
<li class="shell-home-entry">
|
|
61
|
+
<div class="shell-home-entry-label">{manifest.label}</div>
|
|
62
|
+
<div class="shell-home-entry-meta">
|
|
63
|
+
{manifest.id} · v{manifest.version}
|
|
64
|
+
</div>
|
|
65
|
+
<button
|
|
66
|
+
type="button"
|
|
67
|
+
class="shell-home-launch"
|
|
68
|
+
onclick={() => launchApp(manifest.id)}
|
|
69
|
+
>
|
|
70
|
+
Launch
|
|
71
|
+
</button>
|
|
72
|
+
</li>
|
|
73
|
+
{/each}
|
|
74
|
+
</ul>
|
|
121
75
|
</section>
|
|
122
76
|
{/if}
|
|
123
77
|
|
|
@@ -203,7 +157,7 @@
|
|
|
203
157
|
padding: 14px 18px;
|
|
204
158
|
background: var(--shell-grad-bg-elevated, var(--shell-bg-elevated));
|
|
205
159
|
border: 1px solid var(--shell-border);
|
|
206
|
-
border-radius:
|
|
160
|
+
border-radius: var(--shell-radius-md);
|
|
207
161
|
}
|
|
208
162
|
.shell-home-entry-label {
|
|
209
163
|
grid-column: 1;
|
|
@@ -223,7 +177,7 @@
|
|
|
223
177
|
background: var(--shell-accent);
|
|
224
178
|
color: var(--shell-bg);
|
|
225
179
|
border: none;
|
|
226
|
-
border-radius:
|
|
180
|
+
border-radius: var(--shell-radius);
|
|
227
181
|
font-weight: 600;
|
|
228
182
|
cursor: pointer;
|
|
229
183
|
}
|
|
@@ -235,7 +189,7 @@
|
|
|
235
189
|
background: transparent;
|
|
236
190
|
color: var(--shell-fg-subtle);
|
|
237
191
|
border: 1px solid var(--shell-border);
|
|
238
|
-
border-radius:
|
|
192
|
+
border-radius: var(--shell-radius);
|
|
239
193
|
cursor: pointer;
|
|
240
194
|
font-size: 12px;
|
|
241
195
|
}
|
|
@@ -243,48 +197,8 @@
|
|
|
243
197
|
color: var(--shell-fg);
|
|
244
198
|
border-color: var(--shell-fg-subtle);
|
|
245
199
|
}
|
|
246
|
-
.shell-home-
|
|
247
|
-
margin: 0 0 12px;
|
|
200
|
+
.shell-home-user {
|
|
248
201
|
font-size: 13px;
|
|
249
|
-
color: var(--shell-fg-
|
|
250
|
-
}
|
|
251
|
-
.shell-home-elevate-form {
|
|
252
|
-
display: flex;
|
|
253
|
-
gap: 8px;
|
|
254
|
-
}
|
|
255
|
-
.shell-home-key-input {
|
|
256
|
-
flex: 1;
|
|
257
|
-
padding: 8px 12px;
|
|
258
|
-
background: var(--shell-grad-bg-elevated, var(--shell-bg-elevated));
|
|
259
|
-
color: var(--shell-fg);
|
|
260
|
-
border: 1px solid var(--shell-border);
|
|
261
|
-
border-radius: 4px;
|
|
262
|
-
font-family: monospace;
|
|
263
|
-
font-size: 13px;
|
|
264
|
-
}
|
|
265
|
-
.shell-home-key-input::placeholder {
|
|
266
|
-
color: var(--shell-fg-muted);
|
|
267
|
-
}
|
|
268
|
-
.shell-home-elevate-btn {
|
|
269
|
-
padding: 8px 16px;
|
|
270
|
-
background: var(--shell-accent);
|
|
271
|
-
color: var(--shell-bg);
|
|
272
|
-
border: none;
|
|
273
|
-
border-radius: 4px;
|
|
274
|
-
font-weight: 600;
|
|
275
|
-
cursor: pointer;
|
|
276
|
-
white-space: nowrap;
|
|
277
|
-
}
|
|
278
|
-
.shell-home-elevate-btn:disabled {
|
|
279
|
-
opacity: 0.6;
|
|
280
|
-
cursor: not-allowed;
|
|
281
|
-
}
|
|
282
|
-
.shell-home-elevate-error {
|
|
283
|
-
margin-top: 8px;
|
|
284
|
-
padding: 6px 10px;
|
|
285
|
-
font-size: 12px;
|
|
286
|
-
color: var(--shell-error, #d32f2f);
|
|
287
|
-
background: color-mix(in srgb, var(--shell-error, #d32f2f) 10%, transparent);
|
|
288
|
-
border-radius: 4px;
|
|
202
|
+
color: var(--shell-fg-subtle);
|
|
289
203
|
}
|
|
290
204
|
</style>
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
|
|
126
126
|
<style>
|
|
127
127
|
.installed-view {
|
|
128
|
-
font-family: var(--shell-font
|
|
128
|
+
font-family: var(--shell-font-ui);
|
|
129
129
|
color: var(--shell-fg, #e0e0e0);
|
|
130
130
|
background: var(--shell-bg, #1e1e1e);
|
|
131
131
|
padding: 16px;
|
|
@@ -149,7 +149,7 @@
|
|
|
149
149
|
background: var(--shell-accent, #007acc);
|
|
150
150
|
color: #fff;
|
|
151
151
|
border: none;
|
|
152
|
-
border-radius:
|
|
152
|
+
border-radius: var(--shell-radius);
|
|
153
153
|
cursor: pointer;
|
|
154
154
|
font-family: inherit;
|
|
155
155
|
font-size: 0.875rem;
|
|
@@ -171,7 +171,7 @@
|
|
|
171
171
|
.installed-item {
|
|
172
172
|
background: var(--shell-input-bg, #2a2a2a);
|
|
173
173
|
border: 1px solid var(--shell-border, #444);
|
|
174
|
-
border-radius:
|
|
174
|
+
border-radius: var(--shell-radius-md);
|
|
175
175
|
padding: 12px 14px;
|
|
176
176
|
display: flex;
|
|
177
177
|
flex-direction: column;
|
|
@@ -189,7 +189,7 @@
|
|
|
189
189
|
.installed-item-badge {
|
|
190
190
|
font-size: 0.6875rem;
|
|
191
191
|
padding: 1px 6px;
|
|
192
|
-
border-radius:
|
|
192
|
+
border-radius: var(--shell-radius-sm);
|
|
193
193
|
text-transform: uppercase;
|
|
194
194
|
font-weight: 600;
|
|
195
195
|
letter-spacing: 0.04em;
|
|
@@ -223,7 +223,7 @@
|
|
|
223
223
|
background: transparent;
|
|
224
224
|
color: var(--shell-error, #d32f2f);
|
|
225
225
|
border: 1px solid var(--shell-error, #d32f2f);
|
|
226
|
-
border-radius:
|
|
226
|
+
border-radius: var(--shell-radius);
|
|
227
227
|
cursor: pointer;
|
|
228
228
|
font-family: inherit;
|
|
229
229
|
font-size: 0.8125rem;
|
|
@@ -240,7 +240,7 @@
|
|
|
240
240
|
background: var(--shell-warning, #ff9800);
|
|
241
241
|
color: #fff;
|
|
242
242
|
border: none;
|
|
243
|
-
border-radius:
|
|
243
|
+
border-radius: var(--shell-radius);
|
|
244
244
|
cursor: pointer;
|
|
245
245
|
font-family: inherit;
|
|
246
246
|
font-size: 0.8125rem;
|
|
@@ -258,7 +258,7 @@
|
|
|
258
258
|
background: color-mix(in srgb, var(--shell-error, #d32f2f) 15%, transparent);
|
|
259
259
|
color: var(--shell-error, #d32f2f);
|
|
260
260
|
border: 1px solid var(--shell-error, #d32f2f);
|
|
261
|
-
border-radius:
|
|
261
|
+
border-radius: var(--shell-radius);
|
|
262
262
|
font-size: 0.8125rem;
|
|
263
263
|
}
|
|
264
264
|
</style>
|
|
@@ -273,7 +273,7 @@
|
|
|
273
273
|
|
|
274
274
|
<style>
|
|
275
275
|
.store-view {
|
|
276
|
-
font-family: var(--shell-font
|
|
276
|
+
font-family: var(--shell-font-ui);
|
|
277
277
|
color: var(--shell-fg, #e0e0e0);
|
|
278
278
|
background: var(--shell-bg, #1e1e1e);
|
|
279
279
|
padding: 16px;
|
|
@@ -301,7 +301,7 @@
|
|
|
301
301
|
background: var(--shell-input-bg, #2a2a2a);
|
|
302
302
|
color: var(--shell-fg, #e0e0e0);
|
|
303
303
|
border: 1px solid var(--shell-border, #444);
|
|
304
|
-
border-radius:
|
|
304
|
+
border-radius: var(--shell-radius);
|
|
305
305
|
font-family: inherit;
|
|
306
306
|
font-size: 0.875rem;
|
|
307
307
|
}
|
|
@@ -313,7 +313,7 @@
|
|
|
313
313
|
background: var(--shell-input-bg, #2a2a2a);
|
|
314
314
|
color: var(--shell-fg, #e0e0e0);
|
|
315
315
|
border: 1px solid var(--shell-border, #444);
|
|
316
|
-
border-radius:
|
|
316
|
+
border-radius: var(--shell-radius);
|
|
317
317
|
font-family: inherit;
|
|
318
318
|
font-size: 0.875rem;
|
|
319
319
|
}
|
|
@@ -322,7 +322,7 @@
|
|
|
322
322
|
background: var(--shell-accent, #007acc);
|
|
323
323
|
color: #fff;
|
|
324
324
|
border: none;
|
|
325
|
-
border-radius:
|
|
325
|
+
border-radius: var(--shell-radius);
|
|
326
326
|
cursor: pointer;
|
|
327
327
|
font-family: inherit;
|
|
328
328
|
font-size: 0.875rem;
|
|
@@ -337,7 +337,7 @@
|
|
|
337
337
|
background: color-mix(in srgb, var(--shell-error, #d32f2f) 15%, transparent);
|
|
338
338
|
color: var(--shell-error, #d32f2f);
|
|
339
339
|
border: 1px solid var(--shell-error, #d32f2f);
|
|
340
|
-
border-radius:
|
|
340
|
+
border-radius: var(--shell-radius);
|
|
341
341
|
font-size: 0.8125rem;
|
|
342
342
|
}
|
|
343
343
|
.store-grid {
|
|
@@ -348,7 +348,7 @@
|
|
|
348
348
|
.store-card {
|
|
349
349
|
background: var(--shell-input-bg, #2a2a2a);
|
|
350
350
|
border: 1px solid var(--shell-border, #444);
|
|
351
|
-
border-radius:
|
|
351
|
+
border-radius: var(--shell-radius-md);
|
|
352
352
|
padding: 14px;
|
|
353
353
|
display: flex;
|
|
354
354
|
flex-direction: column;
|
|
@@ -373,7 +373,7 @@
|
|
|
373
373
|
.store-icon-img {
|
|
374
374
|
width: 36px;
|
|
375
375
|
height: 36px;
|
|
376
|
-
border-radius:
|
|
376
|
+
border-radius: var(--shell-radius);
|
|
377
377
|
object-fit: cover;
|
|
378
378
|
}
|
|
379
379
|
.store-icon-placeholder {
|
|
@@ -384,7 +384,7 @@
|
|
|
384
384
|
justify-content: center;
|
|
385
385
|
background: var(--shell-accent, #007acc);
|
|
386
386
|
color: #fff;
|
|
387
|
-
border-radius:
|
|
387
|
+
border-radius: var(--shell-radius);
|
|
388
388
|
font-weight: 700;
|
|
389
389
|
font-size: 1rem;
|
|
390
390
|
}
|
|
@@ -401,7 +401,7 @@
|
|
|
401
401
|
.store-card-badge {
|
|
402
402
|
font-size: 0.6875rem;
|
|
403
403
|
padding: 1px 6px;
|
|
404
|
-
border-radius:
|
|
404
|
+
border-radius: var(--shell-radius-sm);
|
|
405
405
|
text-transform: uppercase;
|
|
406
406
|
font-weight: 600;
|
|
407
407
|
letter-spacing: 0.04em;
|
|
@@ -433,7 +433,7 @@
|
|
|
433
433
|
color: var(--shell-warning, #ff9800);
|
|
434
434
|
padding: 4px 8px;
|
|
435
435
|
background: color-mix(in srgb, var(--shell-warning, #ff9800) 10%, transparent);
|
|
436
|
-
border-radius:
|
|
436
|
+
border-radius: var(--shell-radius-sm);
|
|
437
437
|
}
|
|
438
438
|
.store-card-actions {
|
|
439
439
|
margin-top: auto;
|
|
@@ -445,7 +445,7 @@
|
|
|
445
445
|
background: var(--shell-accent, #007acc);
|
|
446
446
|
color: #fff;
|
|
447
447
|
border: none;
|
|
448
|
-
border-radius:
|
|
448
|
+
border-radius: var(--shell-radius);
|
|
449
449
|
cursor: pointer;
|
|
450
450
|
font-family: inherit;
|
|
451
451
|
font-size: 0.8125rem;
|
|
@@ -464,7 +464,7 @@
|
|
|
464
464
|
background: var(--shell-warning, #ff9800);
|
|
465
465
|
color: #fff;
|
|
466
466
|
border: none;
|
|
467
|
-
border-radius:
|
|
467
|
+
border-radius: var(--shell-radius);
|
|
468
468
|
cursor: pointer;
|
|
469
469
|
font-family: inherit;
|
|
470
470
|
font-size: 0.8125rem;
|
|
@@ -495,7 +495,7 @@
|
|
|
495
495
|
padding: 4px 8px;
|
|
496
496
|
background: var(--shell-input-bg, #2a2a2a);
|
|
497
497
|
border: 1px solid var(--shell-border, #444);
|
|
498
|
-
border-radius:
|
|
498
|
+
border-radius: var(--shell-radius);
|
|
499
499
|
font-size: 0.8125rem;
|
|
500
500
|
}
|
|
501
501
|
.store-registry-url {
|
|
@@ -509,7 +509,7 @@
|
|
|
509
509
|
background: transparent;
|
|
510
510
|
color: var(--shell-error, #d32f2f);
|
|
511
511
|
border: 1px solid var(--shell-error, #d32f2f);
|
|
512
|
-
border-radius:
|
|
512
|
+
border-radius: var(--shell-radius-sm);
|
|
513
513
|
cursor: pointer;
|
|
514
514
|
font-size: 0.75rem;
|
|
515
515
|
flex-shrink: 0;
|
|
@@ -526,7 +526,7 @@
|
|
|
526
526
|
background: var(--shell-input-bg, #2a2a2a);
|
|
527
527
|
color: var(--shell-fg, #e0e0e0);
|
|
528
528
|
border: 1px solid var(--shell-border, #444);
|
|
529
|
-
border-radius:
|
|
529
|
+
border-radius: var(--shell-radius);
|
|
530
530
|
font-family: inherit;
|
|
531
531
|
font-size: 0.8125rem;
|
|
532
532
|
}
|
|
@@ -538,7 +538,7 @@
|
|
|
538
538
|
background: var(--shell-accent, #007acc);
|
|
539
539
|
color: #fff;
|
|
540
540
|
border: none;
|
|
541
|
-
border-radius:
|
|
541
|
+
border-radius: var(--shell-radius);
|
|
542
542
|
cursor: pointer;
|
|
543
543
|
font-family: inherit;
|
|
544
544
|
font-size: 0.8125rem;
|
package/dist/store/storeApp.js
CHANGED
|
@@ -48,7 +48,7 @@ export const storeShard = {
|
|
|
48
48
|
manifest: {
|
|
49
49
|
id: 'sh3-store',
|
|
50
50
|
label: 'Package Store',
|
|
51
|
-
version: '0.2.
|
|
51
|
+
version: '0.2.1',
|
|
52
52
|
views: [
|
|
53
53
|
{ id: 'sh3-store:browse', label: 'Store' },
|
|
54
54
|
{ id: 'sh3-store:installed', label: 'Installed' },
|
|
@@ -208,10 +208,11 @@ export const storeShard = {
|
|
|
208
208
|
};
|
|
209
209
|
ctx.registerView('sh3-store:browse', browseFactory);
|
|
210
210
|
ctx.registerView('sh3-store:installed', installedFactory);
|
|
211
|
+
// refreshInstalled can run immediately (hits server, no env needed).
|
|
212
|
+
refreshInstalled();
|
|
211
213
|
},
|
|
212
214
|
autostart() {
|
|
213
|
-
//
|
|
214
|
-
|
|
215
|
-
// the launcher without requiring an app to declare it.
|
|
215
|
+
// Runs after env hydration, so registries are populated.
|
|
216
|
+
storeContext.refreshCatalog();
|
|
216
217
|
},
|
|
217
218
|
};
|