eklavya 1.65.0 → 1.66.0

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/README.md CHANGED
@@ -122,7 +122,7 @@ Its Learning page shows your streak and its calendar under the summary tiles; a
122
122
  waiting for a correction. The
123
123
  review queue gives each project a command to copy that starts Claude Code on its due
124
124
  concepts, in the project's folder when that folder is available.
125
- Its feature tips use Driver.js, bundled in `dist/` at build and served by the
125
+ Its feature tips show the archer companion and use Driver.js, bundled in `dist/` at build and served by the
126
126
  dashboard itself at `/vendor/driver-hints.js` and `/vendor/driver-hints.css`, so
127
127
  the page still requests nothing from another host. [Configuration](https://eklavya-run.web.app/docs/configuration/) lists
128
128
  defaults and scopes. The [memory guide](https://eklavya-run.web.app/docs/memory/)
@@ -879,10 +879,10 @@
879
879
  .coach .driver-popover-arrow-side-bottom { border-bottom-color:var(--spot); }
880
880
  .coach .driver-popover-title { position:absolute; width:1px; height:1px; overflow:hidden;
881
881
  clip-path:inset(50%); white-space:nowrap; }
882
- .coach .driver-popover-description { position:relative; margin:0 !important; padding:0 28px 0 30px;
882
+ .coach .driver-popover-description { position:relative; margin:0 !important; padding:0 28px 0 40px; min-height:28px;
883
883
  font-size:14px; line-height:1.45; color:var(--spot-ink); }
884
884
  .coach .driver-popover-description b { font-weight:600; }
885
- .coach__icon { position:absolute; left:0; top:1px; width:18px; height:18px; }
885
+ .coach__mascot { position:absolute; left:0; top:0; }
886
886
  .coach__x { position:absolute; z-index:1; top:8px; right:8px; width:24px; height:24px; padding:3px; border:0;
887
887
  background:none; color:var(--spot-ink); cursor:pointer; display:grid; place-items:center; }
888
888
  .coach__x svg { width:16px; height:16px; }
@@ -932,7 +932,6 @@
932
932
  <span>dashboard</span>
933
933
  </div>
934
934
  </a>
935
- <a href="/mascot.html" class="ek-companion ek-companion--rail"><eklavya-mascot state="info" variant="face" size="40"></eklavya-mascot><span>Meet your companion ↗</span></a>
936
935
 
937
936
  <div class="wf" id="wf">
938
937
  <a class="wf__main" id="wf-main" href="#/learning/dashboard"></a>
@@ -3153,7 +3152,7 @@ for (const ev of ['wheel', 'touchmove', 'keydown']) {
3153
3152
  it to data that makes it true. Order is priority. The browser suite's
3154
3153
  registry guard checks every row against the fixture. */
3155
3154
  const TIPS = [
3156
- { id: 'wf-switch', where: ['learning/dashboard'], el: '#wf-caret', side: 'right', title: 'Switch workflow',
3155
+ { id: 'wf-switch', where: ['learning/dashboard'], el: '#wf-caret', side: 'right', state: 'new', title: 'Switch workflow',
3157
3156
  text: 'Eklavya has five workflows: Learning, Memory, Artifacts, Feedback and Settings. Switch between them here.' },
3158
3157
  { id: 'how-this-works', where: ['learning/dashboard', 'memory/dashboard'], el: '#view details.about > summary', title: 'How this works',
3159
3158
  text: 'Every page explains where its numbers come from. Open this to read it.' },
@@ -3165,18 +3164,17 @@ const TIPS = [
3165
3164
  text: 'Due, missed and skipped answers each have their own list here.' },
3166
3165
  { id: 'timeline-open', where: ['memory/timeline'], el: '#view .tl-item > summary', title: 'Open an entry',
3167
3166
  text: 'Open a line to read what was remembered and the evidence it came from.' },
3168
- { id: 'to-correct', where: ['artifacts/dashboard'], el: '#view .chips [data-go*="to-correct"]', title: 'Answers to correct',
3167
+ { id: 'to-correct', where: ['artifacts/dashboard'], el: '#view .chips [data-go*="to-correct"]', state: 'review', title: 'Answers to correct',
3169
3168
  text: 'Missed answers wait here. Open one, read the page, then correct your answer.',
3170
3169
  when: () => (S.artifacts ?? []).some((a) => a.correction === 'open') },
3171
3170
  { id: 'artifact-tabs', where: ['artifacts/view'], el: '#view [role="tablist"]', title: 'Open pages',
3172
3171
  text: 'Pages you open stay here as tabs, up to eight. All artifacts takes you back.' },
3173
3172
  { id: 'settings-scope', where: ['settings/dashboard'], el: '.sw__scopes', side: 'left', title: 'User or project',
3174
3173
  text: 'User settings apply everywhere. Pick a project to override them for that project only.' },
3175
- { id: 'ground', where: ['settings/dashboard'], el: '.ground[aria-label="Colour ground"]', side: 'right', title: 'Ink or paper',
3174
+ { id: 'ground', where: ['settings/dashboard'], el: '.ground[aria-label="Colour ground"]', side: 'right', state: 'idle', title: 'Ink or paper',
3176
3175
  text: 'Switch the dashboard between a dark and a light ground.' },
3177
3176
  ];
3178
3177
  const TIPS_KEY = 'eklavya-dash-tips';
3179
- const ICON_TIP = '<svg class="coach__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/></svg>';
3180
3178
  const TIP = {
3181
3179
  state: undefined, // { off, done, opened }; null when storage throws, which means no tips
3182
3180
  hints: null,
@@ -3227,7 +3225,7 @@ const TIP = {
3227
3225
  element: n,
3228
3226
  popover: {
3229
3227
  title: esc(t.title),
3230
- description: `${ICON_TIP}<span><b>Tip:</b> ${esc(t.text)}</span>`,
3228
+ description: `<eklavya-mascot class="coach__mascot" state="${esc(t.state ?? 'tip')}" variant="face" size="28"></eklavya-mascot><span><b>Tip:</b> ${esc(t.text)}</span>`,
3231
3229
  side: t.side ?? 'bottom', align: 'start', buttonText: 'Got it', popoverClass: 'coach',
3232
3230
  onPopoverRender: (p) => {
3233
3231
  const x = document.createElement('button');
@@ -3576,7 +3574,7 @@ function drawSettings(d, scope) {
3576
3574
  const fields = d.fields.filter((f) => f.group === g);
3577
3575
  return { id: swTab(g), label: g, fields, n: file ? fields.filter((f) => Object.hasOwn(file.set, f.key)).length : 0 };
3578
3576
  });
3579
- tabs.push({ id: 'terminal', label: 'Terminal', n: 0 }, { id: 'changed', label: 'Changed', n: file ? Object.keys(file.set).length : 0 });
3577
+ tabs.push({ id: 'terminal', label: 'Terminal', n: 0 }, { id: 'companion', label: 'Companion', n: 0 }, { id: 'changed', label: 'Changed', n: file ? Object.keys(file.set).length : 0 });
3580
3578
  const here = tabs.find((t) => t.id === CUR.param) ?? tabs[0];
3581
3579
 
3582
3580
  const scopeLink = (label, icon, to, current) =>
@@ -3613,6 +3611,9 @@ function drawSettings(d, scope) {
3613
3611
  body = card('Changed from the terminal', 'These send work off this machine or run a command, so they stay a typed command: eklavya config set <key> <value>.',
3614
3612
  lines(d.cli_only.map((c) => ({ t: `<code>${esc(c.key)}</code>`, s: esc(c.why),
3615
3613
  v: `<span class="mono">${esc(showValue(file.effective[c.key]))}</span>` }))));
3614
+ } else if (here.id === 'companion') {
3615
+ body = card('Your companion', 'The mascot that appears in tips, loaders and empty pages. The gallery shows every expression, both grounds and the loading animation.',
3616
+ `<div class="ek-companion"><eklavya-mascot state="info" size="72"></eklavya-mascot><a class="link" href="/mascot.html">Open the companion gallery ↗</a></div>`);
3616
3617
  } else if (here.id === 'changed') {
3617
3618
  const tabOf = (k) => { const f = d.fields.find((x) => x.key === k); return f ? swTab(f.group) : 'terminal'; };
3618
3619
  body = card(`Set ${scope === 'project' ? 'for this project' : 'by you'}`,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "eklavya",
3
3
  "displayName": "Eklavya",
4
- "version": "1.65.0",
4
+ "version": "1.66.0",
5
5
  "description": "Learn while your agent works. Turns coding-agent generation time into adaptive, Socratic learning grounded in the code being written.",
6
6
  "author": {
7
7
  "name": "Ajay Kumar"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eklavya",
3
- "version": "1.65.0",
3
+ "version": "1.66.0",
4
4
  "description": "Learn while your agent works — local knowledge graph, spaced repetition, and quiz gating for agent-assisted development.",
5
5
  "license": "MIT",
6
6
  "repository": {