ethagent 3.0.0 → 3.0.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.
Files changed (26) hide show
  1. package/package.json +1 -1
  2. package/src/identity/continuity/envelope.ts +9 -9
  3. package/src/identity/continuity/publicSkills.ts +17 -0
  4. package/src/identity/hub/OperationalRoutes.tsx +11 -39
  5. package/src/identity/hub/continuity/ContinuityDashboardScreen.tsx +3 -23
  6. package/src/identity/hub/continuity/RecoveryConfirmScreen.tsx +5 -5
  7. package/src/identity/hub/continuity/SavePromptScreen.tsx +1 -3
  8. package/src/identity/hub/continuity/skills/SkillActionsScreen.tsx +151 -0
  9. package/src/identity/hub/continuity/skills/SkillsTreeScreen.tsx +1 -33
  10. package/src/identity/hub/continuity/state.ts +9 -9
  11. package/src/identity/hub/create/CreateFlow.tsx +1 -1
  12. package/src/identity/hub/custody/routes.tsx +1 -1
  13. package/src/identity/hub/ens/EnsEditAdvancedScreens.tsx +0 -1
  14. package/src/identity/hub/ens/EnsEditMaintenanceScreens.tsx +0 -1
  15. package/src/identity/hub/identityHubReducer.ts +3 -9
  16. package/src/identity/hub/profile/EditProfileFlow.tsx +5 -5
  17. package/src/identity/hub/restore/recovery.ts +3 -3
  18. package/src/identity/hub/shared/components/IdentitySummary.tsx +22 -2
  19. package/src/identity/hub/shared/components/MenuScreen.tsx +4 -4
  20. package/src/identity/hub/shared/components/UnlinkedIdentityScreen.tsx +3 -3
  21. package/src/identity/hub/shared/components/menuFlagsFromReconciliation.ts +1 -1
  22. package/src/identity/hub/useIdentityHubContinuity.ts +3 -3
  23. package/src/identity/wallet/page/copy.ts +43 -43
  24. package/src/models/modelPickerOptions.ts +2 -0
  25. package/src/identity/hub/continuity/skills/DeleteSkillScreen.tsx +0 -123
  26. package/src/identity/hub/continuity/skills/SkillVisibilityScreen.tsx +0 -171
@@ -1,171 +0,0 @@
1
- import React, { useEffect, useState } from 'react'
2
- import { Box, Text } from 'ink'
3
- import { Surface } from '../../../../ui/Surface.js'
4
- import { Select, type SelectOption } from '../../../../ui/Select.js'
5
- import { theme } from '../../../../ui/theme.js'
6
- import type { EthagentIdentity } from '../../../../storage/config.js'
7
- import { listSkills } from '../../../continuity/skills/loadSkills.js'
8
- import type { SkillIndexEntry, SkillVisibility } from '../../../continuity/skills/types.js'
9
-
10
- interface SkillVisibilityListProps {
11
- identity?: EthagentIdentity
12
- notice?: string
13
- footer: React.ReactNode
14
- onPick: (relativePath: string) => void
15
- onCancel: () => void
16
- }
17
-
18
- type PickAction =
19
- | { kind: 'skill'; relativePath: string }
20
- | { kind: 'cancel' }
21
-
22
- export const SkillVisibilityListScreen: React.FC<SkillVisibilityListProps> = ({
23
- identity,
24
- notice,
25
- footer,
26
- onPick,
27
- onCancel,
28
- }) => {
29
- const [entries, setEntries] = useState<SkillIndexEntry[] | null>(null)
30
- const [error, setError] = useState<string | null>(null)
31
-
32
- useEffect(() => {
33
- let cancelled = false
34
- if (!identity) {
35
- setEntries([])
36
- return () => { cancelled = true }
37
- }
38
- listSkills(identity)
39
- .then(list => { if (!cancelled) { setEntries(list); setError(null) } })
40
- .catch(err => {
41
- if (cancelled) return
42
- setEntries([])
43
- setError(String((err as Error).message ?? err))
44
- })
45
- return () => { cancelled = true }
46
- }, [identity])
47
-
48
- const subtitle = notice ?? 'Pick a skill to change its visibility in the public manifest.'
49
- const isLoading = entries === null
50
- const skills = entries ?? []
51
-
52
- const options: Array<SelectOption<PickAction>> = []
53
- if (isLoading) {
54
- options.push({ value: { kind: 'cancel' }, role: 'notice', label: 'Loading...', labelColor: theme.dim, indent: 0 })
55
- } else if (skills.length === 0) {
56
- options.push({ value: { kind: 'cancel' }, role: 'notice', label: 'No skills yet. Create one first.', labelColor: theme.dim, indent: 0 })
57
- } else {
58
- options.push({ value: { kind: 'cancel' }, role: 'section', label: 'Skills' })
59
- for (const skill of skills) {
60
- options.push({
61
- value: { kind: 'skill', relativePath: skill.relativePath },
62
- label: skill.displayName ?? skill.name,
63
- hint: visibilityBadge(skill.visibility),
64
- hintColor: visibilityColor(skill.visibility),
65
- })
66
- }
67
- }
68
- options.push({ value: { kind: 'cancel' }, role: 'section', label: 'Navigation' })
69
- options.push({ value: { kind: 'cancel' }, label: 'Back', hint: 'Return to Skills', role: 'utility' })
70
-
71
- return (
72
- <Surface title="Skill Visibility" subtitle={subtitle} footer={footer}>
73
- {error && (
74
- <Box marginTop={1}>
75
- <Text color={theme.accentError}>{error}</Text>
76
- </Box>
77
- )}
78
- <Box marginTop={1}>
79
- <Select<PickAction>
80
- options={options}
81
- hintLayout="inline"
82
- onSubmit={choice => {
83
- if (choice.kind === 'cancel') return onCancel()
84
- return onPick(choice.relativePath)
85
- }}
86
- onCancel={onCancel}
87
- />
88
- </Box>
89
- </Surface>
90
- )
91
- }
92
-
93
- interface SkillVisibilityPickProps {
94
- identity?: EthagentIdentity
95
- relativePath: string
96
- footer: React.ReactNode
97
- onSelect: (visibility: SkillVisibility) => void
98
- onCancel: () => void
99
- }
100
-
101
- export const SkillVisibilityPickScreen: React.FC<SkillVisibilityPickProps> = ({
102
- identity,
103
- relativePath,
104
- footer,
105
- onSelect,
106
- onCancel,
107
- }) => {
108
- const [current, setCurrent] = useState<SkillVisibility | null>(null)
109
- const [displayName, setDisplayName] = useState<string>(relativePath)
110
-
111
- useEffect(() => {
112
- let cancelled = false
113
- if (!identity) return () => { cancelled = true }
114
- listSkills(identity)
115
- .then(list => {
116
- if (cancelled) return
117
- const match = list.find(entry => entry.relativePath === relativePath)
118
- if (match) {
119
- setCurrent(match.visibility)
120
- setDisplayName(match.displayName ?? match.name)
121
- }
122
- })
123
- .catch(() => null)
124
- return () => { cancelled = true }
125
- }, [identity, relativePath])
126
-
127
- const subtitle = current
128
- ? `Current: ${current}. Pick a new value.`
129
- : 'Pick a visibility level.'
130
-
131
- return (
132
- <Surface title={`Visibility · ${displayName}`} subtitle={subtitle} footer={footer}>
133
- <Box marginTop={1}>
134
- <Select<SkillVisibility | 'cancel'>
135
- options={[
136
- { value: 'private', label: 'Private', hint: 'Local-only. Not in skills.json.' },
137
- { value: 'discoverable', label: 'Discoverable', hint: 'Default. Indexed in skills.json with description.' },
138
- { value: 'public', label: 'Public', hint: 'Indexed in skills.json and Agent Card.' },
139
- { value: 'cancel', role: 'section', label: 'Navigation' },
140
- { value: 'cancel', label: 'Back', hint: 'Return to skill list', role: 'utility' },
141
- ]}
142
- hintLayout="inline"
143
- initialIndex={current ? indexForVisibility(current) : 0}
144
- onSubmit={choice => {
145
- if (choice === 'cancel') return onCancel()
146
- return onSelect(choice)
147
- }}
148
- onCancel={onCancel}
149
- />
150
- </Box>
151
- </Surface>
152
- )
153
- }
154
-
155
- function visibilityBadge(visibility: SkillVisibility): string {
156
- if (visibility === 'public') return '[public]'
157
- if (visibility === 'discoverable') return '[discoverable]'
158
- return '[private]'
159
- }
160
-
161
- function visibilityColor(visibility: SkillVisibility): string {
162
- if (visibility === 'public') return theme.accentPeriwinkle
163
- if (visibility === 'discoverable') return theme.textSubtle
164
- return theme.dim
165
- }
166
-
167
- function indexForVisibility(visibility: SkillVisibility): number {
168
- if (visibility === 'private') return 0
169
- if (visibility === 'discoverable') return 1
170
- return 2
171
- }