eklavya 1.19.0 → 1.19.2
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 +1 -1
- package/dist/assets/dashboard.html +11 -1
- package/dist/assets/tutor/SKILL.md +5 -5
- package/dist/assets/tutor/references/focus-and-level.md +5 -5
- package/dist/assets/tutor/references/grading.md +1 -1
- package/dist/cli.js +126 -42
- package/dist/cli.js.map +1 -1
- package/dist/config.js +260 -72
- package/dist/config.js.map +1 -1
- package/dist/dashboard.js +2 -1
- package/dist/dashboard.js.map +1 -1
- package/dist/hooks/checkpoint-quiz.js +6 -4
- package/dist/hooks/checkpoint-quiz.js.map +1 -1
- package/dist/hooks/pre-tool-gate.js +2 -2
- package/dist/hooks/pre-tool-gate.js.map +1 -1
- package/dist/hooks/prompt-submit-nudge.js +7 -6
- package/dist/hooks/prompt-submit-nudge.js.map +1 -1
- package/dist/hooks/session-start.js +76 -22
- package/dist/hooks/session-start.js.map +1 -1
- package/dist/hooks/stop-quiz-check.js +32 -38
- package/dist/hooks/stop-quiz-check.js.map +1 -1
- package/dist/hooks/subagent-start.js +2 -2
- package/dist/hooks/subagent-start.js.map +1 -1
- package/dist/memory/sync.js +1 -1
- package/dist/packs.js +26 -12
- package/dist/packs.js.map +1 -1
- package/dist/paths.js +60 -0
- package/dist/paths.js.map +1 -1
- package/dist/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/plugin/cli/CLAUDE.md +32 -8
- package/dist/plugin/cli/eklavya-gate +80 -9
- package/dist/plugin/hooks/CLAUDE.md +40 -21
- package/dist/plugin/scripts/install-git-hook.sh +2 -1
- package/dist/plugin/skills/CLAUDE.md +12 -10
- package/dist/plugin/skills/gate/SKILL.md +1 -1
- package/dist/plugin/skills/level/SKILL.md +3 -3
- package/dist/plugin/skills/mode/SKILL.md +24 -16
- package/dist/plugin/skills/pack/SKILL.md +8 -4
- package/dist/plugin/skills/progress/SKILL.md +1 -1
- package/dist/plugin/skills/quiz/SKILL.md +2 -2
- package/dist/plugin/skills/setup/SKILL.md +12 -12
- package/dist/plugin/skills/tutor/SKILL.md +5 -5
- package/dist/plugin/skills/tutor/references/focus-and-level.md +5 -5
- package/dist/plugin/skills/tutor/references/grading.md +1 -1
- package/dist/session.js +1 -1
- package/dist/statusline.js +20 -6
- package/dist/statusline.js.map +1 -1
- package/dist/store.js +2 -2
- package/dist/store.js.map +1 -1
- package/dist/surface.js +1 -1
- package/dist/tools/config_tools.js +82 -52
- package/dist/tools/config_tools.js.map +1 -1
- package/dist/tools/get_learner_profile.js +2 -1
- package/dist/tools/get_learner_profile.js.map +1 -1
- package/dist/tools/get_session_quiz_plan.js +15 -9
- package/dist/tools/get_session_quiz_plan.js.map +1 -1
- package/dist/tools/types.js +1 -1
- package/dist/tools/types.js.map +1 -1
- package/dist/user-skill/eklavya/SKILL.md +35 -21
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkpoint-quiz.js","sourceRoot":"","sources":["../../src/hooks/checkpoint-quiz.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACjG,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;IACxB,0EAA0E;IAC1E,8EAA8E;IAC9E,2EAA2E;IAC3E,gEAAgE;IAChE,IAAI,KAAK,CAAC,QAAQ;QAAE,OAAO,CAAC,CAAC;IAE7B,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;IAC1B,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,CAAC;IAElB,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IACzB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,sBAAsB,EAAE,+BAA+B,EAAE,GAClG,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IAErB,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"checkpoint-quiz.js","sourceRoot":"","sources":["../../src/hooks/checkpoint-quiz.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,7 +22,7 @@ await run(async (input) => {
|
|
|
22
22
|
if (!COMMIT.test(command))
|
|
23
23
|
return 0;
|
|
24
24
|
const cwd = cwdOf(input);
|
|
25
|
-
if (config(cwd).config.
|
|
25
|
+
if (!config(cwd).config.quiz.enforced)
|
|
26
26
|
return 0;
|
|
27
27
|
const db = openExisting();
|
|
28
28
|
if (!db)
|
|
@@ -47,7 +47,7 @@ await run(async (input) => {
|
|
|
47
47
|
const silenced = isSessionOff(db, sid);
|
|
48
48
|
const reason = `Eklavya gate: this session's quiz has not been passed yet (${gate.answered} of ${gate.required} concepts answered). ` +
|
|
49
49
|
(silenced
|
|
50
|
-
? '
|
|
50
|
+
? 'Questions are off for this session, so the quiz cannot run until they are back on: set_config with scope "session" and quiz {enabled: true}, then run the quiz — '
|
|
51
51
|
: 'Run the quiz first — ') +
|
|
52
52
|
'get_session_quiz_plan, ask one question at a time, grade each answer with record_attempt — ' +
|
|
53
53
|
'then retry the commit. Nothing else is blocked.';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pre-tool-gate.js","sourceRoot":"","sources":["../../src/hooks/pre-tool-gate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,MAAM,GAAG,mEAAmE,CAAC;AAEnF,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;IACxB,4EAA4E;IAC5E,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,EAAE,OAAO,CAAC;IAC1C,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,CAAC;IACtD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,CAAC,CAAC;IAEpC,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IACzB,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"pre-tool-gate.js","sourceRoot":"","sources":["../../src/hooks/pre-tool-gate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,MAAM,GAAG,mEAAmE,CAAC;AAEnF,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;IACxB,4EAA4E;IAC5E,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,EAAE,OAAO,CAAC;IAC1C,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,CAAC;IACtD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,CAAC,CAAC;IAEpC,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IACzB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ;QAAE,OAAO,CAAC,CAAC;IAEhD,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;IAC1B,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,CAAC;IAElB,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACjC,IAAI,CAAC,GAAG;QAAE,OAAO,CAAC,CAAC;IAEnB,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CAAC,mEAAmE,CAAC;SAC5E,GAAG,CAAC,GAAG,CAAuE,CAAC;IAElF,4EAA4E;IAC5E,wDAAwD;IACxD,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IACpB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAEhC,2EAA2E;IAC3E,2EAA2E;IAC3E,qEAAqE;IACrE,2EAA2E;IAC3E,0CAA0C;IAC1C,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAEvC,MAAM,MAAM,GACV,8DAA8D,IAAI,CAAC,QAAQ,OAAO,IAAI,CAAC,QAAQ,uBAAuB;QACtH,CAAC,QAAQ;YACP,CAAC,CAAC,mKAAmK;YACrK,CAAC,CAAC,uBAAuB,CAAC;QAC5B,6FAA6F;QAC7F,iDAAiD,CAAC;IAEpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,IAAI,CAAC,SAAS,CAAC;QAChB,kBAAkB,EAAE;YAClB,aAAa,EAAE,YAAY;YAC3B,kBAAkB,EAAE,MAAM;YAC1B,wBAAwB,EAAE,MAAM;SACjC;KACF,CAAC,IAAI,CACP,CAAC;IACF,OAAO,CAAC,CAAC;AACX,CAAC,CAAC,CAAC"}
|
|
@@ -109,11 +109,12 @@ await run(async (input) => {
|
|
|
109
109
|
// small JSON files is the cheaper question, so it is asked first.
|
|
110
110
|
const cwd = cwdOf(input);
|
|
111
111
|
const resolved = config(cwd);
|
|
112
|
-
const {
|
|
113
|
-
// `
|
|
114
|
-
// someone who asked for no quizzes did not ask for their project
|
|
115
|
-
// stop being recorded (PRD CFG-01) -- so the early return needs
|
|
116
|
-
|
|
112
|
+
const { quiz } = resolved.config;
|
|
113
|
+
// `quiz.enabled: false` silences the learning half. It does not stop memory
|
|
114
|
+
// capture -- someone who asked for no quizzes did not ask for their project
|
|
115
|
+
// history to stop being recorded (PRD CFG-01) -- so the early return needs
|
|
116
|
+
// both switches off, which is exactly the pair of names the config now uses.
|
|
117
|
+
if (!quiz.enabled && !resolved.config.memory.enabled)
|
|
117
118
|
return 0;
|
|
118
119
|
// `quiet` is deliberately NOT consulted. It suppresses the banner and the
|
|
119
120
|
// status bar -- things the developer looks at -- and this is an
|
|
@@ -159,7 +160,7 @@ await run(async (input) => {
|
|
|
159
160
|
if (recalled)
|
|
160
161
|
context.push(recalled);
|
|
161
162
|
}
|
|
162
|
-
if (
|
|
163
|
+
if (!quiz.enabled)
|
|
163
164
|
return emit(context);
|
|
164
165
|
if (isSessionOff(db, sid))
|
|
165
166
|
return emit(context);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-submit-nudge.js","sourceRoot":"","sources":["../../src/hooks/prompt-submit-nudge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,OAAO,EACL,GAAG,EACH,YAAY,EACZ,MAAM,EACN,KAAK,EACL,SAAS,EACT,YAAY,EACZ,gBAAgB,GAEjB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEhF;;;;;GAKG;AACH,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB,8DAA8D;AAC9D,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAE5B;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,GAAG,CAAC,CAAC;AAErB;;;;;;GAMG;AACH,SAAS,SAAS,CAAC,EAAM,EAAE,GAAW;IACpC,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC,GAAG,CAAC,GAAG,CAEzD,CAAC;IACd,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;AACtE,CAAC;AAED,SAAS,UAAU,CAAC,EAAM,EAAE,GAAW,EAAE,KAAa,EAAE,MAAqB,EAAE,KAAa;IAC1F,EAAE,CAAC,OAAO,CAAC,mGAAmG,CAAC,CAAC,GAAG,CACjH,GAAG,EACH,GAAG,KAAK,IAAI,MAAM,IAAI,EAAE,IAAI,KAAK,EAAE,CACpC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,KAAK,CAAC,EAAM;IACnB,EAAE,CAAC,OAAO,CACR;;yDAEqD,CACtD,CAAC,GAAG,CAAC,GAAG,gBAAgB,GAAG,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;IACxB,6EAA6E;IAC7E,4EAA4E;IAC5E,iDAAiD;IACjD,IAAI,KAAK,CAAC,QAAQ;QAAE,OAAO,CAAC,CAAC;IAE7B,6EAA6E;IAC7E,8EAA8E;IAC9E,0EAA0E;IAC1E,kEAAkE;IAClE,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IACzB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7B,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC;IACjC,
|
|
1
|
+
{"version":3,"file":"prompt-submit-nudge.js","sourceRoot":"","sources":["../../src/hooks/prompt-submit-nudge.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Hard rule: this must never break a session. Every failure path
|
|
5
5
|
* exits 0 with no output — `run()` enforces it.
|
|
6
6
|
*/
|
|
7
|
+
import { findRepoConfig, mainRepoRoot, migrateLegacyRepoConfig } from '../config.js';
|
|
7
8
|
import { isSessionOff, setCurrentSession } from '../session.js';
|
|
8
9
|
import { levelStanding } from '../store.js';
|
|
9
10
|
import { isCowork, withSurfaceNote } from '../surface.js';
|
|
@@ -33,24 +34,39 @@ const DIRECTIVE = `[Eklavya] Standing instruction for this session, on every tas
|
|
|
33
34
|
interruption is the product -- learning while the work happens, not a pile of questions after
|
|
34
35
|
it. One question, no summary, no re-plan, no second question.`;
|
|
35
36
|
await run(async (input) => {
|
|
37
|
+
const cwd = cwdOf(input);
|
|
38
|
+
// Lift a leftover `<repo>/.eklavya.json` out of the checkout, silently. This
|
|
39
|
+
// is the moment that makes the move automatic: settings files stopped living
|
|
40
|
+
// in repositories, and nobody should have to be told so or do anything about
|
|
41
|
+
// it. `loadConfig` reads the legacy file until this lands, so the session it
|
|
42
|
+
// runs in is configured identically either way. It never throws.
|
|
43
|
+
//
|
|
44
|
+
// **Before the database check below**, and that ordering is the whole point:
|
|
45
|
+
// this has nothing to do with the database, and behind that guard it never ran
|
|
46
|
+
// on a fresh install -- the one case where the file is most likely to be a
|
|
47
|
+
// just-cloned repo's, and where the next thing to happen is `openDb` creating
|
|
48
|
+
// the database and every later session finding the move already done.
|
|
49
|
+
const { repoRoot } = findRepoConfig(cwd);
|
|
50
|
+
if (repoRoot)
|
|
51
|
+
migrateLegacyRepoConfig(repoRoot, mainRepoRoot(repoRoot));
|
|
36
52
|
const db = openExisting();
|
|
37
53
|
if (!db)
|
|
38
54
|
return 0;
|
|
39
|
-
const cwd = cwdOf(input);
|
|
40
55
|
const sid = sessionId(input, db);
|
|
41
56
|
// Stamp the session so MCP tools resolve the same id the hooks will use later
|
|
42
57
|
// (decision G1). This happens even when the banner is suppressed.
|
|
43
58
|
if (sid)
|
|
44
59
|
setCurrentSession(db, sid, cwd);
|
|
45
60
|
const resolved = config(cwd);
|
|
46
|
-
const {
|
|
61
|
+
const { quiz, difficulty, quiet } = resolved.config;
|
|
47
62
|
// The memory half runs before every learning gate below, because it is not
|
|
48
|
-
// governed by them (PRD CFG-01): `
|
|
49
|
-
// history. Three jobs, all silent on failure -- replay whatever the spool
|
|
63
|
+
// governed by them (PRD CFG-01): `quiz.enabled: false` means no quizzes, not
|
|
64
|
+
// no history. Three jobs, all silent on failure -- replay whatever the spool
|
|
50
65
|
// holds, mark the seam, and drain any batch the last session left queued.
|
|
51
66
|
const identity = identityOf(input, cwd, sid);
|
|
52
67
|
const memoryContext = [];
|
|
53
|
-
|
|
68
|
+
const memoryEnabled = resolved.config.memory.enabled;
|
|
69
|
+
if (memoryEnabled) {
|
|
54
70
|
replaySpool(db);
|
|
55
71
|
// Drain first, then mark the seam. The other order batches the lifecycle
|
|
56
72
|
// event on its own and summarises "session started" into an observation of
|
|
@@ -65,25 +81,40 @@ await run(async (input) => {
|
|
|
65
81
|
if (block)
|
|
66
82
|
memoryContext.push(block);
|
|
67
83
|
}
|
|
68
|
-
if (
|
|
84
|
+
if (!quiz.enabled) {
|
|
69
85
|
// Recall still has a job here: the developer turned quizzing off, not
|
|
70
86
|
// project memory. Nothing else this hook says applies.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
87
|
+
//
|
|
88
|
+
// The line below it is the whole reason the `mode` dial was retired. With
|
|
89
|
+
// quizzing off and nothing yet recalled -- a first session in a repo, which
|
|
90
|
+
// is exactly when somebody is deciding whether this tool works -- this hook
|
|
91
|
+
// used to print nothing whatsoever, and a plugin that greets you with
|
|
92
|
+
// silence is a plugin you conclude is broken. It was not: memory was
|
|
93
|
+
// recording the entire time, with no way to tell from the outside. One line
|
|
94
|
+
// costs nothing and answers the question before it is asked.
|
|
95
|
+
const shown = [];
|
|
96
|
+
if (!quiet) {
|
|
97
|
+
shown.push(memoryEnabled
|
|
98
|
+
? '[Eklavya] Questions are off for this project (`quiz.enabled: false`). Memory is still recording and recalling — `memory.enabled: false` is the dial for that.'
|
|
99
|
+
: '[Eklavya] Questions and memory are both off for this project. Nothing is being recorded.');
|
|
100
|
+
}
|
|
101
|
+
return emit(shown, memoryContext);
|
|
74
102
|
}
|
|
75
103
|
// Fires on resume and after a compaction too, with the same session id, so a
|
|
76
104
|
// session silenced an hour ago stays silent rather than greeting its way back.
|
|
77
105
|
if (isSessionOff(db, sid))
|
|
78
106
|
return 0;
|
|
79
|
-
|
|
107
|
+
// Two audiences, two channels. `shown` is for the developer; `context` is for
|
|
108
|
+
// the model. See `emit` for why they cannot share one.
|
|
109
|
+
const shown = [];
|
|
110
|
+
const context = [];
|
|
80
111
|
// `quiet` suppresses the banner, and only the banner. It used to return here,
|
|
81
112
|
// which also dropped the directive below -- so a developer who turned the
|
|
82
113
|
// greeting off silently turned the whole product off: nothing was logged, so
|
|
83
114
|
// the Stop hook found no candidates, so no question was ever asked, while
|
|
84
|
-
// `get_config` went on reporting
|
|
115
|
+
// `get_config` went on reporting quizzing as enabled. The manual has always said
|
|
85
116
|
// this key "suppresses the session-start banner and the statusline output",
|
|
86
|
-
// and `
|
|
117
|
+
// and `quiz.enabled: false` is the documented way to stop the questions.
|
|
87
118
|
if (!quiet) {
|
|
88
119
|
// The runway, and the one place it is visible: without it week one and week
|
|
89
120
|
// ten look identical from the outside, and a learner on `easy` reads a
|
|
@@ -95,7 +126,7 @@ await run(async (input) => {
|
|
|
95
126
|
const standing = levelStanding(db, resolved.config, resolved.repoRoot);
|
|
96
127
|
levelLabel = `${standing.level} (${standing.counts.passed}/${standing.needed.answers})`;
|
|
97
128
|
}
|
|
98
|
-
banner(db,
|
|
129
|
+
banner(db, shown, {
|
|
99
130
|
project: identity.project,
|
|
100
131
|
memory: resolved.config.memory.enabled,
|
|
101
132
|
levelLabel,
|
|
@@ -103,12 +134,12 @@ await run(async (input) => {
|
|
|
103
134
|
});
|
|
104
135
|
}
|
|
105
136
|
// Said even when `quiet` is set, and said before the directive, because it is
|
|
106
|
-
// not a greeting: a lead who pinned enforced
|
|
137
|
+
// not a greeting: a lead who pinned `quiz.enforced` has been promised commits
|
|
107
138
|
// are held, and in Cowork nothing holds them. The gate matches `git commit` in
|
|
108
139
|
// a Bash call, and Cowork sessions do not commit. Better to say so once per
|
|
109
140
|
// session than to let someone believe an unenforceable setting is enforcing.
|
|
110
|
-
if (
|
|
111
|
-
|
|
141
|
+
if (quiz.enforced && isCowork()) {
|
|
142
|
+
shown.push('[Eklavya] Quizzing is enforced, but this is a Cowork session: the commit gate holds `git commit`, ' +
|
|
112
143
|
'and there are no commits here. Questions still come and the gate still records — nothing is blocked.');
|
|
113
144
|
}
|
|
114
145
|
// The directive is on screen again, so the nudge's clock starts again. This
|
|
@@ -119,17 +150,40 @@ await run(async (input) => {
|
|
|
119
150
|
clearNudgeState(db, sid);
|
|
120
151
|
// Before the directive: it is what the session is *about*, and the directive
|
|
121
152
|
// is what to do about it.
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return 0;
|
|
153
|
+
context.push(...memoryContext);
|
|
154
|
+
context.push(withSurfaceNote(DIRECTIVE));
|
|
155
|
+
return emit(shown, context);
|
|
126
156
|
});
|
|
157
|
+
/**
|
|
158
|
+
* One envelope, split by audience.
|
|
159
|
+
*
|
|
160
|
+
* This hook used to print everything as plain stdout, and on SessionStart plain
|
|
161
|
+
* stdout is context: the model reads it and the developer never sees it. So the
|
|
162
|
+
* banner -- three lines written for a person, and the "questions are off, memory
|
|
163
|
+
* is still recording" line that exists precisely so a quiet install does not
|
|
164
|
+
* look broken -- went to the one reader it was not for, and every session opened
|
|
165
|
+
* in silence. `systemMessage` is the only field the harness renders to the
|
|
166
|
+
* developer (top level, not inside `hookSpecificOutput`, where it is dropped);
|
|
167
|
+
* `additionalContext` is the model's. Nothing is sent to both: the model has
|
|
168
|
+
* `get_config` and `get_learner_profile` for anything the banner says.
|
|
169
|
+
*/
|
|
170
|
+
function emit(shown, context) {
|
|
171
|
+
if (!shown.length && !context.length)
|
|
172
|
+
return 0;
|
|
173
|
+
process.stdout.write(`${JSON.stringify({
|
|
174
|
+
...(shown.length > 0 && { systemMessage: shown.join('\n') }),
|
|
175
|
+
...(context.length > 0 && {
|
|
176
|
+
hookSpecificOutput: { hookEventName: 'SessionStart', additionalContext: context.join('\n') },
|
|
177
|
+
}),
|
|
178
|
+
})}\n`);
|
|
179
|
+
return 0;
|
|
180
|
+
}
|
|
127
181
|
/**
|
|
128
182
|
* The developer-facing greeting, and everything `quiet` is about.
|
|
129
183
|
*
|
|
130
184
|
* Three lines (PRD UX-01): a heading, what reuse saved, and where this project
|
|
131
185
|
* stands. Deliberately short. It used to print the learner profile, the weakest
|
|
132
|
-
* concepts, the due count and
|
|
186
|
+
* concepts, the due count and every dial — a scoreboard at the moment
|
|
133
187
|
* somebody sat down to work, none of which they had asked for. The dials live
|
|
134
188
|
* in the status bar (`eklavya statusline`), the profile and the weak list live
|
|
135
189
|
* in the dashboard, and both are there when they are wanted.
|
|
@@ -152,7 +206,7 @@ function banner(db, out, parts) {
|
|
|
152
206
|
if (parts.overrides.length > 0) {
|
|
153
207
|
// A warning, not a scoreboard: a repo silently overriding a personal
|
|
154
208
|
// setting is the one thing worth interrupting for.
|
|
155
|
-
out.push(`
|
|
209
|
+
out.push(`Your settings for this project override your global ones for: ${parts.overrides.join(' ')}.`);
|
|
156
210
|
}
|
|
157
211
|
}
|
|
158
212
|
//# sourceMappingURL=session-start.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-start.js","sourceRoot":"","sources":["../../src/hooks/session-start.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,eAAe,EAAW,MAAM,UAAU,CAAC;AACjG,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD;;;;;;;;;GASG;AACH,MAAM,SAAS,GAAG;;;;;;;;;;;kEAWgD,CAAC;AAEnE,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;IACxB,MAAM,
|
|
1
|
+
{"version":3,"file":"session-start.js","sourceRoot":"","sources":["../../src/hooks/session-start.ts"],"names":[],"mappings":"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"}
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
* (`min_minutes_between_checkpoints` here, `min_minutes_between_quizzes` under
|
|
39
39
|
* `end`), `max_stop_blocks_per_session`, and the remaining session budget.
|
|
40
40
|
*/
|
|
41
|
-
import {
|
|
42
|
-
import { run, openExisting, config, cwdOf, sessionId, minutesSince
|
|
41
|
+
import { isCowork } from '../surface.js';
|
|
42
|
+
import { run, openExisting, config, cwdOf, sessionId, minutesSince } from './lib.js';
|
|
43
43
|
import { isSessionOff } from '../session.js';
|
|
44
44
|
import { flushAtSeam, identityOf, wrapUpAtSeam } from './memory-lib.js';
|
|
45
45
|
import { fillOmissions } from '../memory/learning.js';
|
|
@@ -88,12 +88,13 @@ await run(async (input) => {
|
|
|
88
88
|
// on it. Gating memory on an announcement channel means nobody ever gets one.
|
|
89
89
|
await wrapUpAtSeam(db, stopConfig, identity);
|
|
90
90
|
}
|
|
91
|
-
// Silenced sessions are never blocked, enforced
|
|
92
|
-
// is what enforced
|
|
91
|
+
// Silenced sessions are never blocked, enforced quizzing included: the commit
|
|
92
|
+
// gate is what `quiz.enforced` is for, and it reads the project config rather
|
|
93
|
+
// than this.
|
|
93
94
|
if (isSessionOff(db, sid))
|
|
94
95
|
return 0;
|
|
95
|
-
const {
|
|
96
|
-
if (
|
|
96
|
+
const { quiz, cadence, max_questions_per_task, max_stop_blocks_per_session, min_minutes_between_quizzes, min_minutes_between_checkpoints, } = config(cwd).config;
|
|
97
|
+
if (!quiz.enabled)
|
|
97
98
|
return 0;
|
|
98
99
|
const stats = db
|
|
99
100
|
.prepare(`SELECT
|
|
@@ -128,10 +129,10 @@ await run(async (input) => {
|
|
|
128
129
|
return 0;
|
|
129
130
|
// Under `interleaved` this sweep asks exactly ONE question (see `take` below),
|
|
130
131
|
// so it is paced by the single-question clock rather than the whole-quiz one.
|
|
131
|
-
// Enforced
|
|
132
|
-
const interleaved = cadence === 'interleaved' &&
|
|
132
|
+
// Enforced quizzing is exempt from both, as it always was (decision G5).
|
|
133
|
+
const interleaved = cadence === 'interleaved' && !quiz.enforced;
|
|
133
134
|
// --- the pacing clock ------------------------------------------------------
|
|
134
|
-
//
|
|
135
|
+
// Unenforced quizzing respects the cadence. Enforced must not, or a cooldown
|
|
135
136
|
// could make a commit gate unpassable (decision G5).
|
|
136
137
|
//
|
|
137
138
|
// Which clock depends on what is being paced. `min_minutes_between_quizzes` is
|
|
@@ -155,7 +156,7 @@ await run(async (input) => {
|
|
|
155
156
|
// which has a logged concept behind each firing. A Stop sweep has no such event:
|
|
156
157
|
// at a gap of 0 a model that ignores the instruction and stops again immediately
|
|
157
158
|
// gets blocked again immediately, three times in a row with no pause.
|
|
158
|
-
if (
|
|
159
|
+
if (!quiz.enforced) {
|
|
159
160
|
const gap = interleaved
|
|
160
161
|
? Math.max(1, min_minutes_between_checkpoints)
|
|
161
162
|
: min_minutes_between_quizzes;
|
|
@@ -226,47 +227,40 @@ await run(async (input) => {
|
|
|
226
227
|
last_blocked_at = excluded.last_blocked_at,
|
|
227
228
|
last_logged_count = excluded.last_logged_count,
|
|
228
229
|
block_count = stop_markers.block_count + 1`).run({ sid, logged: stats.logged });
|
|
229
|
-
const framing = framingFor(focus, focus_topic, 'stop');
|
|
230
230
|
// What the model is being asked for, in the words of the cadence it is running
|
|
231
231
|
// under. `interleaved` gets a hard singular -- the plan will hand back exactly
|
|
232
232
|
// one item, and prose that still says "each question" reads as licence to go
|
|
233
233
|
// looking for more.
|
|
234
234
|
const ask = take === 1
|
|
235
|
-
?
|
|
236
|
-
|
|
237
|
-
record_attempt. One question, then let them finish -- there is no second one to
|
|
238
|
-
come back for. The plan returns a "framing" field. Follow it.`
|
|
239
|
-
: `Use the eklavya MCP server and the tutor skill: call get_session_quiz_plan, ask
|
|
240
|
-
ONE question at a time at each concept's tier_to_ask, and grade each answer with
|
|
241
|
-
record_attempt. The plan returns a "framing" field. Follow it.`;
|
|
235
|
+
? 'One question, then let them finish -- there is no second one to come back for.'
|
|
236
|
+
: `Ask ONE question at a time, up to ${take}.`;
|
|
242
237
|
// The enforced line names the commit gate as the reason to press, which is
|
|
243
238
|
// true everywhere the gate can fire. On Cowork it cannot — it matches `git
|
|
244
239
|
// commit`, and Cowork does not commit — and session-start has already told
|
|
245
240
|
// this session that nothing is blocked. Saying both things in one session
|
|
246
241
|
// teaches the learner that Eklavya's warnings need not be read carefully, so
|
|
247
242
|
// the enforced framing drops to why the quiz still matters there.
|
|
248
|
-
const tone =
|
|
243
|
+
const tone = quiz.enforced
|
|
249
244
|
? isCowork()
|
|
250
|
-
? '
|
|
251
|
-
: '
|
|
252
|
-
: 'If they say skip, record
|
|
253
|
-
|
|
254
|
-
|
|
245
|
+
? 'Quizzing is enforced here. Nothing is blocked — Cowork does not commit — but the gate still records what was answered.'
|
|
246
|
+
: 'Quizzing is enforced in this session: the commit gate needs this quiz.'
|
|
247
|
+
: 'If they say skip, record grade 0 and let them go — do not ask twice.';
|
|
248
|
+
// EVERY LINE BELOW IS PRINTED TO THE DEVELOPER, VERBATIM.
|
|
249
|
+
// The harness renders a Stop hook's `additionalContext` under "Ran N stop
|
|
250
|
+
// hooks" in gold, wrapped and effectively untruncated (`stop_hook_summary` in
|
|
251
|
+
// the 2.1.278 bundle), and there is no field that hides it — `suppressOutput`
|
|
252
|
+
// does not reach this path. So length is the only lever there is, and the page
|
|
253
|
+
// of model-facing instructions this used to be was Eklavya reciting its own
|
|
254
|
+
// prompt at the person it is meant to be teaching, every single task.
|
|
255
|
+
//
|
|
256
|
+
// Say only what this hook alone knows -- which concepts, how big the sweep,
|
|
257
|
+
// whether the gate is pressing -- and let `get_session_quiz_plan` carry the
|
|
258
|
+
// rest. It already returns `framing`, `ask_attribution`, `answer_position` and
|
|
259
|
+
// `tier_to_ask` with every plan, and the next thing the model does is call it,
|
|
260
|
+
// so repeating any of that here buys nothing and costs the developer a screen.
|
|
261
|
+
const context = `Eklavya: quiz the developer on what this task taught. ${ask}
|
|
255
262
|
Concepts: ${concepts}
|
|
256
|
-
|
|
257
|
-
${ask}
|
|
258
|
-
|
|
259
|
-
Ask each question as MULTIPLE CHOICE via the AskUserQuestion tool: four options,
|
|
260
|
-
one correct and three plausible, the correct one in the slot answer_position
|
|
261
|
-
names.
|
|
262
|
-
${attributionRule()}
|
|
263
|
-
The tool's own "Other" choice is the escape hatch for "I don't know". They are
|
|
264
|
-
mid-task -- a blank prompt gets skipped whether or not they knew the answer.
|
|
265
|
-
Record with format "mcq", the labels in "options", and only the stem in
|
|
266
|
-
"question".
|
|
267
|
-
${framing}
|
|
268
|
-
${tone}
|
|
269
|
-
`;
|
|
263
|
+
get_session_quiz_plan, then AskUserQuestion, then record_attempt (format "mcq", labels in "options", stem alone in "question"). The plan's framing, ask_attribution, answer_position and tier_to_ask are the rules — follow them. ${tone}`;
|
|
270
264
|
// exit 0 + JSON, not exit 2 + stderr. Both continue the turn and both pass
|
|
271
265
|
// through the same loop protections; only one of them tells the developer
|
|
272
266
|
// their session just hit an error. No `systemMessage` -- that field is a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stop-quiz-check.js","sourceRoot":"","sources":["../../src/hooks/stop-quiz-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"stop-quiz-check.js","sourceRoot":"","sources":["../../src/hooks/stop-quiz-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -74,9 +74,9 @@ await run(async (input) => {
|
|
|
74
74
|
// subagent may well be the first thing in a session to touch Eklavya, and a
|
|
75
75
|
// hook that bailed on `openExisting() === null` would be silent on exactly
|
|
76
76
|
// the fresh install that most needs the directive.
|
|
77
|
-
if (config(cwdOf(input)).config.
|
|
77
|
+
if (!config(cwdOf(input)).config.quiz.enabled)
|
|
78
78
|
return 0;
|
|
79
|
-
// The one query this hook makes, and only past
|
|
79
|
+
// The one query this hook makes, and only past that gate: a session the
|
|
80
80
|
// developer silenced should not be handed the directive through the back door
|
|
81
81
|
// of delegated work.
|
|
82
82
|
const db = openExisting();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagent-start.js","sourceRoot":"","sources":["../../src/hooks/subagent-start.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,SAAS,GAAG;+HAC6G,CAAC;AAEhI;;;;;;;;;;;;;GAaG;AACH,SAAS,OAAO,CAAC,SAA6B;IAC5C,OAAO,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;IACxB,0EAA0E;IAC1E,4EAA4E;IAC5E,2EAA2E;IAC3E,mDAAmD;IACnD,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"subagent-start.js","sourceRoot":"","sources":["../../src/hooks/subagent-start.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,SAAS,GAAG;+HAC6G,CAAC;AAEhI;;;;;;;;;;;;;GAaG;AACH,SAAS,OAAO,CAAC,SAA6B;IAC5C,OAAO,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;IACxB,0EAA0E;IAC1E,4EAA4E;IAC5E,2EAA2E;IAC3E,mDAAmD;IACnD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO;QAAE,OAAO,CAAC,CAAC;IAExD,wEAAwE;IACxE,8EAA8E;IAC9E,qBAAqB;IACrB,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;IAC1B,IAAI,EAAE,IAAI,YAAY,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IAE3D,6EAA6E;IAC7E,2EAA2E;IAC3E,2EAA2E;IAC3E,0EAA0E;IAC1E,gEAAgE;IAChE,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC;QAAE,OAAO,CAAC,CAAC;IAExC,2EAA2E;IAC3E,2EAA2E;IAC3E,8DAA8D;IAC9D,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,IAAI,CAAC,SAAS,CAAC;QAChB,kBAAkB,EAAE;YAClB,aAAa,EAAE,eAAe;YAC9B,iBAAiB,EAAE,eAAe,CAAC,SAAS,CAAC;SAC9C;KACF,CAAC,IAAI,CACP,CAAC;IACF,OAAO,CAAC,CAAC;AACX,CAAC,CAAC,CAAC"}
|
package/dist/memory/sync.js
CHANGED
|
@@ -61,7 +61,7 @@ const DEVICE_ID_KEY = 'sync_device_id';
|
|
|
61
61
|
* This install's identity, generated once.
|
|
62
62
|
*
|
|
63
63
|
* Kept in `meta` rather than in the config file, and the difference matters.
|
|
64
|
-
* Config travels:
|
|
64
|
+
* Config travels: `~/.eklavya/config.json` is
|
|
65
65
|
* what a dotfile manager copies to the second machine. Two devices sharing an id
|
|
66
66
|
* would interleave one revision stream and each would read the other's writes as
|
|
67
67
|
* its own already-applied history -- a silent, unrecoverable merge. `meta` lives
|
package/dist/packs.js
CHANGED
|
@@ -8,23 +8,31 @@
|
|
|
8
8
|
* mid-session. A pack is the same file shape, loaded from two places Eklavya
|
|
9
9
|
* does not own:
|
|
10
10
|
*
|
|
11
|
-
* ~/.eklavya/packs/*.json
|
|
12
|
-
*
|
|
11
|
+
* ~/.eklavya/packs/*.json yours, everywhere
|
|
12
|
+
* ~/.eklavya/projects/<slug>/packs/*.json yours, on one codebase
|
|
13
|
+
* <repo>/.eklavya/packs/*.json read-only, the pre-move home
|
|
13
14
|
*
|
|
14
|
-
* The second is the interesting one. A
|
|
15
|
-
* and prerequisites is
|
|
16
|
-
*
|
|
15
|
+
* The second is the interesting one. A pack that describes a codebase's own
|
|
16
|
+
* concepts and prerequisites is onboarding rather than quizzing.
|
|
17
|
+
*
|
|
18
|
+
* It used to be the third, committed alongside the code, and that was the last
|
|
19
|
+
* thing Eklavya wrote into a repository. The argument for it was real — unlike
|
|
20
|
+
* settings, a concept graph genuinely is the same for everyone — but it lost to
|
|
21
|
+
* a simpler rule: Eklavya creates no files in your project. The old directory is
|
|
22
|
+
* still **read**, so a repository that already ships a pack keeps working, and
|
|
23
|
+
* nothing deletes it: a committed pack is authored content somebody reviewed,
|
|
24
|
+
* which is not ours to relocate. Only the writers moved.
|
|
17
25
|
*
|
|
18
26
|
* Packs are applied AFTER the seed and merged over it, so a pack may retier or
|
|
19
|
-
* rename a shipped concept, and a
|
|
27
|
+
* rename a shipped concept, and a project pack wins over a global one. Nothing
|
|
20
28
|
* here touches `mastery`: the seed's rule is the pack's rule, and a learner's
|
|
21
29
|
* history survives any pack being installed, edited or deleted.
|
|
22
30
|
*/
|
|
23
31
|
import fs from 'node:fs';
|
|
24
32
|
import path from 'node:path';
|
|
25
33
|
import crypto from 'node:crypto';
|
|
26
|
-
import { eklavyaHome } from './paths.js';
|
|
27
|
-
import { findRepoConfig } from './config.js';
|
|
34
|
+
import { eklavyaHome, projectPacksDir } from './paths.js';
|
|
35
|
+
import { findRepoConfig, mainRepoRoot } from './config.js';
|
|
28
36
|
import { applySeedGraph, validateSeedGraph, SEED_VERSION } from './seed.js';
|
|
29
37
|
/**
|
|
30
38
|
* One row per set of pack directories, not one row for the install.
|
|
@@ -38,17 +46,23 @@ export function packFingerprintKey(dirs) {
|
|
|
38
46
|
return `packs_fingerprint:${crypto.createHash('sha256').update(dirs.join('\n')).digest('hex').slice(0, 16)}`;
|
|
39
47
|
}
|
|
40
48
|
/**
|
|
41
|
-
* Global first,
|
|
42
|
-
*
|
|
43
|
-
*
|
|
49
|
+
* Global first, then the project's, because later wins.
|
|
50
|
+
*
|
|
51
|
+
* The legacy in-repo directory sits between them: after global, so a pack a
|
|
52
|
+
* repository already ships still overrides your own, and before the project
|
|
53
|
+
* directory, so moving a pack out of the checkout takes effect rather than
|
|
54
|
+
* being silently outranked by the copy left behind.
|
|
44
55
|
*/
|
|
45
56
|
export function packDirs(cwd = process.cwd()) {
|
|
46
57
|
const dirs = [
|
|
47
58
|
{ dir: path.join(eklavyaHome(), 'packs'), scope: 'global' },
|
|
48
59
|
];
|
|
49
60
|
const { repoRoot } = findRepoConfig(cwd);
|
|
50
|
-
if (repoRoot)
|
|
61
|
+
if (repoRoot) {
|
|
62
|
+
const project = mainRepoRoot(repoRoot);
|
|
51
63
|
dirs.push({ dir: path.join(repoRoot, '.eklavya', 'packs'), scope: 'repo' });
|
|
64
|
+
dirs.push({ dir: projectPacksDir(project), scope: 'project' });
|
|
65
|
+
}
|
|
52
66
|
return dirs;
|
|
53
67
|
}
|
|
54
68
|
function listPackFiles(dir) {
|
package/dist/packs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packs.js","sourceRoot":"","sources":["../src/packs.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"packs.js","sourceRoot":"","sources":["../src/packs.ts"],"names":[],"mappings":"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"}
|