@cloud411716/fancy-webnovel 1.0.42 → 1.0.44

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.
@@ -12,6 +12,9 @@ import { initProject } from './init-project.js';
12
12
 
13
13
  // inject is declared in the root index.js; only apply() is imported by index.js
14
14
 
15
+ /** UserQuestionError codes that indicate user cancellation */
16
+ const USER_CANCEL_CODES = new Set(['ASK_CANCELLED', 'ASK_ABORTED', 'NO_PROVIDER']);
17
+
15
18
  function isValidPath(p) {
16
19
  return (
17
20
  !p.includes('..') &&
@@ -49,6 +52,8 @@ const bootstrap = {
49
52
  return `❓ 确认将以下路径作为项目根?\n${projectRoot}`;
50
53
  case 'cancelled':
51
54
  return '🚫 已取消';
55
+ case 'no_provider':
56
+ return '⚠️ 当前环境不支持交互式提问。请在 dsh-tui 中运行此命令,或确保 web UI 已正确加载交互组件。';
52
57
  case 'initializing':
53
58
  return `⏳ 正在初始化 ${projectRoot}...`;
54
59
  case 'success':
@@ -77,11 +82,22 @@ export function apply(ctx) {
77
82
  let projectRoot = rawInput;
78
83
 
79
84
  if (!projectRoot) {
80
- const result = await ctx.userQuestions.ask({
81
- questions: [bootstrap.askPath()],
82
- agent: invocation.agent,
83
- signal,
84
- });
85
+ let result;
86
+ try {
87
+ result = await ctx.userQuestions.ask({
88
+ questions: [bootstrap.askPath()],
89
+ agent: invocation.agent,
90
+ signal,
91
+ });
92
+ } catch (err) {
93
+ if (err?.code === 'NO_PROVIDER') {
94
+ return notify(session, 'error', bootstrap.notify({ type: 'no_provider' }));
95
+ }
96
+ if (err?.code && USER_CANCEL_CODES.has(err.code)) {
97
+ return notify(session, 'error', bootstrap.notify({ type: 'cancelled' }));
98
+ }
99
+ throw err;
100
+ }
85
101
  projectRoot = result.answers[0]?.custom?.trim() ?? '';
86
102
  }
87
103
 
@@ -103,17 +119,28 @@ export function apply(ctx) {
103
119
  }
104
120
 
105
121
  // ---------- confirm ----------
106
- const confirm = await ctx.userQuestions.ask({
107
- questions: [{
108
- id: 'confirm',
109
- question: bootstrap.notify({ type: 'confirm', projectRoot }),
110
- detail: projectRoot,
111
- hideCustomInput: true,
112
- options: bootstrap.confirmOptions(),
113
- }],
114
- agent: invocation.agent,
115
- signal,
116
- });
122
+ let confirm;
123
+ try {
124
+ confirm = await ctx.userQuestions.ask({
125
+ questions: [{
126
+ id: 'confirm',
127
+ question: bootstrap.notify({ type: 'confirm', projectRoot }),
128
+ detail: projectRoot,
129
+ hideCustomInput: true,
130
+ options: bootstrap.confirmOptions(),
131
+ }],
132
+ agent: invocation.agent,
133
+ signal,
134
+ });
135
+ } catch (err) {
136
+ if (err?.code === 'NO_PROVIDER') {
137
+ return notify(session, 'error', bootstrap.notify({ type: 'no_provider' }));
138
+ }
139
+ if (err?.code && USER_CANCEL_CODES.has(err.code)) {
140
+ return notify(session, 'error', bootstrap.notify({ type: 'cancelled' }));
141
+ }
142
+ throw err;
143
+ }
117
144
  const ans = confirm.answers[0];
118
145
  const chosen = ans?.selected?.[0] ?? ans?.custom;
119
146
  if (chosen !== '确认创建') {
@@ -14,6 +14,9 @@ import * as fanqie from './platforms/fanqie.js';
14
14
  import * as jinjiang from './platforms/jinjiang.js';
15
15
  import * as qimao from './platforms/qimao.js';
16
16
 
17
+ /** UserQuestionError codes that indicate user cancellation or unavailability */
18
+ const USER_CANCEL_CODES = new Set(['ASK_CANCELLED', 'ASK_ABORTED', 'NO_PROVIDER']);
19
+
17
20
  // inject is declared in the root index.js; only apply() is imported by index.js
18
21
 
19
22
  const PLATFORM_TABLE = [
@@ -66,6 +69,8 @@ const scan = {
66
69
  return '❌ 无效选择,请输入 1-4 的编号。';
67
70
  case 'cancelled':
68
71
  return '🚫 已取消。';
72
+ case 'no_provider':
73
+ return '⚠️ 当前环境不支持交互式提问。请在 dsh-tui 中运行此命令,或确保 web UI 已正确加载交互组件。';
69
74
  case 'handover':
70
75
  return (
71
76
  `📊 采集完成,正在将数据交给 LLM 进行分析...\n` +
@@ -133,15 +138,28 @@ export function apply(ctx) {
133
138
  }
134
139
 
135
140
  // ---------- platform selection ----------
136
- const platformResult = await ctx.userQuestions.ask({
137
- questions: [{
138
- id: 'platform',
139
- ...scan.askPlatform(),
140
- question: `${scan.platformList()}\n\n请选择要扫的平台(输入编号 1-4):`,
141
- }],
142
- agent: invocation.agent,
143
- signal,
144
- });
141
+ let platformResult;
142
+ try {
143
+ platformResult = await ctx.userQuestions.ask({
144
+ questions: [{
145
+ id: 'platform',
146
+ ...scan.askPlatform(),
147
+ question: `${scan.platformList()}\n\n请选择要扫的平台(输入编号 1-4):`,
148
+ }],
149
+ agent: invocation.agent,
150
+ signal,
151
+ });
152
+ } catch (err) {
153
+ // Handle user cancellation or no provider
154
+ if (err?.code === 'NO_PROVIDER') {
155
+ return notify(session, 'error', scan.notify({ type: 'no_provider' }));
156
+ }
157
+ if (err?.code && USER_CANCEL_CODES.has(err.code)) {
158
+ return notify(session, 'error', scan.notify({ type: 'cancelled' }));
159
+ }
160
+ // Re-throw unexpected errors
161
+ throw err;
162
+ }
145
163
  const answer = platformResult.answers[0]?.custom?.trim();
146
164
  if (!answer) {
147
165
  return notify(session, 'error', scan.notify({ type: 'cancelled' }));
@@ -154,11 +172,22 @@ export function apply(ctx) {
154
172
  const platform = row[1];
155
173
 
156
174
  // ---------- rank selection (multi-select) ----------
157
- const rankResult = await ctx.userQuestions.ask({
158
- questions: [scan.askRankList(platform)],
159
- agent: invocation.agent,
160
- signal,
161
- });
175
+ let rankResult;
176
+ try {
177
+ rankResult = await ctx.userQuestions.ask({
178
+ questions: [scan.askRankList(platform)],
179
+ agent: invocation.agent,
180
+ signal,
181
+ });
182
+ } catch (err) {
183
+ if (err?.code === 'NO_PROVIDER') {
184
+ return notify(session, 'error', scan.notify({ type: 'no_provider' }));
185
+ }
186
+ if (err?.code && USER_CANCEL_CODES.has(err.code)) {
187
+ return notify(session, 'error', scan.notify({ type: 'cancelled' }));
188
+ }
189
+ throw err;
190
+ }
162
191
  const selected = rankResult.answers[0]?.selected ?? [];
163
192
  const custom = rankResult.answers[0]?.custom?.trim();
164
193
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloud411716/fancy-webnovel",
3
- "version": "1.0.42",
3
+ "version": "1.0.44",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "exports": {