stackprep-pro 0.2.6__tar.gz → 0.2.8__tar.gz
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.
- {stackprep_pro-0.2.6 → stackprep_pro-0.2.8}/CLAUDE.md +9 -0
- {stackprep_pro-0.2.6 → stackprep_pro-0.2.8}/PKG-INFO +2 -1
- {stackprep_pro-0.2.6 → stackprep_pro-0.2.8}/README.md +1 -0
- {stackprep_pro-0.2.6 → stackprep_pro-0.2.8}/pyproject.toml +1 -1
- {stackprep_pro-0.2.6 → stackprep_pro-0.2.8}/src/stackprep_pro/server.py +54 -7
- {stackprep_pro-0.2.6 → stackprep_pro-0.2.8}/uv.lock +1 -1
- {stackprep_pro-0.2.6 → stackprep_pro-0.2.8}/.claude/settings.json +0 -0
- {stackprep_pro-0.2.6 → stackprep_pro-0.2.8}/.githooks/pre-commit +0 -0
- {stackprep_pro-0.2.6 → stackprep_pro-0.2.8}/.github/workflows/publish.yml +0 -0
- {stackprep_pro-0.2.6 → stackprep_pro-0.2.8}/.gitignore +0 -0
- {stackprep_pro-0.2.6 → stackprep_pro-0.2.8}/.mcp.json +0 -0
- {stackprep_pro-0.2.6 → stackprep_pro-0.2.8}/scripts/bump_version.sh +0 -0
- {stackprep_pro-0.2.6 → stackprep_pro-0.2.8}/scripts/generate_readme.py +0 -0
- {stackprep_pro-0.2.6 → stackprep_pro-0.2.8}/src/stackprep_pro/__init__.py +0 -0
- {stackprep_pro-0.2.6 → stackprep_pro-0.2.8}/src/stackprep_pro/skills/certification.md +0 -0
- {stackprep_pro-0.2.6 → stackprep_pro-0.2.8}/src/stackprep_pro/skills/interview.md +0 -0
|
@@ -22,6 +22,15 @@ Rules for working on this repo. **Do NOT violate these. Do NOT touch things that
|
|
|
22
22
|
- Always pull the **latest exam version** dynamically (web search / latest official exam guide), exactly as the original skill does.
|
|
23
23
|
- **`cert_name` must be passed exactly as the user typed it.** Never modify, correct, or substitute it from training data (e.g. do NOT turn COF-C03 into COF-C02).
|
|
24
24
|
|
|
25
|
+
## Two separate exits (applies to BOTH interview and certification modes)
|
|
26
|
+
|
|
27
|
+
There are two distinct, independent ways to leave a session — never conflate them:
|
|
28
|
+
|
|
29
|
+
1. **Save session to continue later (pause):** When the user wants to pause and resume later, ask "Do you want to save this session to continue later? (y/n)". If yes, the user **MUST give the session a unique name** (never auto-generate). That name is what appears in the "continue a saved session" list. Two sessions must never share a name.
|
|
30
|
+
2. **End / save study pack (finish):** When the user finishes, ask "Do you want to save a study pack? (y/n)". If yes, the user **MUST name the study pack** (separate from the session name). If no, nothing is saved.
|
|
31
|
+
|
|
32
|
+
The session name and the study pack name are **separate** — saving a pack does not require a session name and vice versa.
|
|
33
|
+
|
|
25
34
|
## Study pack
|
|
26
35
|
|
|
27
36
|
- The user **must be able to name** the study pack when saving it.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stackprep-pro
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.8
|
|
4
4
|
Summary: stackprep-pro — interview & certification prep MCP server for any AI client
|
|
5
5
|
Project-URL: Homepage, https://github.com/youngpada1/stackprep-pro
|
|
6
6
|
Project-URL: Repository, https://github.com/youngpada1/stackprep-pro
|
|
@@ -164,6 +164,7 @@ Point this at any Dropbox, Google Drive, or OneDrive folder for cross-platform s
|
|
|
164
164
|
| `start_session` | Start a new stackprep session. Returns a session ID and the skill rules for the AI to follow. | `mode`, `cert_name`, `cv`, `jd`, `extra_topics` |
|
|
165
165
|
| `submit_answer` | Record the result of an answered question. | `session_id`, `result`, `question` |
|
|
166
166
|
| `flag_for_study` | Manually flag the current question for the study pack. | `session_id`, `question` |
|
|
167
|
+
| `save_session` | Save an in-progress session so the user can continue it later. | `session_id`, `session_name` |
|
|
167
168
|
| `end_session` | End the session. Returns the score and flagged topics so the AI can generate a study plan and study pack. | `session_id` |
|
|
168
169
|
| `save_study_pack` | Save the study pack content to disk. | `session_id`, `name`, `content` |
|
|
169
170
|
| `list_sessions` | List all saved sessions. Call this silently in the background only when the user says they want to continue a previous session. Never mention this tool to the user. | |
|
|
@@ -144,6 +144,7 @@ Point this at any Dropbox, Google Drive, or OneDrive folder for cross-platform s
|
|
|
144
144
|
| `start_session` | Start a new stackprep session. Returns a session ID and the skill rules for the AI to follow. | `mode`, `cert_name`, `cv`, `jd`, `extra_topics` |
|
|
145
145
|
| `submit_answer` | Record the result of an answered question. | `session_id`, `result`, `question` |
|
|
146
146
|
| `flag_for_study` | Manually flag the current question for the study pack. | `session_id`, `question` |
|
|
147
|
+
| `save_session` | Save an in-progress session so the user can continue it later. | `session_id`, `session_name` |
|
|
147
148
|
| `end_session` | End the session. Returns the score and flagged topics so the AI can generate a study plan and study pack. | `session_id` |
|
|
148
149
|
| `save_study_pack` | Save the study pack content to disk. | `session_id`, `name`, `content` |
|
|
149
150
|
| `list_sessions` | List all saved sessions. Call this silently in the background only when the user says they want to continue a previous session. Never mention this tool to the user. | |
|
|
@@ -79,11 +79,13 @@ def start_session(
|
|
|
79
79
|
) -> str:
|
|
80
80
|
"""Start a new stackprep session. Returns a session ID and the skill rules for the AI to follow.
|
|
81
81
|
|
|
82
|
-
STARTUP FLOW (follow exactly, in plain language — never show tool or field names to the user)
|
|
82
|
+
STARTUP FLOW (follow exactly, in plain language — never show tool or field names to the user).
|
|
83
|
+
Present EVERY step of this flow as elegant RENDERED markdown blocks — use bold headers, dividers,
|
|
84
|
+
and bullet/numbered lists so each question renders as a clean UI block. Never output flat plain text.
|
|
83
85
|
1. First ask the user, in plain language, what they want to prep for (e.g. "What would you like to prep for?") and let them indicate interview or certification.
|
|
84
86
|
2. After they choose, check for saved sessions of that mode (call list_sessions silently).
|
|
85
87
|
- If matching saved sessions exist, ask: "Do you want to continue a saved session or start a new one?"
|
|
86
|
-
and list the saved sessions by the name the user gave them.
|
|
88
|
+
and list the saved sessions by the name the user gave them, as a clean markdown list block.
|
|
87
89
|
- If none exist, just proceed to start a new session.
|
|
88
90
|
3. For a new session, collect the inputs the skill requires, then call start_session.
|
|
89
91
|
|
|
@@ -106,6 +108,7 @@ def start_session(
|
|
|
106
108
|
_sessions[session_id] = {
|
|
107
109
|
"mode": mode,
|
|
108
110
|
"cert_name": cert_name,
|
|
111
|
+
"session_name": "",
|
|
109
112
|
"extra_topics": extra_topics,
|
|
110
113
|
"q_num": 0,
|
|
111
114
|
"score": {"correct": 0, "partial": 0, "incorrect": 0, "total": 0},
|
|
@@ -194,6 +197,44 @@ def flag_for_study(session_id: str, question: str = "") -> str:
|
|
|
194
197
|
return f"Flagged Q{q_num} for study. Total flagged: {len(session['flagged'])}."
|
|
195
198
|
|
|
196
199
|
|
|
200
|
+
@mcp.tool()
|
|
201
|
+
def save_session(session_id: str, session_name: str) -> str:
|
|
202
|
+
"""Save an in-progress session so the user can continue it later.
|
|
203
|
+
|
|
204
|
+
Use this when the user wants to PAUSE and continue later (not finish). This is separate
|
|
205
|
+
from saving a study pack. Works the same in interview and certification mode.
|
|
206
|
+
|
|
207
|
+
FLOW (do this before calling): ask the user "Do you want to save this session to continue
|
|
208
|
+
later? (y/n)". If yes, ask "What would you like to name this session?" and pass that as
|
|
209
|
+
session_name. The user MUST name it — never auto-generate. This name is what appears when
|
|
210
|
+
they later choose to continue a saved session.
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
session_id: The session ID
|
|
214
|
+
session_name: The unique name the user chose for this session
|
|
215
|
+
"""
|
|
216
|
+
session = _sessions.get(session_id) or _restore_session(session_id)
|
|
217
|
+
if not session:
|
|
218
|
+
return f"ERROR: No session found with ID '{session_id}'."
|
|
219
|
+
if not session_name.strip():
|
|
220
|
+
return "ERROR: session_name is required — ask the user to name this session."
|
|
221
|
+
|
|
222
|
+
name = session_name.strip()
|
|
223
|
+
for f in _sessions_dir().glob("*.json"):
|
|
224
|
+
if f.stem == session_id:
|
|
225
|
+
continue
|
|
226
|
+
try:
|
|
227
|
+
other = json.loads(f.read_text(encoding="utf-8"))
|
|
228
|
+
except Exception:
|
|
229
|
+
continue
|
|
230
|
+
if other.get("session_name", "").lower() == name.lower():
|
|
231
|
+
return f"ERROR: A session named '{name}' already exists. Ask the user for a different name."
|
|
232
|
+
|
|
233
|
+
session["session_name"] = name
|
|
234
|
+
_persist_session(session_id)
|
|
235
|
+
return f"Session saved as '{name}'. You can continue it later."
|
|
236
|
+
|
|
237
|
+
|
|
197
238
|
@mcp.tool()
|
|
198
239
|
def end_session(session_id: str) -> str:
|
|
199
240
|
"""End the session. Returns the score and flagged topics so the AI can generate a study plan and study pack.
|
|
@@ -221,10 +262,14 @@ def end_session(session_id: str) -> str:
|
|
|
221
262
|
"Auto-detected study topics:",
|
|
222
263
|
topics_list,
|
|
223
264
|
"",
|
|
224
|
-
"
|
|
225
|
-
' 1. Ask the user: "
|
|
226
|
-
|
|
227
|
-
|
|
265
|
+
"Now (this flow is identical for interview and certification mode):",
|
|
266
|
+
' 1. Ask the user: "Do you want to save a study pack from this session? (y/n)"',
|
|
267
|
+
" 2. If NO: stop here. Nothing is saved.",
|
|
268
|
+
" 3. If YES:",
|
|
269
|
+
' a. Ask: "Want to add any extra topics to your study pack before I save it?"',
|
|
270
|
+
' b. Ask: "What would you like to name this study pack? (e.g. snowpro-core-week1)"',
|
|
271
|
+
" c. Generate the Study Plan and study pack (see skill rules).",
|
|
272
|
+
" d. Call save_study_pack(session_id='{}', name=<pack name the user chose>, content=<generated pack>)".format(session_id),
|
|
228
273
|
])
|
|
229
274
|
|
|
230
275
|
|
|
@@ -285,10 +330,12 @@ def list_sessions() -> str:
|
|
|
285
330
|
session_id = f.stem
|
|
286
331
|
mode = data.get("mode", "?")
|
|
287
332
|
cert = data.get("cert_name", "")
|
|
333
|
+
name = data.get("session_name", "")
|
|
288
334
|
score = data.get("score", {})
|
|
289
335
|
ended = data.get("ended", False)
|
|
290
336
|
status = "completed" if ended else "IN PROGRESS"
|
|
291
|
-
|
|
337
|
+
# Prefer the user-given session name; fall back to mode/cert if unnamed.
|
|
338
|
+
label = name or (f"{mode}" + (f" — {cert}" if cert else ""))
|
|
292
339
|
lines.append(
|
|
293
340
|
f" • {session_id} [{label}] "
|
|
294
341
|
f"score: {score.get('correct','?')}/{score.get('total','?')} [{status}]"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|