create-ekka-desktop-app 0.4.6 → 0.4.7
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/package.json +1 -1
- package/template/src/demo/components/InfoTooltip.tsx +3 -2
- package/template/src/demo/pages/AuditLogPage.tsx +2 -2
- package/template/src/demo/pages/PathPermissionsPage.tsx +5 -4
- package/template/src/demo/pages/RunnerPage.tsx +5 -4
- package/template/src/demo/pages/VaultPage.tsx +2 -2
package/package.json
CHANGED
|
@@ -45,8 +45,9 @@ export function InfoTooltip({ text, darkMode = false }: InfoTooltipProps): React
|
|
|
45
45
|
fontSize: '12px',
|
|
46
46
|
lineHeight: 1.4,
|
|
47
47
|
borderRadius: '6px',
|
|
48
|
-
whiteSpace: '
|
|
49
|
-
maxWidth: '
|
|
48
|
+
whiteSpace: 'normal',
|
|
49
|
+
maxWidth: '320px',
|
|
50
|
+
width: 'max-content',
|
|
50
51
|
zIndex: 1000,
|
|
51
52
|
opacity: isVisible ? 1 : 0,
|
|
52
53
|
visibility: isVisible ? 'visible' : 'hidden',
|
|
@@ -7,7 +7,7 @@ import { type CSSProperties, type ReactElement } from 'react';
|
|
|
7
7
|
import { clearAuditEvents, type AuditEvent } from '../../ekka/audit';
|
|
8
8
|
import { formatLocalTime, formatRelativeTime } from '../../ekka/utils';
|
|
9
9
|
import { useAuditEvents } from '../hooks/useAuditEvents';
|
|
10
|
-
import { EmptyState } from '../components
|
|
10
|
+
import { EmptyState, InfoTooltip } from '../components';
|
|
11
11
|
import { LearnMore } from '../components/LearnMore';
|
|
12
12
|
|
|
13
13
|
interface AuditLogPageProps {
|
|
@@ -193,7 +193,7 @@ export function AuditLogPage({ darkMode }: AuditLogPageProps): ReactElement {
|
|
|
193
193
|
<div>
|
|
194
194
|
<header style={styles.header}>
|
|
195
195
|
<div style={styles.headerText}>
|
|
196
|
-
<h1 style={styles.title}>Audit Log
|
|
196
|
+
<h1 style={styles.title}>Audit Log <InfoTooltip text="Append-only log of security-relevant events on this node. Every grant check, secret access, auth event, and runner action is recorded with actor, decision, and correlation ID." darkMode={darkMode} /></h1>
|
|
197
197
|
<p style={styles.description}>
|
|
198
198
|
Track system events and operations for debugging and compliance.
|
|
199
199
|
</p>
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { useState, useEffect, useCallback, type CSSProperties, type ReactElement } from 'react';
|
|
9
9
|
import { ekka, advanced, type PathInfo, type PathType, type PathAccess, type PathGrantResult } from '../../ekka';
|
|
10
10
|
import { InfoPopover } from '../components/InfoPopover';
|
|
11
|
+
import { InfoTooltip } from '../components';
|
|
11
12
|
|
|
12
13
|
interface PathPermissionsPageProps {
|
|
13
14
|
darkMode: boolean;
|
|
@@ -516,7 +517,7 @@ export function PathPermissionsPage({ darkMode }: PathPermissionsPageProps): Rea
|
|
|
516
517
|
return (
|
|
517
518
|
<div style={styles.container}>
|
|
518
519
|
<header style={styles.header}>
|
|
519
|
-
<h1 style={styles.title}>Path Permissions
|
|
520
|
+
<h1 style={styles.title}>Path Permissions <InfoTooltip text="Every folder your app accesses requires an explicit, engine-signed grant. Grants follow least-privilege: scoped to one path, one user, with an expiration. No grant = no access." darkMode={darkMode} /></h1>
|
|
520
521
|
<p style={styles.subtitle}>
|
|
521
522
|
EKKA requires explicit permission to access any path outside your home directory.
|
|
522
523
|
When you approve, EKKA requests an engine-signed grant that unlocks access.
|
|
@@ -528,7 +529,7 @@ export function PathPermissionsPage({ darkMode }: PathPermissionsPageProps): Rea
|
|
|
528
529
|
{/* Section A: Path Selector */}
|
|
529
530
|
<div style={styles.section}>
|
|
530
531
|
<div style={styles.sectionHeader}>
|
|
531
|
-
<span style={styles.sectionTitle}>Select Path
|
|
532
|
+
<span style={styles.sectionTitle}>Select Path <InfoTooltip text="Choose a folder to check whether a valid grant exists. The check is local — no data leaves your machine." darkMode={darkMode} /></span>
|
|
532
533
|
<div style={styles.sectionLine} />
|
|
533
534
|
</div>
|
|
534
535
|
<div style={styles.card}>
|
|
@@ -578,7 +579,7 @@ export function PathPermissionsPage({ darkMode }: PathPermissionsPageProps): Rea
|
|
|
578
579
|
{selectedPath && permissionStatus && (
|
|
579
580
|
<div style={styles.section}>
|
|
580
581
|
<div style={styles.sectionHeader}>
|
|
581
|
-
<span style={styles.sectionTitle}>Permission Status
|
|
582
|
+
<span style={styles.sectionTitle}>Permission Status <InfoTooltip text="Shows whether the selected path has a valid, cryptographically signed grant from the engine." darkMode={darkMode} /></span>
|
|
582
583
|
<div style={styles.sectionLine} />
|
|
583
584
|
</div>
|
|
584
585
|
<div
|
|
@@ -743,7 +744,7 @@ export function PathPermissionsPage({ darkMode }: PathPermissionsPageProps): Rea
|
|
|
743
744
|
{/* Section E: Current Permissions Table */}
|
|
744
745
|
<div style={styles.section}>
|
|
745
746
|
<div style={styles.sectionHeader}>
|
|
746
|
-
<span style={styles.sectionTitle}>Current Permissions
|
|
747
|
+
<span style={styles.sectionTitle}>Current Permissions <InfoTooltip text="All active grants for this node. Each grant is Ed25519-signed by the engine, scoped to a specific path, user, and tenant, with a fixed expiration." darkMode={darkMode} /></span>
|
|
747
748
|
<div style={styles.sectionLine} />
|
|
748
749
|
</div>
|
|
749
750
|
<div style={{ ...styles.card, padding: 0, overflowX: 'auto' }}>
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import { useState, useEffect, useRef, type CSSProperties, type ReactElement } from 'react';
|
|
15
15
|
import { advanced, type RunnerTaskStats } from '../../ekka';
|
|
16
|
+
import { InfoTooltip } from '../components';
|
|
16
17
|
|
|
17
18
|
interface RunnerPageProps {
|
|
18
19
|
darkMode: boolean;
|
|
@@ -247,7 +248,7 @@ export function RunnerPage({ darkMode }: RunnerPageProps): ReactElement {
|
|
|
247
248
|
return (
|
|
248
249
|
<div style={styles.container}>
|
|
249
250
|
<div style={styles.header}>
|
|
250
|
-
<h1 style={styles.title}>Runner
|
|
251
|
+
<h1 style={styles.title}>Runner <InfoTooltip text="The runner executes tasks assigned to this node. It polls the engine for work, sends heartbeats, and reports results. Tasks run in a sandboxed context with only the permissions granted to this node." darkMode={darkMode} /></h1>
|
|
251
252
|
<div style={styles.subtitle}>
|
|
252
253
|
<span>Task queue observability</span>
|
|
253
254
|
<span style={styles.refreshBadge}>Auto-refresh: 2s</span>
|
|
@@ -311,7 +312,7 @@ export function RunnerPage({ darkMode }: RunnerPageProps): ReactElement {
|
|
|
311
312
|
<div style={styles.grid}>
|
|
312
313
|
{/* Active Runners */}
|
|
313
314
|
<div style={styles.card}>
|
|
314
|
-
<div style={styles.cardTitle}>Active Runners
|
|
315
|
+
<div style={styles.cardTitle}>Active Runners <InfoTooltip text="Number of runner loops currently polling for and executing tasks on this node." darkMode={darkMode} /></div>
|
|
315
316
|
{stats.active_runners.length === 0 ? (
|
|
316
317
|
<div style={styles.noRunners}>
|
|
317
318
|
No active runners detected (last 10m)
|
|
@@ -334,7 +335,7 @@ export function RunnerPage({ darkMode }: RunnerPageProps): ReactElement {
|
|
|
334
335
|
|
|
335
336
|
{/* Queue Counts */}
|
|
336
337
|
<div style={styles.card}>
|
|
337
|
-
<div style={styles.cardTitle}>Queue Counts
|
|
338
|
+
<div style={styles.cardTitle}>Queue Counts <InfoTooltip text="Pending: waiting for a runner. Claimed: in progress. Completed/Failed: finished tasks in the last 5 minutes." darkMode={darkMode} /></div>
|
|
338
339
|
<div style={styles.countGrid}>
|
|
339
340
|
<div style={styles.countItem}>
|
|
340
341
|
<div style={{ ...styles.countValue, color: stats.counts.pending > 0 ? colors.yellow : colors.textMuted }}>
|
|
@@ -395,7 +396,7 @@ export function RunnerPage({ darkMode }: RunnerPageProps): ReactElement {
|
|
|
395
396
|
|
|
396
397
|
{/* Recent Tasks */}
|
|
397
398
|
<div style={styles.card}>
|
|
398
|
-
<div style={styles.cardTitle}>Recent Tasks (25)
|
|
399
|
+
<div style={styles.cardTitle}>Recent Tasks (25) <InfoTooltip text="Last 25 tasks processed by this node, newest first. Each shows type, status, and timing." darkMode={darkMode} /></div>
|
|
399
400
|
{stats.recent.length === 0 ? (
|
|
400
401
|
<div style={{ color: colors.textMuted, fontSize: '13px' }}>No tasks found</div>
|
|
401
402
|
) : (
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { useState, useEffect, useMemo, useCallback, useRef, type CSSProperties, type ReactElement } from 'react';
|
|
11
11
|
import { ekka, type SecretMeta, type SecretType, type BundleMeta, type FileEntry, type AuditEvent } from '../../ekka';
|
|
12
|
-
import { EmptyState } from '../components
|
|
12
|
+
import { EmptyState, InfoTooltip } from '../components';
|
|
13
13
|
import { Banner } from '../components/Banner';
|
|
14
14
|
|
|
15
15
|
// =============================================================================
|
|
@@ -213,7 +213,7 @@ export function VaultPage({ darkMode }: VaultPageProps): ReactElement {
|
|
|
213
213
|
return (
|
|
214
214
|
<div style={styles.container}>
|
|
215
215
|
<header style={styles.header}>
|
|
216
|
-
<h1 style={styles.title}>Vault
|
|
216
|
+
<h1 style={styles.title}>Vault <InfoTooltip text="Encrypted-at-rest secret storage, local to this node. Secrets never leave the device unencrypted. Organize with bundles and folders; every access is audited." darkMode={darkMode} /></h1>
|
|
217
217
|
<p style={styles.subtitle}>Securely manage secrets, organize them into bundles and folders, and track all access.</p>
|
|
218
218
|
</header>
|
|
219
219
|
|