@pmate/cli 0.20.1 → 0.20.3
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/dist/index.d.ts +21 -2
- package/dist/index.js +425 -73
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -121,12 +121,31 @@ type SummaryCommandArgs = {
|
|
|
121
121
|
};
|
|
122
122
|
type QuizCommandArgs = {
|
|
123
123
|
type: Command.Quiz;
|
|
124
|
-
action: "
|
|
124
|
+
action: "create-draft";
|
|
125
|
+
paperId: string;
|
|
126
|
+
apiBaseUrl?: string;
|
|
127
|
+
linkBaseUrl?: string;
|
|
128
|
+
} | {
|
|
129
|
+
type: Command.Quiz;
|
|
130
|
+
action: "update-meta";
|
|
131
|
+
paperId: string;
|
|
125
132
|
filePath: string;
|
|
133
|
+
apiBaseUrl?: string;
|
|
134
|
+
linkBaseUrl?: string;
|
|
135
|
+
} | {
|
|
136
|
+
type: Command.Quiz;
|
|
137
|
+
action: "append-step";
|
|
126
138
|
paperId: string;
|
|
139
|
+
filePath: string;
|
|
140
|
+
apiBaseUrl?: string;
|
|
141
|
+
linkBaseUrl?: string;
|
|
142
|
+
} | {
|
|
143
|
+
type: Command.Quiz;
|
|
144
|
+
action: "reorder";
|
|
145
|
+
paperId: string;
|
|
146
|
+
stepIds: string[];
|
|
127
147
|
apiBaseUrl?: string;
|
|
128
148
|
linkBaseUrl?: string;
|
|
129
|
-
activate: boolean;
|
|
130
149
|
} | {
|
|
131
150
|
type: Command.Quiz;
|
|
132
151
|
action: "activate";
|
package/dist/index.js
CHANGED
|
@@ -13271,7 +13271,14 @@ var LoginCommandHandler = class {
|
|
|
13271
13271
|
if (!token) {
|
|
13272
13272
|
response.statusCode = 400;
|
|
13273
13273
|
response.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
13274
|
-
response.end(
|
|
13274
|
+
response.end(
|
|
13275
|
+
this.renderHtml({
|
|
13276
|
+
state: "error",
|
|
13277
|
+
title: "Login failed",
|
|
13278
|
+
message: "Missing sessionId in redirect URL.",
|
|
13279
|
+
hint: "Please retry from your terminal with `pmate login`."
|
|
13280
|
+
})
|
|
13281
|
+
);
|
|
13275
13282
|
rejectToken(new Error("Login callback did not include sessionId."));
|
|
13276
13283
|
return;
|
|
13277
13284
|
}
|
|
@@ -13280,30 +13287,106 @@ var LoginCommandHandler = class {
|
|
|
13280
13287
|
response.setHeader("Connection", "close");
|
|
13281
13288
|
response.end(
|
|
13282
13289
|
this.renderHtml(
|
|
13283
|
-
|
|
13284
|
-
|
|
13290
|
+
{
|
|
13291
|
+
state: "success",
|
|
13292
|
+
title: "Login complete",
|
|
13293
|
+
message: "You can close this tab and return to the terminal.",
|
|
13294
|
+
hint: "This window is only used to hand the session back to PMate CLI."
|
|
13295
|
+
}
|
|
13285
13296
|
),
|
|
13286
13297
|
() => resolveToken(token)
|
|
13287
13298
|
);
|
|
13288
13299
|
}
|
|
13289
|
-
renderHtml(
|
|
13300
|
+
renderHtml(input) {
|
|
13301
|
+
const badgeBg = input.state === "success" ? "#ecfdf3" : "#fff1f2";
|
|
13302
|
+
const badgeText = input.state === "success" ? "#027a48" : "#be123c";
|
|
13303
|
+
const dotColor = input.state === "success" ? "#10b981" : "#f43f5e";
|
|
13304
|
+
const stateText = input.state === "success" ? "Ready" : "Action required";
|
|
13305
|
+
const hint = input.hint?.trim();
|
|
13290
13306
|
return `<!doctype html>
|
|
13291
13307
|
<html lang="en">
|
|
13292
13308
|
<head>
|
|
13293
13309
|
<meta charset="utf-8" />
|
|
13294
13310
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
13295
|
-
<title>${title}</title>
|
|
13311
|
+
<title>${input.title}</title>
|
|
13296
13312
|
<style>
|
|
13297
|
-
|
|
13298
|
-
|
|
13299
|
-
|
|
13300
|
-
|
|
13313
|
+
:root {
|
|
13314
|
+
color-scheme: light;
|
|
13315
|
+
}
|
|
13316
|
+
* {
|
|
13317
|
+
box-sizing: border-box;
|
|
13318
|
+
}
|
|
13319
|
+
body {
|
|
13320
|
+
margin: 0;
|
|
13321
|
+
min-height: 100vh;
|
|
13322
|
+
font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
13323
|
+
color: #0f172a;
|
|
13324
|
+
background:
|
|
13325
|
+
radial-gradient(circle at 18% 18%, #e0f2fe 0, transparent 36%),
|
|
13326
|
+
radial-gradient(circle at 82% 14%, #e0e7ff 0, transparent 34%),
|
|
13327
|
+
linear-gradient(180deg, #f8fafc 0%, #eef2ff 100%);
|
|
13328
|
+
display: grid;
|
|
13329
|
+
place-items: center;
|
|
13330
|
+
padding: 24px;
|
|
13331
|
+
}
|
|
13332
|
+
main {
|
|
13333
|
+
width: min(560px, 100%);
|
|
13334
|
+
border-radius: 28px;
|
|
13335
|
+
border: 1px solid rgba(15, 23, 42, 0.08);
|
|
13336
|
+
background: rgba(255, 255, 255, 0.9);
|
|
13337
|
+
box-shadow:
|
|
13338
|
+
0 22px 56px rgba(15, 23, 42, 0.14),
|
|
13339
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.75);
|
|
13340
|
+
backdrop-filter: blur(8px);
|
|
13341
|
+
padding: 28px;
|
|
13342
|
+
}
|
|
13343
|
+
.badge {
|
|
13344
|
+
display: inline-flex;
|
|
13345
|
+
align-items: center;
|
|
13346
|
+
gap: 8px;
|
|
13347
|
+
border-radius: 999px;
|
|
13348
|
+
padding: 8px 12px;
|
|
13349
|
+
font-size: 14px;
|
|
13350
|
+
font-weight: 600;
|
|
13351
|
+
background: ${badgeBg};
|
|
13352
|
+
color: ${badgeText};
|
|
13353
|
+
}
|
|
13354
|
+
.dot {
|
|
13355
|
+
width: 10px;
|
|
13356
|
+
height: 10px;
|
|
13357
|
+
border-radius: 999px;
|
|
13358
|
+
background: ${dotColor};
|
|
13359
|
+
}
|
|
13360
|
+
h1 {
|
|
13361
|
+
margin: 16px 0 8px;
|
|
13362
|
+
font-size: 32px;
|
|
13363
|
+
line-height: 1.18;
|
|
13364
|
+
letter-spacing: -0.03em;
|
|
13365
|
+
}
|
|
13366
|
+
p {
|
|
13367
|
+
margin: 0;
|
|
13368
|
+
font-size: 16px;
|
|
13369
|
+
line-height: 1.6;
|
|
13370
|
+
color: #334155;
|
|
13371
|
+
}
|
|
13372
|
+
.hint {
|
|
13373
|
+
margin-top: 16px;
|
|
13374
|
+
border-radius: 14px;
|
|
13375
|
+
background: rgba(148, 163, 184, 0.14);
|
|
13376
|
+
padding: 12px 14px;
|
|
13377
|
+
font-size: 14px;
|
|
13378
|
+
}
|
|
13301
13379
|
</style>
|
|
13302
13380
|
</head>
|
|
13303
13381
|
<body>
|
|
13304
13382
|
<main>
|
|
13305
|
-
<
|
|
13306
|
-
|
|
13383
|
+
<div class="badge">
|
|
13384
|
+
<span class="dot"></span>
|
|
13385
|
+
<span>${stateText}</span>
|
|
13386
|
+
</div>
|
|
13387
|
+
<h1>${input.title}</h1>
|
|
13388
|
+
<p>${input.message}</p>
|
|
13389
|
+
${hint ? `<p class="hint">${hint}</p>` : ""}
|
|
13307
13390
|
</main>
|
|
13308
13391
|
</body>
|
|
13309
13392
|
</html>`;
|
|
@@ -17964,24 +18047,24 @@ init_sessionStore();
|
|
|
17964
18047
|
|
|
17965
18048
|
// src/services/QuizService.ts
|
|
17966
18049
|
var INTRO_STEP_COUNT = 2;
|
|
17967
|
-
var QUIZ_APP_ID = "quiz";
|
|
18050
|
+
var QUIZ_APP_ID = "pmate:quiz";
|
|
17968
18051
|
var DEFAULT_MIN_LENGTHS = Object.freeze({
|
|
17969
|
-
|
|
18052
|
+
teachingArticle: 36,
|
|
17970
18053
|
explanation: 60
|
|
17971
18054
|
});
|
|
17972
18055
|
var INTRO_MIN_LENGTHS = Object.freeze({
|
|
17973
|
-
|
|
17974
|
-
|
|
18056
|
+
teachingArticle: 90,
|
|
18057
|
+
teachingTip: 36,
|
|
17975
18058
|
explanation: 90
|
|
17976
18059
|
});
|
|
17977
18060
|
var FIELD_RULES = Object.freeze({
|
|
17978
|
-
|
|
17979
|
-
label: "
|
|
18061
|
+
teachingArticle: Object.freeze({
|
|
18062
|
+
label: "teachingArticle\uFF08\u6559\u5B66\u77ED\u6587\uFF09",
|
|
17980
18063
|
defaultHint: "\u77E5\u8BC6\u8BB2\u89E3\u81F3\u5C11\u8981\u5148\u628A\u9898\u76EE\u524D\u63D0\u8BF4\u6E05\u695A\uFF0C\u518D\u8BA9\u7528\u6237\u53BB\u9009\u7B54\u6848\u3002",
|
|
17981
18064
|
introHint: "\u5F00\u573A\u9898\u81F3\u5C11\u8981\u8BB2\u6E05\u5B83\u662F\u4EC0\u4E48\u3001\u89E3\u51B3\u4EC0\u4E48\u95EE\u9898\uFF0C\u4EE5\u53CA\u8BFB\u8005\u63A5\u4E0B\u6765\u8BE5\u5E26\u7740\u4EC0\u4E48\u7406\u89E3\u8DEF\u5F84\u7EE7\u7EED\u5F80\u4E0B\u770B\u3002"
|
|
17982
18065
|
}),
|
|
17983
|
-
|
|
17984
|
-
label: "
|
|
18066
|
+
teachingTip: Object.freeze({
|
|
18067
|
+
label: "teachingTip\uFF08\u8865\u5145\u8BF4\u660E\uFF09",
|
|
17985
18068
|
introHint: "\u5F00\u573A\u9898\u8981\u8865\u5145\u4E3A\u4EC0\u4E48\u5BB9\u6613\u8BEF\u89E3\uFF0C\u6216\u8005\u7B2C\u4E00\u6B21\u8BFB\u8FD9\u5757\u5185\u5BB9\u65F6\u5E94\u8BE5\u5148\u770B\u54EA\u91CC\u3002"
|
|
17986
18069
|
}),
|
|
17987
18070
|
explanation: Object.freeze({
|
|
@@ -18021,9 +18104,9 @@ function validateQuizPaperPayload(payload) {
|
|
|
18021
18104
|
assertMinLength(
|
|
18022
18105
|
step,
|
|
18023
18106
|
index,
|
|
18024
|
-
"
|
|
18025
|
-
DEFAULT_MIN_LENGTHS.
|
|
18026
|
-
FIELD_RULES.
|
|
18107
|
+
"teachingArticle",
|
|
18108
|
+
DEFAULT_MIN_LENGTHS.teachingArticle,
|
|
18109
|
+
FIELD_RULES.teachingArticle.defaultHint
|
|
18027
18110
|
);
|
|
18028
18111
|
assertMinLength(
|
|
18029
18112
|
step,
|
|
@@ -18038,16 +18121,16 @@ function validateQuizPaperPayload(payload) {
|
|
|
18038
18121
|
assertMinLength(
|
|
18039
18122
|
step,
|
|
18040
18123
|
index,
|
|
18041
|
-
"
|
|
18042
|
-
INTRO_MIN_LENGTHS.
|
|
18043
|
-
FIELD_RULES.
|
|
18124
|
+
"teachingArticle",
|
|
18125
|
+
INTRO_MIN_LENGTHS.teachingArticle,
|
|
18126
|
+
FIELD_RULES.teachingArticle.introHint
|
|
18044
18127
|
);
|
|
18045
18128
|
assertMinLength(
|
|
18046
18129
|
step,
|
|
18047
18130
|
index,
|
|
18048
|
-
"
|
|
18049
|
-
INTRO_MIN_LENGTHS.
|
|
18050
|
-
FIELD_RULES.
|
|
18131
|
+
"teachingTip",
|
|
18132
|
+
INTRO_MIN_LENGTHS.teachingTip,
|
|
18133
|
+
FIELD_RULES.teachingTip.introHint
|
|
18051
18134
|
);
|
|
18052
18135
|
assertMinLength(
|
|
18053
18136
|
step,
|
|
@@ -18195,6 +18278,131 @@ async function activateQuizPaper({
|
|
|
18195
18278
|
data: activated
|
|
18196
18279
|
};
|
|
18197
18280
|
}
|
|
18281
|
+
async function createQuizDraft({
|
|
18282
|
+
fetchImpl = fetch,
|
|
18283
|
+
apiBaseUrl,
|
|
18284
|
+
linkBaseUrl,
|
|
18285
|
+
paperId,
|
|
18286
|
+
token
|
|
18287
|
+
}) {
|
|
18288
|
+
const trimmedApiBaseUrl = apiBaseUrl.replace(/\/+$/, "");
|
|
18289
|
+
const trimmedLinkBaseUrl = linkBaseUrl.replace(/\/+$/, "");
|
|
18290
|
+
const previewLink = `${trimmedLinkBaseUrl}/?paper=${encodeURIComponent(paperId)}`;
|
|
18291
|
+
const data = await requestJson(
|
|
18292
|
+
fetchImpl,
|
|
18293
|
+
`${trimmedApiBaseUrl}/api/quiz/papers`,
|
|
18294
|
+
{
|
|
18295
|
+
method: "POST",
|
|
18296
|
+
headers: {
|
|
18297
|
+
Authorization: `Bearer ${token}`,
|
|
18298
|
+
"Content-Type": "application/json"
|
|
18299
|
+
},
|
|
18300
|
+
body: JSON.stringify({ paperId })
|
|
18301
|
+
},
|
|
18302
|
+
"\u521B\u5EFA\u8349\u7A3F"
|
|
18303
|
+
);
|
|
18304
|
+
return {
|
|
18305
|
+
apiBaseUrl: trimmedApiBaseUrl,
|
|
18306
|
+
paperId,
|
|
18307
|
+
previewLink,
|
|
18308
|
+
data
|
|
18309
|
+
};
|
|
18310
|
+
}
|
|
18311
|
+
async function updateQuizPaperMetadata({
|
|
18312
|
+
fetchImpl = fetch,
|
|
18313
|
+
apiBaseUrl,
|
|
18314
|
+
linkBaseUrl,
|
|
18315
|
+
paperId,
|
|
18316
|
+
metadata,
|
|
18317
|
+
token
|
|
18318
|
+
}) {
|
|
18319
|
+
const trimmedApiBaseUrl = apiBaseUrl.replace(/\/+$/, "");
|
|
18320
|
+
const trimmedLinkBaseUrl = linkBaseUrl.replace(/\/+$/, "");
|
|
18321
|
+
const previewLink = `${trimmedLinkBaseUrl}/?paper=${encodeURIComponent(paperId)}`;
|
|
18322
|
+
const data = await requestJson(
|
|
18323
|
+
fetchImpl,
|
|
18324
|
+
`${trimmedApiBaseUrl}/api/quiz/papers/${encodeURIComponent(paperId)}`,
|
|
18325
|
+
{
|
|
18326
|
+
method: "PATCH",
|
|
18327
|
+
headers: {
|
|
18328
|
+
Authorization: `Bearer ${token}`,
|
|
18329
|
+
"Content-Type": "application/json"
|
|
18330
|
+
},
|
|
18331
|
+
body: JSON.stringify(metadata)
|
|
18332
|
+
},
|
|
18333
|
+
"\u66F4\u65B0\u8BD5\u5377\u5143\u4FE1\u606F"
|
|
18334
|
+
);
|
|
18335
|
+
return {
|
|
18336
|
+
apiBaseUrl: trimmedApiBaseUrl,
|
|
18337
|
+
paperId,
|
|
18338
|
+
previewLink,
|
|
18339
|
+
data
|
|
18340
|
+
};
|
|
18341
|
+
}
|
|
18342
|
+
async function appendQuizPaperStep({
|
|
18343
|
+
fetchImpl = fetch,
|
|
18344
|
+
apiBaseUrl,
|
|
18345
|
+
linkBaseUrl,
|
|
18346
|
+
paperId,
|
|
18347
|
+
step,
|
|
18348
|
+
token
|
|
18349
|
+
}) {
|
|
18350
|
+
const trimmedApiBaseUrl = apiBaseUrl.replace(/\/+$/, "");
|
|
18351
|
+
const trimmedLinkBaseUrl = linkBaseUrl.replace(/\/+$/, "");
|
|
18352
|
+
const previewLink = `${trimmedLinkBaseUrl}/?paper=${encodeURIComponent(paperId)}`;
|
|
18353
|
+
const data = await requestJson(
|
|
18354
|
+
fetchImpl,
|
|
18355
|
+
`${trimmedApiBaseUrl}/api/quiz/papers/${encodeURIComponent(paperId)}/steps`,
|
|
18356
|
+
{
|
|
18357
|
+
method: "POST",
|
|
18358
|
+
headers: {
|
|
18359
|
+
Authorization: `Bearer ${token}`,
|
|
18360
|
+
"Content-Type": "application/json"
|
|
18361
|
+
},
|
|
18362
|
+
body: JSON.stringify(step)
|
|
18363
|
+
},
|
|
18364
|
+
`\u8FFD\u52A0\u9898\u76EE\uFF08${String(step?.stepId ?? "unknown-step")}\uFF09`
|
|
18365
|
+
);
|
|
18366
|
+
return {
|
|
18367
|
+
apiBaseUrl: trimmedApiBaseUrl,
|
|
18368
|
+
paperId,
|
|
18369
|
+
previewLink,
|
|
18370
|
+
data
|
|
18371
|
+
};
|
|
18372
|
+
}
|
|
18373
|
+
async function reorderQuizPaperSteps({
|
|
18374
|
+
fetchImpl = fetch,
|
|
18375
|
+
apiBaseUrl,
|
|
18376
|
+
linkBaseUrl,
|
|
18377
|
+
paperId,
|
|
18378
|
+
stepIds,
|
|
18379
|
+
token
|
|
18380
|
+
}) {
|
|
18381
|
+
const trimmedApiBaseUrl = apiBaseUrl.replace(/\/+$/, "");
|
|
18382
|
+
const trimmedLinkBaseUrl = linkBaseUrl.replace(/\/+$/, "");
|
|
18383
|
+
const previewLink = `${trimmedLinkBaseUrl}/?paper=${encodeURIComponent(paperId)}`;
|
|
18384
|
+
const data = await requestJson(
|
|
18385
|
+
fetchImpl,
|
|
18386
|
+
`${trimmedApiBaseUrl}/api/quiz/papers/${encodeURIComponent(paperId)}/steps/reorder`,
|
|
18387
|
+
{
|
|
18388
|
+
method: "POST",
|
|
18389
|
+
headers: {
|
|
18390
|
+
Authorization: `Bearer ${token}`,
|
|
18391
|
+
"Content-Type": "application/json"
|
|
18392
|
+
},
|
|
18393
|
+
body: JSON.stringify({
|
|
18394
|
+
stepIds
|
|
18395
|
+
})
|
|
18396
|
+
},
|
|
18397
|
+
"\u91CD\u6392\u9898\u76EE\u987A\u5E8F"
|
|
18398
|
+
);
|
|
18399
|
+
return {
|
|
18400
|
+
apiBaseUrl: trimmedApiBaseUrl,
|
|
18401
|
+
paperId,
|
|
18402
|
+
previewLink,
|
|
18403
|
+
data
|
|
18404
|
+
};
|
|
18405
|
+
}
|
|
18198
18406
|
async function viewQuizPaper({
|
|
18199
18407
|
fetchImpl = fetch,
|
|
18200
18408
|
apiBaseUrl,
|
|
@@ -18257,26 +18465,76 @@ var QuizCommandHandler = class {
|
|
|
18257
18465
|
const apiBaseUrl = args.apiBaseUrl || DEFAULT_QUIZ_API_BASE_URL;
|
|
18258
18466
|
const linkBaseUrl = args.linkBaseUrl || DEFAULT_QUIZ_LINK_BASE_URL;
|
|
18259
18467
|
if (args.action === "activate") {
|
|
18260
|
-
const
|
|
18468
|
+
const result = await activateQuizPaper({
|
|
18469
|
+
apiBaseUrl,
|
|
18470
|
+
linkBaseUrl,
|
|
18471
|
+
paperId: args.paperId,
|
|
18472
|
+
token: session.token
|
|
18473
|
+
});
|
|
18474
|
+
ui.success("Quiz \u5DF2\u6FC0\u6D3B\u53D1\u5E03", result.link);
|
|
18475
|
+
return;
|
|
18476
|
+
}
|
|
18477
|
+
if (args.action === "create-draft") {
|
|
18478
|
+
const result = await createQuizDraft({
|
|
18261
18479
|
apiBaseUrl,
|
|
18262
18480
|
linkBaseUrl,
|
|
18263
18481
|
paperId: args.paperId,
|
|
18264
18482
|
token: session.token
|
|
18265
18483
|
});
|
|
18266
|
-
ui.success("Quiz \
|
|
18484
|
+
ui.success("Quiz \u8349\u7A3F\u5DF2\u521B\u5EFA", result.previewLink);
|
|
18485
|
+
ui.info("\u72B6\u6001", "draft");
|
|
18486
|
+
return;
|
|
18487
|
+
}
|
|
18488
|
+
if (args.action === "update-meta") {
|
|
18489
|
+
const resolvedFilePath = import_node_path14.default.resolve(process.cwd(), args.filePath);
|
|
18490
|
+
const metadata = JSON.parse((0, import_node_fs9.readFileSync)(resolvedFilePath, "utf8"));
|
|
18491
|
+
const result = await updateQuizPaperMetadata({
|
|
18492
|
+
apiBaseUrl,
|
|
18493
|
+
linkBaseUrl,
|
|
18494
|
+
paperId: args.paperId,
|
|
18495
|
+
metadata,
|
|
18496
|
+
token: session.token
|
|
18497
|
+
});
|
|
18498
|
+
ui.success("Quiz \u5143\u4FE1\u606F\u5DF2\u66F4\u65B0", result.previewLink);
|
|
18499
|
+
return;
|
|
18500
|
+
}
|
|
18501
|
+
if (args.action === "append-step") {
|
|
18502
|
+
const resolvedFilePath = import_node_path14.default.resolve(process.cwd(), args.filePath);
|
|
18503
|
+
const step = JSON.parse((0, import_node_fs9.readFileSync)(resolvedFilePath, "utf8"));
|
|
18504
|
+
const result = await appendQuizPaperStep({
|
|
18505
|
+
apiBaseUrl,
|
|
18506
|
+
linkBaseUrl,
|
|
18507
|
+
paperId: args.paperId,
|
|
18508
|
+
step,
|
|
18509
|
+
token: session.token
|
|
18510
|
+
});
|
|
18511
|
+
ui.success("Quiz \u9898\u76EE\u5DF2\u8FFD\u52A0", result.previewLink);
|
|
18512
|
+
ui.info("stepId", String(step.stepId));
|
|
18513
|
+
return;
|
|
18514
|
+
}
|
|
18515
|
+
if (args.action === "reorder") {
|
|
18516
|
+
const result = await reorderQuizPaperSteps({
|
|
18517
|
+
apiBaseUrl,
|
|
18518
|
+
linkBaseUrl,
|
|
18519
|
+
paperId: args.paperId,
|
|
18520
|
+
stepIds: args.stepIds,
|
|
18521
|
+
token: session.token
|
|
18522
|
+
});
|
|
18523
|
+
ui.success("Quiz \u9898\u76EE\u987A\u5E8F\u5DF2\u66F4\u65B0", result.previewLink);
|
|
18524
|
+
ui.info("\u6570\u91CF", String(args.stepIds.length));
|
|
18267
18525
|
return;
|
|
18268
18526
|
}
|
|
18269
18527
|
if (args.action === "view") {
|
|
18270
|
-
const
|
|
18528
|
+
const result = await viewQuizPaper({
|
|
18271
18529
|
apiBaseUrl,
|
|
18272
18530
|
linkBaseUrl,
|
|
18273
18531
|
paperId: args.paperId,
|
|
18274
18532
|
token: session.token
|
|
18275
18533
|
});
|
|
18276
|
-
ui.success("Quiz \u8BD5\u5377\u5DF2\u627E\u5230",
|
|
18277
|
-
ui.info("\u72B6\u6001",
|
|
18278
|
-
if (typeof
|
|
18279
|
-
ui.info("\u9898\u76EE\u6570", String(
|
|
18534
|
+
ui.success("Quiz \u8BD5\u5377\u5DF2\u627E\u5230", result.previewLink);
|
|
18535
|
+
ui.info("\u72B6\u6001", result.paperStatus);
|
|
18536
|
+
if (typeof result.stepCount === "number") {
|
|
18537
|
+
ui.info("\u9898\u76EE\u6570", String(result.stepCount));
|
|
18280
18538
|
}
|
|
18281
18539
|
return;
|
|
18282
18540
|
}
|
|
@@ -18291,13 +18549,13 @@ var QuizCommandHandler = class {
|
|
|
18291
18549
|
if (targetIndex < 0) {
|
|
18292
18550
|
throw new Error(`\u672A\u627E\u5230 stepId=${args.stepId}\uFF0C\u65E0\u6CD5\u66F4\u65B0\u8BE5\u9898\u76EE\u3002`);
|
|
18293
18551
|
}
|
|
18294
|
-
const
|
|
18295
|
-
const nextStep = JSON.parse((0, import_node_fs9.readFileSync)(
|
|
18552
|
+
const resolvedFilePath = import_node_path14.default.resolve(process.cwd(), args.filePath);
|
|
18553
|
+
const nextStep = JSON.parse((0, import_node_fs9.readFileSync)(resolvedFilePath, "utf8"));
|
|
18296
18554
|
nextStep.stepId = args.stepId;
|
|
18297
18555
|
const nextSteps = [...basePaper.steps];
|
|
18298
18556
|
nextSteps[targetIndex] = nextStep;
|
|
18299
18557
|
const nextPaperId = args.newPaperId || `${args.paperId}-rev-${this.timestampTag()}`;
|
|
18300
|
-
const
|
|
18558
|
+
const result = await publishQuizPaper({
|
|
18301
18559
|
apiBaseUrl,
|
|
18302
18560
|
linkBaseUrl,
|
|
18303
18561
|
paperId: nextPaperId,
|
|
@@ -18311,37 +18569,20 @@ var QuizCommandHandler = class {
|
|
|
18311
18569
|
token: session.token,
|
|
18312
18570
|
activate: args.activate
|
|
18313
18571
|
});
|
|
18314
|
-
if (
|
|
18315
|
-
ui.success("Quiz \u5355\u9898\u4FEE\u8BA2\u7A3F\u5DF2\u521B\u5EFA",
|
|
18572
|
+
if (result.status === "draft") {
|
|
18573
|
+
ui.success("Quiz \u5355\u9898\u4FEE\u8BA2\u7A3F\u5DF2\u521B\u5EFA", result.previewLink);
|
|
18316
18574
|
ui.info("\u6765\u6E90\u8BD5\u5377", args.paperId);
|
|
18317
18575
|
ui.info("\u4FEE\u8BA2\u9898\u76EE", args.stepId);
|
|
18318
18576
|
ui.info("\u65B0\u8BD5\u5377", nextPaperId);
|
|
18319
18577
|
ui.info("\u4E0B\u4E00\u6B65", `pmate quiz activate --paper-id ${nextPaperId}`);
|
|
18320
18578
|
return;
|
|
18321
18579
|
}
|
|
18322
|
-
ui.success("Quiz \u5355\u9898\u4FEE\u8BA2\u7A3F\u5DF2\u53D1\u5E03",
|
|
18580
|
+
ui.success("Quiz \u5355\u9898\u4FEE\u8BA2\u7A3F\u5DF2\u53D1\u5E03", result.link);
|
|
18323
18581
|
ui.info("\u6765\u6E90\u8BD5\u5377", args.paperId);
|
|
18324
18582
|
ui.info("\u4FEE\u8BA2\u9898\u76EE", args.stepId);
|
|
18325
18583
|
ui.info("\u65B0\u8BD5\u5377", nextPaperId);
|
|
18326
18584
|
return;
|
|
18327
18585
|
}
|
|
18328
|
-
const resolvedFilePath = import_node_path14.default.resolve(process.cwd(), args.filePath);
|
|
18329
|
-
const payload = JSON.parse((0, import_node_fs9.readFileSync)(resolvedFilePath, "utf8"));
|
|
18330
|
-
const result = await publishQuizPaper({
|
|
18331
|
-
apiBaseUrl,
|
|
18332
|
-
linkBaseUrl,
|
|
18333
|
-
paperId: args.paperId,
|
|
18334
|
-
payload,
|
|
18335
|
-
token: session.token,
|
|
18336
|
-
activate: args.activate
|
|
18337
|
-
});
|
|
18338
|
-
if (result.status === "draft") {
|
|
18339
|
-
ui.success("Quiz \u8349\u7A3F\u5DF2\u521B\u5EFA", result.previewLink);
|
|
18340
|
-
ui.info("\u72B6\u6001", "draft");
|
|
18341
|
-
ui.info("\u4E0B\u4E00\u6B65", `pmate quiz activate --paper-id ${args.paperId}`);
|
|
18342
|
-
return;
|
|
18343
|
-
}
|
|
18344
|
-
ui.success("Quiz \u5DF2\u53D1\u5E03", result.link);
|
|
18345
18586
|
}
|
|
18346
18587
|
timestampTag() {
|
|
18347
18588
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -21992,7 +22233,10 @@ var HELP_TEXT = [
|
|
|
21992
22233
|
` ${import_chalk3.default.cyan("summary")} Summarize a GitHub PR with AI`,
|
|
21993
22234
|
` ${import_chalk3.default.gray(" --pr <id> [--cwd <dir>]")}`,
|
|
21994
22235
|
` ${import_chalk3.default.cyan("quiz")} Manage quiz papers on quiz-api`,
|
|
21995
|
-
` ${import_chalk3.default.gray("
|
|
22236
|
+
` ${import_chalk3.default.gray(" create-draft --paper-id <id>")}`,
|
|
22237
|
+
` ${import_chalk3.default.gray(" update-meta --paper-id <id> --file <metadata.json>")}`,
|
|
22238
|
+
` ${import_chalk3.default.gray(" append-step --paper-id <id> --file <step.json>")}`,
|
|
22239
|
+
` ${import_chalk3.default.gray(" reorder --paper-id <id> --step-ids <id1,id2,...>")}`,
|
|
21996
22240
|
` ${import_chalk3.default.gray(" activate --paper-id <id>")}`,
|
|
21997
22241
|
` ${import_chalk3.default.gray(" view --paper-id <id>")}`,
|
|
21998
22242
|
` ${import_chalk3.default.gray(" edit-step --paper-id <id> --step-id <step-id> --file <step.json> [--new-paper-id <id>] [--activate]")}`,
|
|
@@ -22592,50 +22836,158 @@ function parseQuizArgs(tokens) {
|
|
|
22592
22836
|
const rest = [...tokens];
|
|
22593
22837
|
const action = rest.shift();
|
|
22594
22838
|
if (!action) {
|
|
22595
|
-
throw new Error("Missing quiz action. Usage: quiz
|
|
22839
|
+
throw new Error("Missing quiz action. Usage: quiz create-draft|update-meta|append-step|reorder|activate|view|edit-step");
|
|
22596
22840
|
}
|
|
22597
|
-
if (action === "
|
|
22598
|
-
let filePath;
|
|
22841
|
+
if (action === "create-draft") {
|
|
22599
22842
|
let paperId;
|
|
22600
22843
|
let apiBaseUrl;
|
|
22601
22844
|
let linkBaseUrl;
|
|
22602
|
-
let activate = false;
|
|
22603
22845
|
while (rest.length > 0) {
|
|
22604
22846
|
const token = rest.shift();
|
|
22605
22847
|
switch (token) {
|
|
22848
|
+
case "--paper-id":
|
|
22849
|
+
paperId = requireValue8(rest, token);
|
|
22850
|
+
break;
|
|
22851
|
+
case "--base-url":
|
|
22852
|
+
apiBaseUrl = requireValue8(rest, token);
|
|
22853
|
+
break;
|
|
22854
|
+
case "--link-base":
|
|
22855
|
+
linkBaseUrl = requireValue8(rest, token);
|
|
22856
|
+
break;
|
|
22857
|
+
default:
|
|
22858
|
+
throw new Error(`Unknown quiz create-draft option: ${token}`);
|
|
22859
|
+
}
|
|
22860
|
+
}
|
|
22861
|
+
if (!paperId) {
|
|
22862
|
+
throw new Error("Missing --paper-id. Usage: quiz create-draft --paper-id <id>.");
|
|
22863
|
+
}
|
|
22864
|
+
return {
|
|
22865
|
+
type: "quiz" /* Quiz */,
|
|
22866
|
+
action: "create-draft",
|
|
22867
|
+
paperId,
|
|
22868
|
+
apiBaseUrl,
|
|
22869
|
+
linkBaseUrl
|
|
22870
|
+
};
|
|
22871
|
+
}
|
|
22872
|
+
if (action === "update-meta") {
|
|
22873
|
+
let paperId;
|
|
22874
|
+
let filePath;
|
|
22875
|
+
let apiBaseUrl;
|
|
22876
|
+
let linkBaseUrl;
|
|
22877
|
+
while (rest.length > 0) {
|
|
22878
|
+
const token = rest.shift();
|
|
22879
|
+
switch (token) {
|
|
22880
|
+
case "--paper-id":
|
|
22881
|
+
paperId = requireValue8(rest, token);
|
|
22882
|
+
break;
|
|
22606
22883
|
case "--file":
|
|
22607
22884
|
filePath = requireValue8(rest, token);
|
|
22608
22885
|
break;
|
|
22886
|
+
case "--base-url":
|
|
22887
|
+
apiBaseUrl = requireValue8(rest, token);
|
|
22888
|
+
break;
|
|
22889
|
+
case "--link-base":
|
|
22890
|
+
linkBaseUrl = requireValue8(rest, token);
|
|
22891
|
+
break;
|
|
22892
|
+
default:
|
|
22893
|
+
throw new Error(`Unknown quiz update-meta option: ${token}`);
|
|
22894
|
+
}
|
|
22895
|
+
}
|
|
22896
|
+
if (!paperId) {
|
|
22897
|
+
throw new Error("Missing --paper-id. Usage: quiz update-meta --paper-id <id> --file <metadata.json>.");
|
|
22898
|
+
}
|
|
22899
|
+
if (!filePath) {
|
|
22900
|
+
throw new Error("Missing --file. Usage: quiz update-meta --paper-id <id> --file <metadata.json>.");
|
|
22901
|
+
}
|
|
22902
|
+
return {
|
|
22903
|
+
type: "quiz" /* Quiz */,
|
|
22904
|
+
action: "update-meta",
|
|
22905
|
+
paperId,
|
|
22906
|
+
filePath,
|
|
22907
|
+
apiBaseUrl,
|
|
22908
|
+
linkBaseUrl
|
|
22909
|
+
};
|
|
22910
|
+
}
|
|
22911
|
+
if (action === "append-step") {
|
|
22912
|
+
let paperId;
|
|
22913
|
+
let filePath;
|
|
22914
|
+
let apiBaseUrl;
|
|
22915
|
+
let linkBaseUrl;
|
|
22916
|
+
while (rest.length > 0) {
|
|
22917
|
+
const token = rest.shift();
|
|
22918
|
+
switch (token) {
|
|
22609
22919
|
case "--paper-id":
|
|
22610
22920
|
paperId = requireValue8(rest, token);
|
|
22611
22921
|
break;
|
|
22922
|
+
case "--file":
|
|
22923
|
+
filePath = requireValue8(rest, token);
|
|
22924
|
+
break;
|
|
22612
22925
|
case "--base-url":
|
|
22613
22926
|
apiBaseUrl = requireValue8(rest, token);
|
|
22614
22927
|
break;
|
|
22615
22928
|
case "--link-base":
|
|
22616
22929
|
linkBaseUrl = requireValue8(rest, token);
|
|
22617
22930
|
break;
|
|
22618
|
-
case "--activate":
|
|
22619
|
-
activate = true;
|
|
22620
|
-
break;
|
|
22621
22931
|
default:
|
|
22622
|
-
throw new Error(`Unknown quiz
|
|
22932
|
+
throw new Error(`Unknown quiz append-step option: ${token}`);
|
|
22623
22933
|
}
|
|
22624
22934
|
}
|
|
22935
|
+
if (!paperId) {
|
|
22936
|
+
throw new Error("Missing --paper-id. Usage: quiz append-step --paper-id <id> --file <step.json>.");
|
|
22937
|
+
}
|
|
22625
22938
|
if (!filePath) {
|
|
22626
|
-
throw new Error("Missing --file. Usage: quiz
|
|
22939
|
+
throw new Error("Missing --file. Usage: quiz append-step --paper-id <id> --file <step.json>.");
|
|
22940
|
+
}
|
|
22941
|
+
return {
|
|
22942
|
+
type: "quiz" /* Quiz */,
|
|
22943
|
+
action: "append-step",
|
|
22944
|
+
paperId,
|
|
22945
|
+
filePath,
|
|
22946
|
+
apiBaseUrl,
|
|
22947
|
+
linkBaseUrl
|
|
22948
|
+
};
|
|
22949
|
+
}
|
|
22950
|
+
if (action === "reorder") {
|
|
22951
|
+
let paperId;
|
|
22952
|
+
let stepIdsRaw;
|
|
22953
|
+
let apiBaseUrl;
|
|
22954
|
+
let linkBaseUrl;
|
|
22955
|
+
while (rest.length > 0) {
|
|
22956
|
+
const token = rest.shift();
|
|
22957
|
+
switch (token) {
|
|
22958
|
+
case "--paper-id":
|
|
22959
|
+
paperId = requireValue8(rest, token);
|
|
22960
|
+
break;
|
|
22961
|
+
case "--step-ids":
|
|
22962
|
+
stepIdsRaw = requireValue8(rest, token);
|
|
22963
|
+
break;
|
|
22964
|
+
case "--base-url":
|
|
22965
|
+
apiBaseUrl = requireValue8(rest, token);
|
|
22966
|
+
break;
|
|
22967
|
+
case "--link-base":
|
|
22968
|
+
linkBaseUrl = requireValue8(rest, token);
|
|
22969
|
+
break;
|
|
22970
|
+
default:
|
|
22971
|
+
throw new Error(`Unknown quiz reorder option: ${token}`);
|
|
22972
|
+
}
|
|
22627
22973
|
}
|
|
22628
22974
|
if (!paperId) {
|
|
22629
|
-
throw new Error("Missing --paper-id. Usage: quiz
|
|
22975
|
+
throw new Error("Missing --paper-id. Usage: quiz reorder --paper-id <id> --step-ids <id1,id2,...>.");
|
|
22976
|
+
}
|
|
22977
|
+
if (!stepIdsRaw) {
|
|
22978
|
+
throw new Error("Missing --step-ids. Usage: quiz reorder --paper-id <id> --step-ids <id1,id2,...>.");
|
|
22979
|
+
}
|
|
22980
|
+
const stepIds = stepIdsRaw.split(",").map((item) => item.trim()).filter(Boolean);
|
|
22981
|
+
if (stepIds.length === 0) {
|
|
22982
|
+
throw new Error("Invalid --step-ids. At least one step id is required.");
|
|
22630
22983
|
}
|
|
22631
22984
|
return {
|
|
22632
22985
|
type: "quiz" /* Quiz */,
|
|
22633
|
-
action: "
|
|
22634
|
-
filePath,
|
|
22986
|
+
action: "reorder",
|
|
22635
22987
|
paperId,
|
|
22988
|
+
stepIds,
|
|
22636
22989
|
apiBaseUrl,
|
|
22637
|
-
linkBaseUrl
|
|
22638
|
-
activate
|
|
22990
|
+
linkBaseUrl
|
|
22639
22991
|
};
|
|
22640
22992
|
}
|
|
22641
22993
|
if (action === "activate") {
|