incremnt 0.8.6 → 0.8.8

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 (61) hide show
  1. package/README.md +2 -1
  2. package/SKILL.md +2 -1
  3. package/package.json +4 -1
  4. package/src/ask-answer-verifier.js +24 -3
  5. package/src/ask-coach/contexts.js +1472 -0
  6. package/src/ask-coach/evidence-plan.js +342 -0
  7. package/src/ask-coach/observations.js +8 -0
  8. package/src/ask-coach/orchestrator.js +1641 -0
  9. package/src/ask-coach/renderers.js +4 -0
  10. package/src/ask-coach/routing.js +610 -0
  11. package/src/ask-coach/structured-response.js +5 -0
  12. package/src/ask-coach-routing.js +4 -0
  13. package/src/ask-coach.js +26 -3446
  14. package/src/ask-replay.js +70 -4
  15. package/src/ask-starter-prompts.js +206 -0
  16. package/src/auth.js +26 -0
  17. package/src/coach-advice.js +32 -0
  18. package/src/coach-facts.js +214 -0
  19. package/src/coach-prompt-layers.js +26 -30
  20. package/src/contract.js +27 -7
  21. package/src/exercise-aliases.js +6 -0
  22. package/src/format.js +17 -0
  23. package/src/index.js +1 -1
  24. package/src/lib.js +41 -36
  25. package/src/mcp.js +1 -1
  26. package/src/openrouter.js +310 -162
  27. package/src/plan-changeset.js +14 -8
  28. package/src/program-draft.js +97 -1
  29. package/src/prompt-changelog.js +16 -0
  30. package/src/prompt-security.js +34 -3
  31. package/src/promptfoo-evals.js +2 -0
  32. package/src/promptfoo-langfuse-scores.js +10 -0
  33. package/src/prompts/ask.js +22 -0
  34. package/src/prompts/checkpoint.js +14 -0
  35. package/src/prompts/coach-facts.js +24 -0
  36. package/src/prompts/cycle.js +23 -0
  37. package/src/prompts/starter-graph.js +7 -0
  38. package/src/prompts/vitals.js +9 -0
  39. package/src/prompts/weekly-checkin.js +20 -0
  40. package/src/prompts/workout.js +47 -0
  41. package/src/queries/coach-observations.js +8 -0
  42. package/src/queries/coach-read-tools.js +6 -0
  43. package/src/queries/commands.js +3 -0
  44. package/src/queries/common.js +9 -0
  45. package/src/queries/core.js +6354 -0
  46. package/src/queries/exercise-identity.js +6 -0
  47. package/src/queries/health.js +12 -0
  48. package/src/queries/programs.js +17 -0
  49. package/src/queries/records-progress.js +10 -0
  50. package/src/queries/sessions.js +12 -0
  51. package/src/queries/weekly.js +5 -0
  52. package/src/queries.js +10 -6210
  53. package/src/remote.js +51 -0
  54. package/src/score-context.js +58 -3
  55. package/src/score-prelude.js +9 -12
  56. package/src/summary-evals.js +202 -54
  57. package/src/sync-service.js +1118 -104
  58. package/src/training-language-public-terms.json +97 -0
  59. package/src/training-language.js +94 -0
  60. package/src/transport.js +7 -1
  61. package/src/validate.js +11 -1
package/README.md CHANGED
@@ -110,6 +110,7 @@ incremnt login --session-file ~/Downloads/session.json
110
110
  | `coach observations list` | Current persisted coach observations |
111
111
  | `coach observations seen --id <id>` | Mark a coach observation as seen |
112
112
  | `coach observations dismiss --id <id>` | Dismiss an observation and suppress matching follow-ups |
113
+ | `programs create --file <file>` | Create an inactive saved program from generated-plan JSON |
113
114
  | `programs propose --file <file>` | Submit a program proposal |
114
115
  | `programs proposals` | List proposals |
115
116
  | `programs proposal dismiss --id <id>` | Dismiss a proposal |
@@ -201,7 +202,7 @@ Read-only agent tokens can call read tools. Write tools return structured JSON w
201
202
 
202
203
  The MCP server exposes two tool families:
203
204
 
204
- - Command-shaped tools from the public CLI contract, including sessions, programs, cycles, goals, health, training load, ask history/show, `increment-score-current`, `increment-score-history`, `increment-score-upload`, `coach-observations-current`, program proposals, and program shares.
205
+ - Command-shaped tools from the public CLI contract, including sessions, programs, cycles, goals, health, training load, ask history/show, `increment-score-current`, `increment-score-history`, `increment-score-upload`, `coach-observations-current`, inactive generated program creation, program proposals, and program shares.
205
206
  - Typed coach read tools for agent-native context retrieval, including `get_increment_score`, `get_recent_sessions`, `get_exercise_history`, `get_next_session`, `get_readiness_snapshot`, `get_body_weight_snapshot`, `get_goal_status`, and `get_records`.
206
207
 
207
208
  `get_increment_score` returns the same privacy-safe score summary as `increment-score current`: score, snapshot timestamp, formula version, data tier, component scores, positive/negative drivers, day-over-day delta, recent trend, and data-quality flags. It does not expose raw HealthKit values.
package/SKILL.md CHANGED
@@ -26,6 +26,7 @@ Append `--dry-run` to any mutating command to preview the HTTP request as `{ dry
26
26
 
27
27
  | Command | Reversibility | Notes |
28
28
  |---|---|---|
29
+ | `programs create --file <f>` | Reversible in iOS (created inactive) | Creates a saved inactive program from Coach-compatible generated-plan JSON. It does not activate or replace the current plan. Use `records` or `exercises history` first for canonical names. |
29
30
  | `programs propose --file <f>` | Reversible (proposal stays pending) | Weights omitted; iOS computes from history. Names must come from `records` or `exercises history`. |
30
31
  | `programs proposals` | Read-only lookup | Use before dismissing a proposal. |
31
32
  | `programs proposal dismiss --id <id>` | Irreversible | IDs come from `programs proposals`. |
@@ -41,7 +42,7 @@ Confirm with the user before any mutating command unless they explicitly authori
41
42
  ## Read commands worth knowing
42
43
 
43
44
  - `sessions list` → `sessions show --id <id>` → `sessions compare --session-id <id>` / `sessions explain --session-id <id>` is the typical drill-down.
44
- - `records` is the cheapest way to discover the canonical exercise names a user has actually trained. Use it before composing a `programs propose` payload.
45
+ - `records` is the cheapest way to discover the canonical exercise names a user has actually trained. Use it before composing a `programs create` or `programs propose` payload.
45
46
  - `exercises history --name "Bench Press"` uses canonical synonym matching — it finds `Barbell Bench Press` without pulling in incline/dumbbell variants.
46
47
  - `increment-score current` returns a privacy-safe summary only (score, components, drivers, trend, data-quality flags) — no raw HealthKit values.
47
48
  - `coach observations list` returns persisted coach insights generated from training patterns. MCP exposes this read surface as `coach-observations-current`; seen/dismiss writes stay CLI/API-only.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incremnt",
3
- "version": "0.8.6",
3
+ "version": "0.8.8",
4
4
  "description": "Command-line tool for querying your incremnt strength training data",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -36,8 +36,11 @@
36
36
  "postinstall": "node -e \"process.stdout.write('\\n incremnt MCP server installed.\\n Run: incremnt mcp install\\n to register it with Claude and Codex.\\n\\n')\""
37
37
  },
38
38
  "dependencies": {
39
+ "@langchain/core": "^1.2.0",
40
+ "@langchain/langgraph": "^1.4.4",
39
41
  "@langfuse/tracing": "^5.2.0",
40
42
  "@modelcontextprotocol/sdk": "^1.12.1",
43
+ "@opentelemetry/api": "^1.9.1",
41
44
  "chalk": "^5.6.2",
42
45
  "ink": "^7.0.1",
43
46
  "openai": "^6.34.0",
@@ -257,6 +257,21 @@ function evidenceRows(toolResults = []) {
257
257
  return rows;
258
258
  }
259
259
 
260
+ function plannedProgramRows(snapshot) {
261
+ const rows = [];
262
+ for (const program of snapshot?.programs ?? []) {
263
+ for (const day of program.days ?? []) {
264
+ for (const exercise of day.exercises ?? []) {
265
+ addEvidenceRow(rows, 'current_program', {
266
+ exerciseName: exercise?.exerciseName ?? exercise?.name,
267
+ sets: Array.isArray(exercise?.sets) ? exercise.sets : []
268
+ });
269
+ }
270
+ }
271
+ }
272
+ return rows;
273
+ }
274
+
260
275
  function replayAskToolResults(snapshot, routingMetadata = {}, { today = new Date(), exclude = [], executeTool = executeCoachReadTool } = {}) {
261
276
  const results = [];
262
277
  const failures = [];
@@ -534,7 +549,10 @@ function declineLanguage(window) {
534
549
  const text = normalizeText(window);
535
550
  const decline = /\b(drop(?:ped|ping|s)?(?: off)?|drop-off|declin(?:e|ed|ing)|regress(?:ed|ion|ing)?|fell|fall(?:ing)?|decreas(?:e|ed|ing)|lower|worse|slid|slipped)\b/i;
536
551
  if (!decline.test(text)) return false;
537
- if (/\b(?:no|not|isn'?t|wasn'?t|without|rather than)\b.{0,45}\b(drop(?:ped|ping|s)?(?: off)?|drop-off|declin(?:e|ed|ing)?|decreas(?:e|ed|ing)?|regress(?:ed|ion|ing)?|fall(?:ing)?|fell|lower|worse|slid|slipped)\b/i.test(text)) return false;
552
+ if (/\b(?:volume|tonnage|work rate|work done|weekly work)\b.{0,80}\b(drop(?:ped|ping|s)?(?: off)?|drop-off|declin(?:e|ed|ing)?|decreas(?:e|ed|ing)?|fell|fall(?:ing)?|lower|down|dip(?:ped)?|pullback)\b/i.test(text)) return false;
553
+ if (/\b(drop(?:ped|ping|s)?(?: off)?|drop-off|declin(?:e|ed|ing)?|decreas(?:e|ed|ing)?|fell|fall(?:ing)?|lower|down|dip(?:ped)?|pullback)\b.{0,80}\b(?:volume|tonnage|work rate|work done|weekly work)\b/i.test(text)) return false;
554
+ if (/\b(?:no|not|isn'?t|wasn'?t|weren'?t|doesn'?t|don'?t|didn'?t|without|rather than)\b.{0,60}\b(drop(?:ped|ping|s)?(?: off)?|drop-off|declin(?:e|ed|ing)?|decreas(?:e|ed|ing)?|regress(?:ed|ion|ing)?|fall(?:ing)?|fell|lower|worse|slid|slipped)\b/i.test(text)) return false;
555
+ if (/\b(drop(?:ped|ping|s)?(?: off)?|drop-off|declin(?:e|ed|ing)?|decreas(?:e|ed|ing)?|regress(?:ed|ion|ing)?|fall(?:ing)?|fell|lower|worse|slid|slipped)\b.{0,60}\b(?:no|not|isn'?t|wasn'?t|weren'?t|doesn'?t|don'?t|didn'?t)\b/i.test(text)) return false;
538
556
  if (/\b(?:rep|reps)\b.{0,20}\b(drop(?:ped|ping|s)?(?: off)?|drop-off|slip(?:ped|ping)?|fell|fall(?:ing)?|lower|declin(?:e|ed|ing)?|decreas(?:e|ed|ing)?|worse)\b/i.test(text)) return false;
539
557
  return true;
540
558
  }
@@ -658,7 +676,10 @@ function checkToolProvenance(answer, snapshot, routingMetadata, {
658
676
  const { toolResults, replayFailures } = replayAskToolResults(snapshot, routingMetadata, { today, exclude, executeTool });
659
677
  failures.push(...replayFailures);
660
678
 
661
- const rows = evidenceRows(toolResults);
679
+ const rows = [
680
+ ...evidenceRows(toolResults),
681
+ ...plannedProgramRows(snapshot)
682
+ ];
662
683
  const mentions = findAskAnswerExerciseMentions(answer, snapshot);
663
684
  const toolsUsed = routedToolNames(routingMetadata);
664
685
  const normalized = normalizeText(answer);
@@ -1033,7 +1054,7 @@ export function buildAskAnswerRepairContext(context, _draftAnswer, verification)
1033
1054
  }
1034
1055
 
1035
1056
  export function safeAskVerificationFallback() {
1036
- return 'I can’t answer that safely from the evidence I just checked. The draft answer included training claims I could not verify, so I’m not going to guess. Ask me about a specific session or lift and I’ll re-check the data.';
1057
+ return 'I don’t have enough reliable data to answer that clearly. Ask me about a specific lift or session and I’ll check it.';
1037
1058
  }
1038
1059
 
1039
1060
  // Graceful degrade: rather than refusing a whole answer for one unsupported