@ai-ecoverse/slicc-spectrum 1.60.1 → 1.61.0

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.
@@ -7,6 +7,8 @@ import { ModelElement } from './base.js';
7
7
  export declare function countdown(ms: number): string;
8
8
  export declare function asking(approval: Approval): string;
9
9
  export declare function sudo(approval: Approval): string;
10
+ export declare const certain: (rules: string) => boolean;
11
+ export declare function secretRules(approval: Approval): string | null;
10
12
  export declare function waiting(model: SliccModel | null, now: number): Approval[];
11
13
  export declare class SliccApprovals extends ModelElement {
12
14
  #private;
@@ -0,0 +1,63 @@
1
+ import '@adobe/spectrum-wc/components/badge/swc-badge.js';
2
+ import '@adobe/spectrum-wc/components/button/swc-button.js';
3
+ import '@adobe/spectrum-wc/components/status-light/swc-status-light.js';
4
+ import '@adobe/spectrum-wc-icons/swc-icon-alert-triangle.js';
5
+ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
6
+ import type { AuditEntry, LinkedDevice, PolicyNotice, SecretView, SliccModel, VaultPort } from '../model/types.js';
7
+ import { ThemedElement } from './base.js';
8
+ import { type PopupDetail } from './vault.js';
9
+ export declare function until(at: number, now?: number): string;
10
+ export declare function who(entry: {
11
+ uid: number | null;
12
+ tag: string | null;
13
+ }): string;
14
+ export declare function sourceLine(secret: SecretView, devices: readonly LinkedDevice[]): string;
15
+ export declare function revealed(name: string, entries: readonly AuditEntry[], now?: number, more?: boolean): TemplateResult | null;
16
+ export declare function auditLine(entry: AuditEntry, devices: readonly LinkedDevice[]): TemplateResult;
17
+ export declare function merged(...pages: ReadonlyArray<readonly AuditEntry[]>): AuditEntry[];
18
+ export declare function prompt(text: string): string;
19
+ export declare class SliccSecrets extends ThemedElement {
20
+ #private;
21
+ static properties: {
22
+ model: {
23
+ attribute: boolean;
24
+ };
25
+ older: {
26
+ state: boolean;
27
+ };
28
+ more: {
29
+ state: boolean;
30
+ };
31
+ loading: {
32
+ state: boolean;
33
+ };
34
+ reveals: {
35
+ state: boolean;
36
+ };
37
+ popup: {
38
+ state: boolean;
39
+ };
40
+ acking: {
41
+ state: boolean;
42
+ };
43
+ failure: {
44
+ state: boolean;
45
+ };
46
+ };
47
+ older: readonly AuditEntry[];
48
+ more: boolean | null;
49
+ loading: boolean;
50
+ reveals: boolean;
51
+ popup: PopupDetail | null;
52
+ acking: ReadonlySet<string>;
53
+ failure: string | null;
54
+ constructor();
55
+ static styles: import("lit").CSSResult;
56
+ disconnectedCallback(): void;
57
+ protected willUpdate(changed: PropertyValues): void;
58
+ protected updated(): void;
59
+ protected subscribe(model: SliccModel): Array<() => void>;
60
+ showOlder(vault: VaultPort, entries: readonly AuditEntry[]): Promise<void>;
61
+ acknowledge(vault: VaultPort, notice: PolicyNotice): Promise<void>;
62
+ render(): TemplateResult | typeof nothing;
63
+ }
@@ -0,0 +1,36 @@
1
+ import { LitElement, type PropertyValues } from 'lit';
2
+ import type { ButtonConfig, ExecGrant, ExitName, LinkedDevice, PopupIntent, PopupResult, PopupState, Rule, SliccModel, VaultPort, Widening } from '../model/types.js';
3
+ export declare function devicesOf(model: SliccModel | null): readonly LinkedDevice[];
4
+ export declare function deviceName(id: string, devices: readonly LinkedDevice[]): string;
5
+ export declare function exitLabel(exit: ExitName, devices: readonly LinkedDevice[]): string;
6
+ export declare function list(items: readonly string[]): string;
7
+ export declare function ruleLine(rule: Rule): string;
8
+ export declare function shellWord(word: string): string;
9
+ export declare function execLine(grant: ExecGrant): string;
10
+ export declare function widening(change: Widening, devices: readonly LinkedDevice[]): string;
11
+ export declare function tabbables(root: ParentNode, stop: Element, out?: Array<HTMLElement | null>): Array<HTMLElement | null>;
12
+ export declare function sequential(order: Array<HTMLElement | null>): Array<HTMLElement | null>;
13
+ export interface PopupDetail {
14
+ intent: PopupIntent;
15
+ state: PopupState;
16
+ result?: PopupResult;
17
+ }
18
+ export declare class SliccVaultButton extends LitElement {
19
+ #private;
20
+ static properties: {
21
+ vault: {
22
+ attribute: boolean;
23
+ };
24
+ config: {
25
+ attribute: boolean;
26
+ };
27
+ };
28
+ vault: VaultPort | null | undefined;
29
+ config: ButtonConfig | null;
30
+ static styles: import("lit").CSSResult;
31
+ constructor();
32
+ connectedCallback(): void;
33
+ disconnectedCallback(): void;
34
+ focus(): void;
35
+ protected updated(changed: PropertyValues): void;
36
+ }
@@ -1,7 +1,7 @@
1
1
  import { Emitter } from '../model/emitter.js';
2
2
  import type { Approval, ApprovalDecision, ApprovalEnd, ApprovalsEvents, ApprovalsPort } from '../model/types.js';
3
3
  import type { Clock } from './clock.js';
4
- export type ApprovalScenario = 'agent' | 'user' | 'many' | 'follower' | 'fail' | 'soon' | 'elsewhere' | 'withdrawn';
4
+ export type ApprovalScenario = 'agent' | 'user' | 'many' | 'follower' | 'fail' | 'soon' | 'elsewhere' | 'withdrawn' | 'secrets';
5
5
  export declare function approvalFixtures(scenario: ApprovalScenario, now?: number): Approval[];
6
6
  export declare class DummyApprovals extends Emitter<ApprovalsEvents> implements ApprovalsPort {
7
7
  #private;
@@ -8,6 +8,7 @@ import { DummyNetwork, type LinksScenario, type NetworkScenario, type TailnetSce
8
8
  import { DummyNotices, type NoticeScenario } from './notices.js';
9
9
  import { DummyTabs, type TabsScenario } from './tabs.js';
10
10
  import { DummyUpdates, type PackageConfirm, type PackageScenario, type UpdateScenario } from './updates.js';
11
+ import { DummyVault, type VaultScenario } from './vault.js';
11
12
  export interface DummyOptions {
12
13
  delay?: number;
13
14
  storage?: Storage | null;
@@ -23,6 +24,7 @@ export interface DummyOptions {
23
24
  tabs?: TabsScenario | 'off';
24
25
  approvals?: ApprovalScenario | 'off';
25
26
  follow?: FollowScenario | 'off';
27
+ vault?: VaultScenario | 'off';
26
28
  browser?: BrowserScenario;
27
29
  sprinkles?: 'builtin' | 'cones';
28
30
  monitor?: 'dummy' | 'agent';
@@ -35,5 +37,6 @@ export interface DummyModel extends SliccModel {
35
37
  tabs?: DummyTabs;
36
38
  approvals?: DummyApprovals;
37
39
  follow?: DummyFollow;
40
+ vault?: DummyVault;
38
41
  }
39
- export declare function createDummyModel({ delay, storage, updates, packages, confirm, mounts, network, tailnet, links, changes, notices, tabs, approvals, follow, browser: scenario, sprinkles, monitor, }?: DummyOptions): DummyModel;
42
+ export declare function createDummyModel({ delay, storage, updates, packages, confirm, mounts, network, tailnet, links, changes, notices, tabs, approvals, follow, vault, browser: scenario, sprinkles, monitor, }?: DummyOptions): DummyModel;
@@ -0,0 +1,42 @@
1
+ import { Emitter } from '../model/emitter.js';
2
+ import type { AuditEntry, AuditPage, ButtonConfig, ButtonEvent, ButtonMessage, PolicyNotice, SecretView, VaultButton, VaultEvents, VaultList, VaultPort, VaultStatus } from '../model/types.js';
3
+ import type { Clock } from './clock.js';
4
+ export type VaultScenario = 'empty' | 'secrets' | 'notice' | 'locked';
5
+ export declare function vaultSecrets(now?: number): SecretView[];
6
+ export declare function vaultAudit(now?: number): AuditEntry[];
7
+ export declare function vaultOlder(now?: number): AuditEntry[];
8
+ export declare function vaultNotice(now?: number): PolicyNotice;
9
+ export declare function vaultFixtures(scenario: VaultScenario, now?: number): {
10
+ status: VaultStatus;
11
+ list: VaultList;
12
+ };
13
+ export declare class DummyVaultButton implements VaultButton {
14
+ #private;
15
+ element: HTMLElement;
16
+ config: ButtonConfig | null;
17
+ constructor(vault: DummyVault, time: Clock);
18
+ post(message: ButtonMessage): void;
19
+ listen(listener: (event: ButtonEvent) => void): () => void;
20
+ }
21
+ export declare class DummyVault extends Emitter<VaultEvents> implements VaultPort {
22
+ #private;
23
+ buttons: DummyVaultButton[];
24
+ acknowledged: string[];
25
+ constructor(scenario: VaultScenario, time: Clock);
26
+ status(): VaultStatus;
27
+ list(): VaultList;
28
+ audit(before?: number, limit?: number): Promise<AuditPage>;
29
+ acknowledge(notice: string): Promise<void>;
30
+ button(): DummyVaultButton;
31
+ autoLabel(): string;
32
+ autoIntent(): {
33
+ kind: 'unlock';
34
+ } | {
35
+ kind: 'manage';
36
+ };
37
+ answer(intent: Exclude<ButtonConfig['intent'], 'auto'>): Promise<{
38
+ name: string;
39
+ placeholder: string;
40
+ state: 'active';
41
+ } | null>;
42
+ }
@@ -17,3 +17,5 @@ export type { TabsScenario } from './dummy/tabs.js';
17
17
  export { DummyTabs, tabsFixtures } from './dummy/tabs.js';
18
18
  export type { DummyUpdatesOptions, PackageConfirm, PackageScenario, UpdateScenario, } from './dummy/updates.js';
19
19
  export { DummyUpdates, packageFixtures, updateFixtures } from './dummy/updates.js';
20
+ export type { VaultScenario } from './dummy/vault.js';
21
+ export { DummyVault, DummyVaultButton, vaultAudit, vaultFixtures, vaultNotice, vaultOlder, vaultSecrets, } from './dummy/vault.js';
@@ -806,6 +806,246 @@ export interface FollowPort extends Subscribable<{
806
806
  leave(): Promise<void>;
807
807
  retry?(): Promise<void>;
808
808
  }
809
+ export type DeviceId = string;
810
+ export type RecordKind = 'secret' | 'grant' | 'model' | 'mcp';
811
+ export type RecordState = 'active' | 'inert' | 'removed';
812
+ export type RecordSource = 'popup' | 'process' | `jerk:${string}@${DeviceId}` | `oauth:${string}` | `import:${string}`;
813
+ export type LockMode = 'auto' | 'passkey' | 'passphrase';
814
+ export type RequestKind = 'value' | 'oauth' | 'jerk-seal';
815
+ export type ExitName = 'vault-direct' | 'local-proxy' | 'cli-v' | 'tailscale' | 'local-link' | `device:${DeviceId}`;
816
+ export type ExecGrant = boolean | {
817
+ argv: string[][];
818
+ };
819
+ export interface Rule {
820
+ domain: string;
821
+ header: string;
822
+ methods: string[];
823
+ paths: string[];
824
+ }
825
+ export interface SecretView {
826
+ name: string;
827
+ kind: RecordKind;
828
+ placeholder: string;
829
+ state: RecordState;
830
+ source: RecordSource;
831
+ sourceDevice: DeviceId | null;
832
+ provider?: string;
833
+ account?: string;
834
+ domains: string[];
835
+ rules: Rule[];
836
+ exits: ExitName[];
837
+ exec: ExecGrant;
838
+ createdAt: number;
839
+ usedAt?: number;
840
+ expiresAt?: number;
841
+ removedAt?: number;
842
+ }
843
+ export interface PendingRequest {
844
+ id: string;
845
+ kind: RequestKind;
846
+ name?: string;
847
+ provider?: string;
848
+ prompt?: string;
849
+ uid: number;
850
+ tag: string | null;
851
+ createdAt: number;
852
+ expiresAt: number;
853
+ }
854
+ export interface VaultStatus {
855
+ version: string;
856
+ protocol: 1;
857
+ origin: string;
858
+ locked: boolean;
859
+ lock: LockMode;
860
+ waiting: PendingRequest[];
861
+ notices: number;
862
+ }
863
+ export type Widening = {
864
+ kind: 'rule';
865
+ secret: string;
866
+ rule: Rule;
867
+ } | {
868
+ kind: 'methods';
869
+ secret: string;
870
+ domain: string;
871
+ methods: string[];
872
+ } | {
873
+ kind: 'paths';
874
+ secret: string;
875
+ domain: string;
876
+ paths: string[];
877
+ } | {
878
+ kind: 'exec';
879
+ secret: string;
880
+ grant: ExecGrant;
881
+ } | {
882
+ kind: 'exit';
883
+ secret: string;
884
+ exit: ExitName;
885
+ } | {
886
+ kind: 'limits';
887
+ field: string;
888
+ from: number;
889
+ to: number;
890
+ };
891
+ export type PolicyFile = '/etc/fnox/config.toml' | '/etc/slicc/secrets-policy.toml';
892
+ export interface PolicyNotice {
893
+ id: string;
894
+ at: number;
895
+ file: PolicyFile;
896
+ sha256: string;
897
+ widened: Widening[];
898
+ acknowledged: boolean;
899
+ }
900
+ interface AuditBase {
901
+ seq: number;
902
+ id: string;
903
+ at: number;
904
+ name: string;
905
+ uid: number | null;
906
+ tag: string | null;
907
+ }
908
+ export interface InjectionEntry extends AuditBase {
909
+ type: 'inject' | 'forward';
910
+ domain: string;
911
+ method: string;
912
+ path: string;
913
+ rule: Rule;
914
+ exit: ExitName;
915
+ }
916
+ export interface RevealEntry extends AuditBase {
917
+ type: 'materialize';
918
+ grant: ExecGrant;
919
+ path: string;
920
+ argv: string;
921
+ argvSha256: string;
922
+ cwd: string;
923
+ pid: number;
924
+ ppid: number;
925
+ ticket: string;
926
+ consumed: boolean;
927
+ }
928
+ export interface SealEntry extends AuditBase {
929
+ type: 'seal';
930
+ source: RecordSource;
931
+ rotated: boolean;
932
+ }
933
+ export interface RemoveEntry extends AuditBase {
934
+ type: 'remove' | 'restore';
935
+ }
936
+ export interface PolicyEntry {
937
+ type: 'policy';
938
+ seq: number;
939
+ id: string;
940
+ at: number;
941
+ file: PolicyFile;
942
+ sha256: string;
943
+ accepted: boolean;
944
+ widened: Widening[];
945
+ warning?: string;
946
+ }
947
+ export type AuditEntry = InjectionEntry | RevealEntry | SealEntry | RemoveEntry | PolicyEntry;
948
+ export interface AuditPage {
949
+ audit: AuditEntry[];
950
+ more: boolean;
951
+ next?: number;
952
+ }
953
+ export interface VaultList {
954
+ secrets: SecretView[];
955
+ notices: PolicyNotice[];
956
+ audit: AuditEntry[];
957
+ auditMore: boolean;
958
+ }
959
+ export type PopupIntent = {
960
+ kind: 'unlock';
961
+ } | {
962
+ kind: 'enter';
963
+ name: string;
964
+ request?: string;
965
+ } | {
966
+ kind: 'request';
967
+ request: string;
968
+ } | {
969
+ kind: 'import';
970
+ format?: 'bundle' | 'keepass' | 'six';
971
+ } | {
972
+ kind: 'export';
973
+ } | {
974
+ kind: 'signin';
975
+ provider: string;
976
+ request?: string;
977
+ } | {
978
+ kind: 'manage';
979
+ name?: string;
980
+ };
981
+ export type PopupState = 'opened' | 'done' | 'cancelled' | 'closed' | 'blocked';
982
+ export interface PopupResult {
983
+ name: string;
984
+ placeholder: string;
985
+ state: RecordState;
986
+ }
987
+ export interface ButtonConfig {
988
+ intent: PopupIntent | 'auto';
989
+ label?: string;
990
+ size?: 's' | 'm' | 'l';
991
+ variant?: 'accent' | 'primary' | 'secondary';
992
+ treatment?: 'fill' | 'outline';
993
+ quiet?: boolean;
994
+ scale?: 'medium' | 'large';
995
+ theme?: 'light' | 'dark';
996
+ dir?: 'ltr' | 'rtl';
997
+ lang?: string;
998
+ disabled?: boolean;
999
+ }
1000
+ export type ButtonMessage = {
1001
+ type: 'slicc-vault';
1002
+ v: 1;
1003
+ op: 'button';
1004
+ button: ButtonConfig;
1005
+ } | {
1006
+ type: 'slicc-vault';
1007
+ v: 1;
1008
+ op: 'focus';
1009
+ };
1010
+ export type ButtonEvent = {
1011
+ type: 'slicc-vault';
1012
+ v: 1;
1013
+ } & ({
1014
+ event: 'ready';
1015
+ } | {
1016
+ event: 'size';
1017
+ width: number;
1018
+ height: number;
1019
+ inset: number;
1020
+ } | {
1021
+ event: 'label';
1022
+ label: string;
1023
+ } | {
1024
+ event: 'focus';
1025
+ direction: 'next' | 'previous';
1026
+ } | {
1027
+ event: 'popup';
1028
+ intent: PopupIntent;
1029
+ state: PopupState;
1030
+ result?: PopupResult;
1031
+ });
1032
+ export interface VaultButton {
1033
+ element: HTMLElement;
1034
+ post(message: ButtonMessage): void;
1035
+ listen(listener: (event: ButtonEvent) => void): () => void;
1036
+ }
1037
+ export interface VaultEvents {
1038
+ status: VaultStatus;
1039
+ list: VaultList;
1040
+ notice: PolicyNotice;
1041
+ }
1042
+ export interface VaultPort extends Subscribable<VaultEvents> {
1043
+ status(): VaultStatus | null;
1044
+ list(): VaultList | null;
1045
+ audit(before?: number, limit?: number): Promise<AuditPage>;
1046
+ acknowledge(notice: string): Promise<void>;
1047
+ button(): VaultButton;
1048
+ }
809
1049
  export interface SliccModel {
810
1050
  agent: AgentPort;
811
1051
  files: FilePort;
@@ -823,4 +1063,6 @@ export interface SliccModel {
823
1063
  tabs?: TabsPort;
824
1064
  approvals?: ApprovalsPort;
825
1065
  follow?: FollowPort;
1066
+ vault?: VaultPort;
826
1067
  }
1068
+ export {};
@@ -11,7 +11,9 @@ import { SliccFiles, SliccFileView } from './app/files.js';
11
11
  import { SliccFollow } from './app/follow.js';
12
12
  import { SliccNetwork } from './app/network.js';
13
13
  import { SliccNotices } from './app/notices.js';
14
+ import { SliccSecrets } from './app/secrets.js';
14
15
  import { SliccUpdates } from './app/updates.js';
16
+ import { SliccVaultButton } from './app/vault.js';
15
17
  import { SliccCodeView, SliccDiffView } from './components/code-view.js';
16
18
  import { SliccDock } from './components/dock.js';
17
19
  import { SliccFileTree } from './components/file-tree.js';
@@ -31,5 +33,5 @@ export type { GitStatusEntry } from './components/file-tree.js';
31
33
  export type { Listener, Subscribable } from './model/emitter.js';
32
34
  export { Emitter } from './model/emitter.js';
33
35
  export type * from './model/types.js';
34
- export { SliccAgents, SliccApp, SliccApprovals, SliccBrowser, SliccChanges, SliccChat, SliccCodeView, SliccComposer, SliccConfirm, SliccDiffPanel, SliccDiffView, SliccDock, SliccFiles, SliccFileTree, SliccFileView, SliccFollow, SliccNetwork, SliccNotices, SliccPrompt, SliccUpdates, };
36
+ export { SliccAgents, SliccApp, SliccApprovals, SliccBrowser, SliccChanges, SliccChat, SliccCodeView, SliccComposer, SliccConfirm, SliccDiffPanel, SliccDiffView, SliccDock, SliccFiles, SliccFileTree, SliccFileView, SliccFollow, SliccNetwork, SliccNotices, SliccPrompt, SliccSecrets, SliccUpdates, SliccVaultButton, };
35
37
  export declare function define(): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/slicc-spectrum",
3
- "version": "1.60.1",
3
+ "version": "1.61.0",
4
4
  "description": "Web components for SLICC on Spectrum Web Components: the terminal, the app shell and its surfaces",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -72,14 +72,14 @@
72
72
  "devDependencies": {
73
73
  "@adobe/spectrum-wc": "2.0.0-beta.4",
74
74
  "@adobe/spectrum-wc-icons": "2.0.0-beta.4",
75
- "@ai-ecoverse/slicc-kernel": "1.64.0",
75
+ "@ai-ecoverse/slicc-kernel": "1.65.0",
76
76
  "@ai-ecoverse/slicc-shared-web": "1.13.0",
77
77
  "@ai-ecoverse/wasm-bash": "5.3.0-17",
78
78
  "@ai-ecoverse/wasm-coreutils": "9.7.0-3",
79
79
  "@biomejs/biome": "2.5.15",
80
80
  "@fontsource/source-code-pro": "5.3.0",
81
81
  "@happy-dom/global-registrator": "20.14.5",
82
- "@pierre/diffs": "1.5.1",
82
+ "@pierre/diffs": "1.5.2",
83
83
  "@pierre/trees": "1.0.0-beta.6",
84
84
  "@spectrum-web-components/action-button": "1.12.4",
85
85
  "@spectrum-web-components/action-group": "1.12.4",