@waterwx/dsh-novel-forge 1.6.0 → 1.7.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.
Files changed (41) hide show
  1. package/lib/client.js +37690 -2269
  2. package/lib/client.js.map +1 -1
  3. package/lib/index.js +767 -56
  4. package/lib/index.js.map +1 -1
  5. package/lib/types/client/api.d.ts +3 -0
  6. package/lib/types/client/locales.d.ts +0 -1
  7. package/lib/types/client/panel/FlowGuide.d.ts +21 -0
  8. package/lib/types/client/panel/MangaRoleLibrary.d.ts +18 -0
  9. package/lib/types/client/panel/MangaWorkspace.d.ts +6 -4
  10. package/lib/types/client/panel/RoleVisualPanel.d.ts +5 -3
  11. package/lib/types/client/panel/SceneLibrary.d.ts +1 -1
  12. package/lib/types/client/panel/StoryboardTab.d.ts +6 -2
  13. package/lib/types/engine.d.ts +23 -9
  14. package/lib/types/index.d.ts +6 -4
  15. package/lib/types/protocol.d.ts +171 -3
  16. package/package.json +100 -98
  17. package/src/client/api.ts +9 -0
  18. package/src/client/locales.ts +0 -1
  19. package/src/client/panel/AssetsTab.tsx +22 -22
  20. package/src/client/panel/AssistantTab.tsx +3 -3
  21. package/src/client/panel/BookshelfBar.tsx +1 -1
  22. package/src/client/panel/CreateBookView.tsx +10 -10
  23. package/src/client/panel/FlowGuide.tsx +83 -0
  24. package/src/client/panel/MangaRoleLibrary.tsx +810 -0
  25. package/src/client/panel/MangaWorkspace.tsx +359 -293
  26. package/src/client/panel/NovelPanel.tsx +465 -307
  27. package/src/client/panel/ReaderView.tsx +4 -4
  28. package/src/client/panel/RunPanel.tsx +9 -9
  29. package/src/client/panel/SceneLibrary.tsx +69 -68
  30. package/src/client/panel/ShelfView.tsx +28 -35
  31. package/src/client/panel/StoryboardTab.tsx +106 -42
  32. package/src/client/panel/StyleCard.tsx +13 -13
  33. package/src/client/panel/StyleGallery.tsx +2 -2
  34. package/src/client/panel/WorldTab.tsx +5 -5
  35. package/src/client/panel/panel.module.css +1189 -454
  36. package/src/client/panel/views.tsx +24 -24
  37. package/src/engine.ts +530 -59
  38. package/src/index.ts +37 -6
  39. package/src/protocol.ts +175 -3
  40. package/src/routes.ts +229 -1
  41. package/src/client/panel/RoleVisualPanel.tsx +0 -468
@@ -86,14 +86,14 @@ export function PlotlineCard(props: {
86
86
  }): ReactElement {
87
87
  const { line } = props
88
88
  return (
89
- <div key={line.id} style={{ border: '1px solid var(--nf-border)', borderRadius: 10, padding: '8px 12px', fontSize: 12, display: 'flex', flexDirection: 'column', gap: 4 }}>
89
+ <div key={line.id} style={{ border: '1px solid var(--nf-border)', borderRadius: 'var(--nf-radius-10)', padding: 'var(--nf-space-8) var(--nf-space-12)', fontSize: 'var(--nf-fs-12)', display: 'flex', flexDirection: 'column', gap: 'var(--nf-space-4)' }}>
90
90
  <div className={css.row} style={{ justifyContent: 'space-between', flexWrap: 'wrap' }}>
91
- <span style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
91
+ <span style={{ display: 'flex', alignItems: 'center', gap: 'var(--nf-space-6)', flexWrap: 'wrap' }}>
92
92
  <b>{line.name}</b>
93
93
  <span className={css.badge} style={{ borderColor: 'var(--nf-accent)', color: 'var(--nf-accent)' }}>{kindLabel(line.kind)}</span>
94
94
  <span className={css.badge} style={{ borderColor: plotlineStatusColor(line.status), color: plotlineStatusColor(line.status) }}>{plotlineStatusLabel(line.status)}</span>
95
95
  </span>
96
- <span style={{ display: 'flex', gap: 6 }}>
96
+ <span style={{ display: 'flex', gap: 'var(--nf-space-6)' }}>
97
97
  <button
98
98
  type="button"
99
99
  className={`${css.button} ${css.buttonSmall}`}
@@ -131,14 +131,14 @@ export function RoleCandidateRow(props: {
131
131
  const label = ROLE_LABELS[r.roleLabel] ?? r.roleLabel
132
132
  const color = roleColor(r.roleLabel)
133
133
  return (
134
- <div key={r.name} style={{ border: '1px solid var(--nf-border)', borderRadius: 8, padding: '6px 10px', fontSize: 12 }}>
134
+ <div key={r.name} style={{ border: '1px solid var(--nf-border)', borderRadius: 'var(--nf-radius-8)', padding: 'var(--nf-space-6) var(--nf-space-10)', fontSize: 'var(--nf-fs-12)' }}>
135
135
  <div className={css.row} style={{ justifyContent: 'space-between', flexWrap: 'wrap' }}>
136
- <span style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
136
+ <span style={{ display: 'flex', alignItems: 'center', gap: 'var(--nf-space-6)', flexWrap: 'wrap' }}>
137
137
  <b>{r.name}</b>
138
138
  <span className={css.badge} style={{ borderColor: color, color }}>{label}</span>
139
139
  {r.identity !== '' && <span className={css.meta}>{r.identity}</span>}
140
140
  </span>
141
- <span style={{ display: 'flex', gap: 6 }}>
141
+ <span style={{ display: 'flex', gap: 'var(--nf-space-6)' }}>
142
142
  <button type="button" className={`${css.button} ${css.buttonSmall} ${css.buttonPrimary}`} disabled={props.disabled} onClick={props.onAdopt}>
143
143
  + 采纳
144
144
  </button>
@@ -165,14 +165,14 @@ export function RoleCard(props: {
165
165
  const label = ROLE_LABELS[r.roleLabel] ?? r.roleLabel
166
166
  const color = roleColor(r.roleLabel)
167
167
  return (
168
- <div key={r.name} style={{ border: '1px solid var(--nf-border)', borderRadius: 8, padding: '6px 10px', fontSize: 12 }}>
168
+ <div key={r.name} style={{ border: '1px solid var(--nf-border)', borderRadius: 'var(--nf-radius-8)', padding: 'var(--nf-space-6) var(--nf-space-10)', fontSize: 'var(--nf-fs-12)' }}>
169
169
  <div className={css.row} style={{ justifyContent: 'space-between', flexWrap: 'wrap' }}>
170
- <span style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
170
+ <span style={{ display: 'flex', alignItems: 'center', gap: 'var(--nf-space-6)', flexWrap: 'wrap' }}>
171
171
  <b>{r.name}</b>
172
172
  <span className={css.badge} style={{ borderColor: color, color }}>{label}</span>
173
173
  {r.identity !== '' && <span className={css.meta}>{r.identity}</span>}
174
174
  </span>
175
- <span style={{ display: 'flex', gap: 6 }}>
175
+ <span style={{ display: 'flex', gap: 'var(--nf-space-6)' }}>
176
176
  <button type="button" className={`${css.button} ${css.buttonSmall}`} disabled={props.disabled} onClick={props.onEdit}>编辑</button>
177
177
  <button type="button" className={`${css.button} ${css.buttonSmall}`} disabled={props.disabled} onClick={props.onRemove}>删除</button>
178
178
  </span>
@@ -200,10 +200,10 @@ export function PlotlineHealthPanel(props: {
200
200
  }): ReactElement {
201
201
  const { report } = props
202
202
  return (
203
- <div style={{ display: 'flex', flexDirection: 'column', gap: 6, border: '1px solid var(--nf-info)', borderRadius: 12, padding: 10 }}>
203
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--nf-space-6)', border: '1px solid var(--nf-info)', borderRadius: 'var(--nf-radius-12)', padding: 'var(--nf-space-10)' }}>
204
204
  <div className={css.row} style={{ justifyContent: 'space-between', flexWrap: 'wrap' }}>
205
205
  <b>🩺 剧情健康检查</b>
206
- <span style={{ display: 'flex', gap: 8 }}>
206
+ <span style={{ display: 'flex', gap: 'var(--nf-space-8)' }}>
207
207
  <button
208
208
  type="button"
209
209
  className={`${css.button} ${css.buttonSmall}`}
@@ -216,21 +216,21 @@ export function PlotlineHealthPanel(props: {
216
216
  <button type="button" className={`${css.button} ${css.buttonSmall}`} onClick={props.onClose}>收起</button>
217
217
  </span>
218
218
  </div>
219
- <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--nf-accent)' }}>判定:{report.verdict}</div>
219
+ <div style={{ fontSize: 'var(--nf-fs-12)', fontWeight: 700, color: 'var(--nf-accent)' }}>判定:{report.verdict}</div>
220
220
  {report.timing !== '' && <div className={css.meta}><b>建议时机:</b>{report.timing}</div>}
221
221
  {report.reasons.length > 0 && (
222
- <div style={{ display: 'flex', flexDirection: 'column', gap: 2, fontSize: 12 }}>
222
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--nf-space-2)', fontSize: 'var(--nf-fs-12)' }}>
223
223
  {report.reasons.map((r, i) => <div key={i} className={css.meta}>· {r}</div>)}
224
224
  </div>
225
225
  )}
226
226
  {report.lines.length > 0 && (
227
- <div style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 12 }}>
227
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--nf-space-4)', fontSize: 'var(--nf-fs-12)' }}>
228
228
  {report.lines.map((l, i) => {
229
229
  const color = l.health === 'ok' ? 'var(--nf-success)' : l.health === 'warning' ? 'var(--nf-warn)' : 'var(--nf-error)'
230
230
  const label = l.health === 'ok' ? '健康' : l.health === 'warning' ? '预警' : '搁置过久'
231
231
  return (
232
- <div key={i} style={{ display: 'flex', gap: 8, alignItems: 'flex-start' }}>
233
- <span className={css.badge} style={{ borderColor: color, color, flex: 'none', marginTop: 1 }}>{label}</span>
232
+ <div key={i} style={{ display: 'flex', gap: 'var(--nf-space-8)', alignItems: 'flex-start' }}>
233
+ <span className={css.badge} style={{ borderColor: color, color, flex: 'none', marginTop: 'var(--nf-space-2)' }}>{label}</span>
234
234
  <span className={css.meta}><b>{l.name}</b>:{l.note}</span>
235
235
  </div>
236
236
  )
@@ -250,20 +250,20 @@ export function PlotlinePlanPanel(props: {
250
250
  }): ReactElement {
251
251
  const { plan } = props
252
252
  return (
253
- <div style={{ display: 'flex', flexDirection: 'column', gap: 6, border: '1px solid var(--nf-accent)', borderRadius: 12, padding: 10 }}>
253
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--nf-space-6)', border: '1px solid var(--nf-accent)', borderRadius: 'var(--nf-radius-12)', padding: 'var(--nf-space-10)' }}>
254
254
  <div className={css.row} style={{ justifyContent: 'space-between', flexWrap: 'wrap' }}>
255
255
  <b>✨ AI 剧情方案</b>
256
256
  <button type="button" className={`${css.button} ${css.buttonSmall}`} onClick={props.onClose}>收起</button>
257
257
  </div>
258
258
  {plan.direction !== '' && (
259
- <div className={css.meta} style={{ fontSize: 12 }}><b>下一阶段方向:</b>{plan.direction}</div>
259
+ <div className={css.meta} style={{ fontSize: 'var(--nf-fs-12)' }}><b>下一阶段方向:</b>{plan.direction}</div>
260
260
  )}
261
261
  {plan.suggestions.length > 0 && (
262
- <div style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 12 }}>
262
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--nf-space-4)', fontSize: 'var(--nf-fs-12)' }}>
263
263
  {plan.suggestions.map((s, i) => (
264
- <div key={i} style={{ border: '1px solid var(--nf-border)', borderRadius: 8, padding: '6px 10px' }}>
264
+ <div key={i} style={{ border: '1px solid var(--nf-border)', borderRadius: 'var(--nf-radius-8)', padding: 'var(--nf-space-6) var(--nf-space-10)' }}>
265
265
  <div className={css.row} style={{ justifyContent: 'space-between', flexWrap: 'wrap' }}>
266
- <span style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
266
+ <span style={{ display: 'flex', alignItems: 'center', gap: 'var(--nf-space-6)', flexWrap: 'wrap' }}>
267
267
  <b>{s.name}</b>
268
268
  <span className={css.badge} style={{ borderColor: 'var(--nf-accent)', color: 'var(--nf-accent)' }}>{kindLabel(s.kind)}</span>
269
269
  </span>
@@ -289,16 +289,16 @@ export function PlotlineSuggestionPanel(props: {
289
289
  onClose: () => void
290
290
  }): ReactElement {
291
291
  return (
292
- <div style={{ display: 'flex', flexDirection: 'column', gap: 6, border: '1px solid var(--nf-info)', borderRadius: 12, padding: 10 }}>
292
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--nf-space-6)', border: '1px solid var(--nf-info)', borderRadius: 'var(--nf-radius-12)', padding: 'var(--nf-space-10)' }}>
293
293
  <div className={css.row} style={{ justifyContent: 'space-between', flexWrap: 'wrap' }}>
294
294
  <b>✨ AI 建议({props.suggestions.length} 条)</b>
295
295
  <button type="button" className={`${css.button} ${css.buttonSmall}`} onClick={props.onClose}>收起</button>
296
296
  </div>
297
297
  {props.suggestions.length === 0 && <span className={css.meta}>没有候选线。</span>}
298
298
  {props.suggestions.map((s, i) => (
299
- <div key={i} style={{ border: '1px solid var(--nf-border)', borderRadius: 8, padding: '6px 10px', fontSize: 12 }}>
299
+ <div key={i} style={{ border: '1px solid var(--nf-border)', borderRadius: 'var(--nf-radius-8)', padding: 'var(--nf-space-6) var(--nf-space-10)', fontSize: 'var(--nf-fs-12)' }}>
300
300
  <div className={css.row} style={{ justifyContent: 'space-between', flexWrap: 'wrap' }}>
301
- <span style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
301
+ <span style={{ display: 'flex', alignItems: 'center', gap: 'var(--nf-space-6)', flexWrap: 'wrap' }}>
302
302
  <b>{s.name}</b>
303
303
  <span className={css.badge} style={{ borderColor: 'var(--nf-accent)', color: 'var(--nf-accent)' }}>{kindLabel(s.kind)}</span>
304
304
  </span>