@maci0/dsh-feynman 0.0.0-stage → 0.21.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/LICENSE +21 -0
- package/NOTICE +7 -0
- package/README.md +125 -2
- package/cordis.patch.yml +7 -0
- package/icon.svg +6 -0
- package/index.js +494 -0
- package/lib/client.js +350 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +69 -4
- package/prompts.js +333 -0
package/lib/client.js
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-feynman browser half.
|
|
3
|
+
*
|
|
4
|
+
* One card on the Plugins page, bound to the settings form the settings domain
|
|
5
|
+
* serves for this package's `feynman` row. The card edits nothing in that
|
|
6
|
+
* namespace: the refs it shows are row config. It stages the two key
|
|
7
|
+
* literals locally and writes them through `remote.credentials`, so a literal
|
|
8
|
+
* never rides a settings response (the WebSearchCard pattern). The card learns
|
|
9
|
+
* only configured/writable booleans via `remote.credentials.describe`.
|
|
10
|
+
*
|
|
11
|
+
* Plain JavaScript on purpose: the client module system serves this file as a
|
|
12
|
+
* lazy-CJS factory on `window.__ModuleLoader__`; `react` is provided.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
window.__ModuleLoader__.load({
|
|
16
|
+
id: '@maci0/dsh-feynman',
|
|
17
|
+
|
|
18
|
+
factory: (require) => {
|
|
19
|
+
var module = { exports: {} }
|
|
20
|
+
var exports = module.exports
|
|
21
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
|
|
22
|
+
|
|
23
|
+
const React = require('react')
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* This plugin's locale namespace and slot key. The settings form is
|
|
27
|
+
* separate: the settings domain keys one form per mounted row, so the card
|
|
28
|
+
* reads `feynman`, the row id in `cordis.patch.yml`.
|
|
29
|
+
*/
|
|
30
|
+
const NAMESPACE = 'research-keys'
|
|
31
|
+
|
|
32
|
+
/** The row id whose config form the card edits. */
|
|
33
|
+
const SETTINGS_NAMESPACE = 'feynman'
|
|
34
|
+
|
|
35
|
+
const CSS = [
|
|
36
|
+
'.rk-body{border-top:0.5px solid var(--dsw-alias-border-l2);margin:0 16px;padding:12px 0 8px;display:flex;flex-direction:column;gap:12px}',
|
|
37
|
+
'.rk-field{display:flex;flex-direction:column;gap:6px}',
|
|
38
|
+
'.rk-label{font-size:13px;font-weight:600;color:var(--dsw-alias-label-secondary)}',
|
|
39
|
+
'.rk-row{display:flex;gap:8px}',
|
|
40
|
+
'.rk-input{flex:1;min-width:0;font:inherit;font-size:13px;padding:6px 10px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-4);border:1px solid var(--dsw-alias-border-l2);border-radius:8px}',
|
|
41
|
+
'.rk-btn{appearance:none;font:inherit;font-size:13px;padding:6px 14px;cursor:pointer;color:var(--dsw-alias-label-primary);background:none;border:1px solid var(--dsw-alias-border-l2);border-radius:8px}',
|
|
42
|
+
'.rk-btn:disabled{cursor:default;opacity:.5}',
|
|
43
|
+
'.rk-badge{font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}',
|
|
44
|
+
'.rk-hint{font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}',
|
|
45
|
+
'.rk-error{font-size:12px;line-height:1.5;color:var(--dsw-alias-label-error)}',
|
|
46
|
+
].join('')
|
|
47
|
+
|
|
48
|
+
if (typeof document !== 'undefined') {
|
|
49
|
+
const style = document.createElement('style')
|
|
50
|
+
style.textContent = CSS
|
|
51
|
+
document.head.append(style)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const en = {
|
|
55
|
+
summary: 'Hugging Face and AlphaXiv keys, stored in the credentials file.',
|
|
56
|
+
set: 'set',
|
|
57
|
+
unset: 'not set',
|
|
58
|
+
unknown: 'unknown',
|
|
59
|
+
hfLabel: 'Hugging Face API key',
|
|
60
|
+
axLabel: 'AlphaXiv API key',
|
|
61
|
+
inputLabel: 'New value for {label}',
|
|
62
|
+
save: 'Save',
|
|
63
|
+
clear: 'Clear',
|
|
64
|
+
hint: 'Keys are stored in the managed credentials file, never in settings. Empty input clears nothing; use Clear.',
|
|
65
|
+
envNote: 'A key exported in the environment shadows the stored one.',
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Slot id → settings ref field; labels resolve as `${id}Label`. */
|
|
69
|
+
const SLOTS = { hf: 'hfTokenEnv', ax: 'alphaxivTokenEnv' }
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* `/feynman` subcommand rows for the bare-invocation picker. Static copy
|
|
73
|
+
* of the host catalog (prompts.js WORKFLOWS + SESSION_COMMANDS); the
|
|
74
|
+
* client bundle cannot import the host module. Internal by design: the
|
|
75
|
+
* `/client` entry exports nothing beyond what cordis loading needs, and
|
|
76
|
+
* `client.test.js` asserts the rendered picker options instead.
|
|
77
|
+
*/
|
|
78
|
+
const SUBCOMMANDS = [
|
|
79
|
+
['deepresearch', '<topic>', 'Source-heavy investigation → research brief'],
|
|
80
|
+
['lit', '<topic-or-lab>', 'Literature review: consensus, disagreements, open questions'],
|
|
81
|
+
['review', '<arXiv-ID | URL | file>', 'Internal review with severity-graded feedback'],
|
|
82
|
+
['review-loop', '<artifact> [rounds=3] | stop', 'Bounded review→fix→re-review loop'],
|
|
83
|
+
['audit', '<arXiv-ID | repo-URL>', "Paper's claims vs its codebase"],
|
|
84
|
+
['replicate', '<paper | claim>', 'Source-backed replication plan'],
|
|
85
|
+
['recipe', '<training-task>', 'Ranked implementable ML training recipes'],
|
|
86
|
+
['compare', '<topic | paper-IDs>', 'Agreement/disagreement matrix'],
|
|
87
|
+
['draft', '<topic | --from-session>', 'Paper-style draft from findings'],
|
|
88
|
+
['autoresearch', '<idea>', 'Hypothesis→experiment→analysis→decision loop'],
|
|
89
|
+
['watch', '<topic>', 'Baseline survey + refresh plan'],
|
|
90
|
+
['rank', '<topic> [flags]', 'Read-first paper ranking (PaperRank)'],
|
|
91
|
+
['paper', '<id> [--fetch-full-text] [--json]', 'Legal full-text access candidates'],
|
|
92
|
+
['preview', '[artifact-path]', 'Render an artifact via pandoc'],
|
|
93
|
+
['log', '', 'Write a durable session log'],
|
|
94
|
+
['jobs', '', 'Inspect background-job state'],
|
|
95
|
+
['help', '', 'Show grouped research commands'],
|
|
96
|
+
['feynman-model', '', 'How to change the model route'],
|
|
97
|
+
['init', '', 'Bootstrap AGENTS.md and session-log folders'],
|
|
98
|
+
['outputs', '', 'Browse research artifacts'],
|
|
99
|
+
['btw', '<question>', 'Side question as non-waking context'],
|
|
100
|
+
['thinking', '[level]', 'Note a thinking level'],
|
|
101
|
+
['search', '<query>', 'Search prior session transcripts'],
|
|
102
|
+
['web-results', '', 'List web sources fetched this session'],
|
|
103
|
+
['keys', '', 'Show or store research API keys'],
|
|
104
|
+
['doctor', '', 'Diagnose keys, seams, pandoc, card'],
|
|
105
|
+
['status', '', 'Setup summary'],
|
|
106
|
+
]
|
|
107
|
+
|
|
108
|
+
/** Configured-state word: ellipsis before an answer, `unknown` when the lookup failed. */
|
|
109
|
+
const word = (t, state) => state === undefined ? '…'
|
|
110
|
+
: state.unknown === true ? t('unknown') : t(state.configured ? 'set' : 'unset')
|
|
111
|
+
|
|
112
|
+
function refsOf(snapshot) {
|
|
113
|
+
const value = snapshot.value !== null && typeof snapshot.value === 'object' ? snapshot.value : {}
|
|
114
|
+
return {
|
|
115
|
+
hfTokenEnv: typeof value.hfTokenEnv === 'string' ? value.hfTokenEnv : 'HF_TOKEN',
|
|
116
|
+
alphaxivTokenEnv: typeof value.alphaxivTokenEnv === 'string' ? value.alphaxivTokenEnv : 'ALPHAXIV_API_KEY',
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* One key row: status badge, password input, save/clear.
|
|
122
|
+
* The staged literal lives in component state and is cleared on save.
|
|
123
|
+
* @param remote - the browser remote context for credential writes.
|
|
124
|
+
*/
|
|
125
|
+
function KeyRow(props) {
|
|
126
|
+
// NOTE: `ref` is reserved by React and never arrives as a prop;
|
|
127
|
+
// the credential reference rides `credRef` instead.
|
|
128
|
+
const { t, remote, label, credRef, state, onRefresh } = props
|
|
129
|
+
// `state` is undefined until the credentials domain answers for `credRef`;
|
|
130
|
+
// writes stay enabled meanwhile, and a refused write reports its error.
|
|
131
|
+
const writable = state === undefined || state.writable
|
|
132
|
+
const [staged, setStaged] = React.useState('')
|
|
133
|
+
const [error, setError] = React.useState(null)
|
|
134
|
+
const [busy, setBusy] = React.useState(false)
|
|
135
|
+
|
|
136
|
+
const run = async (fn) => {
|
|
137
|
+
setError(null)
|
|
138
|
+
setBusy(true)
|
|
139
|
+
try {
|
|
140
|
+
const response = await fn()
|
|
141
|
+
if (!response.ok) setError(response.error.message)
|
|
142
|
+
else setStaged('')
|
|
143
|
+
onRefresh()
|
|
144
|
+
} catch (cause) {
|
|
145
|
+
setError(cause instanceof Error ? cause.message : String(cause))
|
|
146
|
+
} finally {
|
|
147
|
+
setBusy(false)
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return React.createElement(
|
|
152
|
+
'div',
|
|
153
|
+
{ className: 'rk-field' },
|
|
154
|
+
React.createElement('span', { className: 'rk-label' }, label),
|
|
155
|
+
React.createElement('span', { className: 'rk-badge', title: state?.failure }, `${credRef}: ${word(t, state)}`),
|
|
156
|
+
React.createElement(
|
|
157
|
+
'div',
|
|
158
|
+
{ className: 'rk-row' },
|
|
159
|
+
React.createElement('input', {
|
|
160
|
+
type: 'password',
|
|
161
|
+
className: 'rk-input',
|
|
162
|
+
value: staged,
|
|
163
|
+
autoComplete: 'off',
|
|
164
|
+
spellCheck: false,
|
|
165
|
+
disabled: busy || !writable,
|
|
166
|
+
// The label beside the field is a plain span, so the field names
|
|
167
|
+
// itself: without this a screen reader announces only "password".
|
|
168
|
+
'aria-label': t('inputLabel', { label }),
|
|
169
|
+
onChange: (event) => { setStaged(event.target.value) },
|
|
170
|
+
}),
|
|
171
|
+
React.createElement(
|
|
172
|
+
'button',
|
|
173
|
+
{
|
|
174
|
+
type: 'button',
|
|
175
|
+
className: 'rk-btn',
|
|
176
|
+
disabled: busy || !writable || staged === '',
|
|
177
|
+
onClick: () => { void run(() => remote.credentials.set(credRef, staged)) },
|
|
178
|
+
},
|
|
179
|
+
t('save'),
|
|
180
|
+
),
|
|
181
|
+
state?.configured === true
|
|
182
|
+
? React.createElement(
|
|
183
|
+
'button',
|
|
184
|
+
{
|
|
185
|
+
type: 'button',
|
|
186
|
+
className: 'rk-btn',
|
|
187
|
+
disabled: busy || !writable,
|
|
188
|
+
onClick: () => { void run(() => remote.credentials.unset(credRef)) },
|
|
189
|
+
},
|
|
190
|
+
t('clear'),
|
|
191
|
+
)
|
|
192
|
+
: null,
|
|
193
|
+
),
|
|
194
|
+
error === null ? null : React.createElement('div', { className: 'rk-error' }, error),
|
|
195
|
+
)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function createCard(scope, remote, t) {
|
|
199
|
+
const useKeys = () => React.useSyncExternalStore(
|
|
200
|
+
(listener) => scope.subscribe(listener),
|
|
201
|
+
() => scope.getSnapshot(),
|
|
202
|
+
)
|
|
203
|
+
/** Live card refreshers, so a key written elsewhere updates open cards. */
|
|
204
|
+
const refreshers = new Set()
|
|
205
|
+
|
|
206
|
+
const Card = function ResearchKeysCard(props) {
|
|
207
|
+
const snapshot = useKeys()
|
|
208
|
+
const [states, setStates] = React.useState({})
|
|
209
|
+
const refreshGeneration = React.useRef(0)
|
|
210
|
+
const ready = snapshot.status === 'ready'
|
|
211
|
+
const summary = props != null && props.view === 'summary'
|
|
212
|
+
const refs = refsOf(snapshot)
|
|
213
|
+
|
|
214
|
+
const refresh = async () => {
|
|
215
|
+
const started = ++refreshGeneration.current
|
|
216
|
+
// The reference is resolved at call time: a rename while a read is in
|
|
217
|
+
// flight must not make the next read answer for the old reference.
|
|
218
|
+
const live = refsOf(scope.getSnapshot())
|
|
219
|
+
const entries = await Promise.all(Object.entries(SLOTS).map(async ([id, refField]) => {
|
|
220
|
+
const ref = live[refField]
|
|
221
|
+
let failure
|
|
222
|
+
const response = await remote.credentials.describe([ref]).catch((cause) => {
|
|
223
|
+
failure = cause instanceof Error ? cause.message : String(cause)
|
|
224
|
+
return undefined
|
|
225
|
+
})
|
|
226
|
+
// Coerce at the wire boundary: only strict booleans reach state,
|
|
227
|
+
// so no response shape can ever render as a child.
|
|
228
|
+
const view = response !== null && typeof response === 'object' && response.ok === true
|
|
229
|
+
? response.value?.[ref]
|
|
230
|
+
: undefined
|
|
231
|
+
const info = view !== null && typeof view === 'object' ? view : undefined
|
|
232
|
+
// A lookup with no usable answer says nothing about the key, so it
|
|
233
|
+
// reads unknown (reason as the tooltip), never "not set".
|
|
234
|
+
if (info === undefined) {
|
|
235
|
+
const refused = response !== null && typeof response === 'object' && response.ok === false
|
|
236
|
+
&& typeof response.error?.message === 'string' ? response.error.message : undefined
|
|
237
|
+
const reason = failure ?? refused
|
|
238
|
+
return [id, { ref, unknown: true, writable: true, ...reason === undefined ? {} : { failure: reason } }]
|
|
239
|
+
}
|
|
240
|
+
// The answer carries the reference it describes. Two reads can
|
|
241
|
+
// settle out of order, and the reference can be renamed between
|
|
242
|
+
// them, so a state without that stamp is dropped at render.
|
|
243
|
+
return [id, { ref, configured: info?.configured === true, writable: info?.writable !== false }]
|
|
244
|
+
}))
|
|
245
|
+
if (started === refreshGeneration.current) setStates(Object.fromEntries(entries))
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Every hook runs before any early return: the form starts `loading`
|
|
249
|
+
// under the same mounted card, and React rejects a render that calls
|
|
250
|
+
// more hooks than the one before it. A rename re-runs the read, since
|
|
251
|
+
// no credential changed and no invalidation will arrive.
|
|
252
|
+
React.useEffect(() => {
|
|
253
|
+
if (!ready || summary) return undefined
|
|
254
|
+
refreshers.add(refresh)
|
|
255
|
+
void refresh()
|
|
256
|
+
return () => { refreshGeneration.current += 1; refreshers.delete(refresh) }
|
|
257
|
+
}, [ready, summary, refs.hfTokenEnv, refs.alphaxivTokenEnv])
|
|
258
|
+
|
|
259
|
+
if (!ready) return null
|
|
260
|
+
if (summary) return t('summary')
|
|
261
|
+
|
|
262
|
+
return React.createElement(
|
|
263
|
+
'div',
|
|
264
|
+
{ className: 'rk-page' },
|
|
265
|
+
React.createElement(
|
|
266
|
+
'div',
|
|
267
|
+
{ className: 'rk-body' },
|
|
268
|
+
Object.entries(SLOTS).map(([id, refField]) => {
|
|
269
|
+
// An answer for a reference the card no longer shows is no
|
|
270
|
+
// answer: reporting it would name one reference's state under
|
|
271
|
+
// another's label. It stays unknown until its own read lands.
|
|
272
|
+
const answered = states[id]
|
|
273
|
+
const state = answered !== undefined && answered.ref === refs[refField] ? answered : undefined
|
|
274
|
+
return React.createElement(KeyRow, {
|
|
275
|
+
key: `${id}:${refs[refField]}`,
|
|
276
|
+
t,
|
|
277
|
+
remote,
|
|
278
|
+
label: `${t(`${id}Label`)} (${refs[refField]})`,
|
|
279
|
+
credRef: refs[refField],
|
|
280
|
+
state,
|
|
281
|
+
onRefresh: () => { void refresh() },
|
|
282
|
+
})
|
|
283
|
+
}),
|
|
284
|
+
React.createElement('div', { className: 'rk-hint' }, `${t('hint')} ${t('envNote')}`),
|
|
285
|
+
),
|
|
286
|
+
)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return { Card, refreshers }
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Mount the card: locale, scope, slot registration, credential invalidation.
|
|
294
|
+
* Plus the `/feynman` bare-invocation picker: a subcommand popup whose
|
|
295
|
+
* pick submits the completed `/feynman <sub>` line back through the host,
|
|
296
|
+
* so the row offers subcommand completion the catalog row cannot.
|
|
297
|
+
* @param ctx - the browser plugin context.
|
|
298
|
+
*/
|
|
299
|
+
function apply(ctx) {
|
|
300
|
+
const t = ctx.locale.bind(NAMESPACE)
|
|
301
|
+
// Single-locale registration: English is the documented fallback locale,
|
|
302
|
+
// and the per-key fallback resolves every other language. Registering a
|
|
303
|
+
// second namespace entry here would shadow later dictionaries.
|
|
304
|
+
ctx.effect(
|
|
305
|
+
() => ctx.locale.register(NAMESPACE, 'en', en),
|
|
306
|
+
'dsh-feynman: locale dictionary',
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
const scope = ctx.configForms.get(SETTINGS_NAMESPACE)
|
|
310
|
+
const { Card, refreshers } = createCard(scope, ctx.remote, t)
|
|
311
|
+
|
|
312
|
+
ctx.slots.inject('plugins.row.config', () => ctx.slots.register({
|
|
313
|
+
name: 'plugins.row.config',
|
|
314
|
+
key: '@maci0/dsh-feynman#feynman',
|
|
315
|
+
locale: NAMESPACE,
|
|
316
|
+
}, Card))
|
|
317
|
+
|
|
318
|
+
ctx.effect(
|
|
319
|
+
() => ctx.remote.$on('credentials/reference-updated', () => {
|
|
320
|
+
for (const refresh of refreshers) void refresh()
|
|
321
|
+
}),
|
|
322
|
+
'dsh-feynman: credential invalidations',
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
ctx.effect(() => ctx.commandUi.decorate({
|
|
326
|
+
name: 'feynman',
|
|
327
|
+
available: () => true,
|
|
328
|
+
ui: {
|
|
329
|
+
kind: 'popupSelect',
|
|
330
|
+
options: () => Promise.resolve(SUBCOMMANDS.map(([id, hint, detail]) => ({
|
|
331
|
+
id,
|
|
332
|
+
label: hint ? `/feynman ${id} ${hint}` : `/feynman ${id}`,
|
|
333
|
+
...(detail === undefined ? {} : { detail }),
|
|
334
|
+
}))),
|
|
335
|
+
onSelect: async (option, session) => {
|
|
336
|
+
const live = ctx.sessions.binding(session.sessionId)?.session
|
|
337
|
+
if (live === undefined) throw new Error('this session is not materialized yet')
|
|
338
|
+
const result = await live.command(`/feynman ${option.id} `)
|
|
339
|
+
if (!result.ok) throw new Error(`subcommand submit failed: ${result.error.code}: ${result.error.message}`)
|
|
340
|
+
if (!result.value.matched) throw new Error('the host offers no /feynman command')
|
|
341
|
+
},
|
|
342
|
+
},
|
|
343
|
+
}), 'dsh-feynman: /feynman subcommand picker')
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
exports.apply = apply
|
|
347
|
+
exports.inject = ['slots', 'configForms', 'locale', 'remote', 'remote.credentials', 'commandUi', 'sessions']
|
|
348
|
+
return module.exports
|
|
349
|
+
},
|
|
350
|
+
})
|
package/locale/en.json
ADDED
package/locale/zh.json
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,71 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maci0/dsh-feynman",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
"version": "0.21.2",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public",
|
|
6
|
+
"registry": "https://registry.npmjs.org/"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "index.js",
|
|
10
|
+
"description": "Feynman-style research workflows for DeepSeek Harness behind one /feynman command (deepresearch, review, audit, review-loop, \u2026)",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": "./index.js",
|
|
14
|
+
"./client": {
|
|
15
|
+
"default": "./lib/client.js"
|
|
16
|
+
},
|
|
17
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
18
|
+
"./locale/*.json": "./locale/*.json",
|
|
19
|
+
"./package.json": "./package.json"
|
|
20
|
+
},
|
|
21
|
+
"dsh": {
|
|
22
|
+
"bundle": {
|
|
23
|
+
"patch": "./cordis.patch.yml"
|
|
24
|
+
},
|
|
25
|
+
"client": {
|
|
26
|
+
"platform": "web",
|
|
27
|
+
"inject": [
|
|
28
|
+
"@deepseek-ai/dsh-client-connection",
|
|
29
|
+
"@deepseek-ai/dsh-client-locale",
|
|
30
|
+
"@deepseek-ai/dsh-client-ui-renderer",
|
|
31
|
+
"@deepseek-ai/dsh-client-ui-settings",
|
|
32
|
+
"@deepseek-ai/dsh-client-ui-plugin-manager",
|
|
33
|
+
"@deepseek-ai/dsh-client-ui-commands",
|
|
34
|
+
"@deepseek-ai/dsh-api-session-controller"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
"compatibility": {
|
|
38
|
+
"dsh": ">=0.2.0-rc.2 <0.3.0"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"icon.svg",
|
|
43
|
+
"locale/*.json",
|
|
44
|
+
"index.js",
|
|
45
|
+
"prompts.js",
|
|
46
|
+
"lib/client.js",
|
|
47
|
+
"cordis.patch.yml",
|
|
48
|
+
"README.md",
|
|
49
|
+
"LICENSE",
|
|
50
|
+
"NOTICE"
|
|
51
|
+
],
|
|
52
|
+
"scripts": {
|
|
53
|
+
"test": "bun test",
|
|
54
|
+
"test:node": "node --test tests/*.test.*"
|
|
55
|
+
},
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": "^22.19.0 || >=24.0.0"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@deepseek-ai/cordis": "4.0.5-alpha.1"
|
|
61
|
+
},
|
|
62
|
+
"repository": {
|
|
63
|
+
"type": "git",
|
|
64
|
+
"url": "https://github.com/maci0/dsh-feynman.git"
|
|
65
|
+
},
|
|
66
|
+
"icon": "./icon.svg",
|
|
67
|
+
"dependencies": {
|
|
68
|
+
"@deepseek-ai/dsh-llm": "0.2.1-alpha.1",
|
|
69
|
+
"@deepseek-ai/schemastery": "^3.18.4"
|
|
70
|
+
}
|
|
71
|
+
}
|