stackprep-pro 0.2.6__tar.gz → 0.2.7__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.
@@ -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.6
3
+ Version: 0.2.7
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. | |
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "stackprep-pro"
3
- version = "0.2.6"
3
+ version = "0.2.7"
4
4
  description = "stackprep-pro — interview & certification prep MCP server for any AI client"
5
5
  readme = "README.md"
6
6
  license = { text = "MIT" }
@@ -106,6 +106,7 @@ def start_session(
106
106
  _sessions[session_id] = {
107
107
  "mode": mode,
108
108
  "cert_name": cert_name,
109
+ "session_name": "",
109
110
  "extra_topics": extra_topics,
110
111
  "q_num": 0,
111
112
  "score": {"correct": 0, "partial": 0, "incorrect": 0, "total": 0},
@@ -194,6 +195,44 @@ def flag_for_study(session_id: str, question: str = "") -> str:
194
195
  return f"Flagged Q{q_num} for study. Total flagged: {len(session['flagged'])}."
195
196
 
196
197
 
198
+ @mcp.tool()
199
+ def save_session(session_id: str, session_name: str) -> str:
200
+ """Save an in-progress session so the user can continue it later.
201
+
202
+ Use this when the user wants to PAUSE and continue later (not finish). This is separate
203
+ from saving a study pack. Works the same in interview and certification mode.
204
+
205
+ FLOW (do this before calling): ask the user "Do you want to save this session to continue
206
+ later? (y/n)". If yes, ask "What would you like to name this session?" and pass that as
207
+ session_name. The user MUST name it — never auto-generate. This name is what appears when
208
+ they later choose to continue a saved session.
209
+
210
+ Args:
211
+ session_id: The session ID
212
+ session_name: The unique name the user chose for this session
213
+ """
214
+ session = _sessions.get(session_id) or _restore_session(session_id)
215
+ if not session:
216
+ return f"ERROR: No session found with ID '{session_id}'."
217
+ if not session_name.strip():
218
+ return "ERROR: session_name is required — ask the user to name this session."
219
+
220
+ name = session_name.strip()
221
+ for f in _sessions_dir().glob("*.json"):
222
+ if f.stem == session_id:
223
+ continue
224
+ try:
225
+ other = json.loads(f.read_text(encoding="utf-8"))
226
+ except Exception:
227
+ continue
228
+ if other.get("session_name", "").lower() == name.lower():
229
+ return f"ERROR: A session named '{name}' already exists. Ask the user for a different name."
230
+
231
+ session["session_name"] = name
232
+ _persist_session(session_id)
233
+ return f"Session saved as '{name}'. You can continue it later."
234
+
235
+
197
236
  @mcp.tool()
198
237
  def end_session(session_id: str) -> str:
199
238
  """End the session. Returns the score and flagged topics so the AI can generate a study plan and study pack.
@@ -221,10 +260,14 @@ def end_session(session_id: str) -> str:
221
260
  "Auto-detected study topics:",
222
261
  topics_list,
223
262
  "",
224
- "Generate a Study Plan now (see skill rules), then:",
225
- ' 1. Ask the user: "Want to add any extra topics to your study pack before I save it?"',
226
- ' 2. Ask the user: "What would you like to name this study pack? (e.g. snowpro-core-week1)"',
227
- ' 3. Call save_study_pack(session_id=\'{}\', name=<name the user chose>, content=<generated pack>)'.format(session_id),
263
+ "Now (this flow is identical for interview and certification mode):",
264
+ ' 1. Ask the user: "Do you want to save a study pack from this session? (y/n)"',
265
+ " 2. If NO: stop here. Nothing is saved.",
266
+ " 3. If YES:",
267
+ ' a. Ask: "Want to add any extra topics to your study pack before I save it?"',
268
+ ' b. Ask: "What would you like to name this study pack? (e.g. snowpro-core-week1)"',
269
+ " c. Generate the Study Plan and study pack (see skill rules).",
270
+ " d. Call save_study_pack(session_id='{}', name=<pack name the user chose>, content=<generated pack>)".format(session_id),
228
271
  ])
229
272
 
230
273
 
@@ -285,10 +328,12 @@ def list_sessions() -> str:
285
328
  session_id = f.stem
286
329
  mode = data.get("mode", "?")
287
330
  cert = data.get("cert_name", "")
331
+ name = data.get("session_name", "")
288
332
  score = data.get("score", {})
289
333
  ended = data.get("ended", False)
290
334
  status = "completed" if ended else "IN PROGRESS"
291
- label = f"{mode}" + (f" {cert}" if cert else "")
335
+ # Prefer the user-given session name; fall back to mode/cert if unnamed.
336
+ label = name or (f"{mode}" + (f" — {cert}" if cert else ""))
292
337
  lines.append(
293
338
  f" • {session_id} [{label}] "
294
339
  f"score: {score.get('correct','?')}/{score.get('total','?')} [{status}]"
@@ -723,7 +723,7 @@ wheels = [
723
723
 
724
724
  [[package]]
725
725
  name = "stackprep-pro"
726
- version = "0.2.5"
726
+ version = "0.2.7"
727
727
  source = { editable = "." }
728
728
  dependencies = [
729
729
  { name = "mcp", extra = ["cli"] },
File without changes
File without changes