@aethrekh/pi-cs 0.1.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/LICENSE +21 -0
  3. package/README.md +250 -0
  4. package/config/defaults.json +25 -0
  5. package/config/schema.json +134 -0
  6. package/extensions/folder-detector.d.ts +34 -0
  7. package/extensions/folder-detector.d.ts.map +1 -0
  8. package/extensions/folder-detector.js +197 -0
  9. package/extensions/folder-detector.js.map +1 -0
  10. package/extensions/index.d.ts +12 -0
  11. package/extensions/index.d.ts.map +1 -0
  12. package/extensions/index.js +227 -0
  13. package/extensions/index.js.map +1 -0
  14. package/extensions/integrity-guard.d.ts +25 -0
  15. package/extensions/integrity-guard.d.ts.map +1 -0
  16. package/extensions/integrity-guard.js +118 -0
  17. package/extensions/integrity-guard.js.map +1 -0
  18. package/extensions/progress-tracker.d.ts +33 -0
  19. package/extensions/progress-tracker.d.ts.map +1 -0
  20. package/extensions/progress-tracker.js +175 -0
  21. package/extensions/progress-tracker.js.map +1 -0
  22. package/extensions/semester-detector.d.ts +53 -0
  23. package/extensions/semester-detector.d.ts.map +1 -0
  24. package/extensions/semester-detector.js +197 -0
  25. package/extensions/semester-detector.js.map +1 -0
  26. package/index.d.ts +146 -0
  27. package/index.js +381 -0
  28. package/index.js.map +1 -0
  29. package/package.json +33 -0
  30. package/pi-cs.meta.json +7 -0
  31. package/pi-package.yaml +76 -0
  32. package/skills/exam/SKILL.md +186 -0
  33. package/skills/explain/SKILL.md +124 -0
  34. package/skills/homework/SKILL.md +89 -0
  35. package/skills/leetcode/SKILL.md +139 -0
  36. package/skills/project/SKILL.md +143 -0
  37. package/skills/research/SKILL.md +164 -0
  38. package/skills/review/SKILL.md +136 -0
  39. package/system.md +98 -0
  40. package/templates/project-init.md +141 -0
  41. package/templates/research-paper.md +134 -0
  42. package/templates/semester-init.md +49 -0
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ /**
3
+ * progress-tracker.ts
4
+ *
5
+ * Extension: Progress Tracker
6
+ * Triggers: on_session_end
7
+ *
8
+ * Tracks weekly activity across skills and sessions.
9
+ * Surfaces burnout prevention nudges and weekly summaries.
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.getBurnoutNudge = getBurnoutNudge;
46
+ exports.buildWeeklySummary = buildWeeklySummary;
47
+ exports.run = run;
48
+ const fs = __importStar(require("fs"));
49
+ const path = __importStar(require("path"));
50
+ const os = __importStar(require("os"));
51
+ // ─── Storage ───────────────────────────────────────────────────────────────
52
+ const TRACKER_DIR = path.join(os.homedir(), ".pi-cs");
53
+ const SESSIONS_FILE = path.join(TRACKER_DIR, "sessions.json");
54
+ function ensureTrackerDir() {
55
+ if (!fs.existsSync(TRACKER_DIR)) {
56
+ fs.mkdirSync(TRACKER_DIR, { recursive: true });
57
+ }
58
+ }
59
+ function loadSessions() {
60
+ try {
61
+ if (!fs.existsSync(SESSIONS_FILE))
62
+ return [];
63
+ const raw = fs.readFileSync(SESSIONS_FILE, "utf-8");
64
+ return JSON.parse(raw);
65
+ }
66
+ catch {
67
+ return [];
68
+ }
69
+ }
70
+ function saveSessions(sessions) {
71
+ try {
72
+ ensureTrackerDir();
73
+ // Keep only last 90 days of sessions
74
+ const cutoff = new Date();
75
+ cutoff.setDate(cutoff.getDate() - 90);
76
+ const recent = sessions.filter((s) => new Date(s.date) > cutoff);
77
+ fs.writeFileSync(SESSIONS_FILE, JSON.stringify(recent, null, 2));
78
+ }
79
+ catch {
80
+ // Fail silently — tracker is a nice-to-have, not critical
81
+ }
82
+ }
83
+ // ─── Stats ─────────────────────────────────────────────────────────────────
84
+ function getWeeklyStats(sessions) {
85
+ const oneWeekAgo = new Date();
86
+ oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);
87
+ const weekSessions = sessions.filter((s) => new Date(s.date) > oneWeekAgo);
88
+ const skillBreakdown = {};
89
+ let totalMinutes = 0;
90
+ let longestSession = 0;
91
+ for (const session of weekSessions) {
92
+ totalMinutes += session.durationMinutes;
93
+ longestSession = Math.max(longestSession, session.durationMinutes);
94
+ for (const skill of session.skillsUsed) {
95
+ skillBreakdown[skill] = (skillBreakdown[skill] ?? 0) + 1;
96
+ }
97
+ }
98
+ // Calculate streak
99
+ let streak = 0;
100
+ const sessionDays = new Set(sessions.map((s) => new Date(s.date).toDateString()));
101
+ const checkDate = new Date();
102
+ while (sessionDays.has(checkDate.toDateString())) {
103
+ streak++;
104
+ checkDate.setDate(checkDate.getDate() - 1);
105
+ }
106
+ return {
107
+ totalMinutes,
108
+ sessionCount: weekSessions.length,
109
+ skillBreakdown,
110
+ longestSession,
111
+ streak,
112
+ };
113
+ }
114
+ // ─── Nudges ─────────────────────────────────────────────────────────────────
115
+ function getBurnoutNudge(sessionDurationMinutes, stats) {
116
+ // Long single session
117
+ if (sessionDurationMinutes >= 180) {
118
+ return "🐠 You've been coding for 3+ hours. Seriously — take a 15-minute break. Your brain consolidates learning during rest, not during grinding.";
119
+ }
120
+ // Very heavy week
121
+ if (stats.totalMinutes > 40 * 60) {
122
+ return "📊 You've put in 40+ hours of study this week. That's impressive, but rest is part of learning. Don't skip sleep before your exam.";
123
+ }
124
+ // Long streak — positive reinforcement
125
+ if (stats.streak >= 7) {
126
+ return `🔥 ${stats.streak}-day streak! Consistent daily practice beats marathon sessions. Keep this up.`;
127
+ }
128
+ return null;
129
+ }
130
+ // ─── Weekly Summary ────────────────────────────────────────────────────────
131
+ function buildWeeklySummary(stats) {
132
+ if (stats.sessionCount === 0) {
133
+ return "📅 No activity recorded this week. When you're ready to start, just ask!";
134
+ }
135
+ const hours = Math.floor(stats.totalMinutes / 60);
136
+ const minutes = stats.totalMinutes % 60;
137
+ const timeStr = hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`;
138
+ const topSkills = Object.entries(stats.skillBreakdown)
139
+ .sort(([, a], [, b]) => b - a)
140
+ .slice(0, 3)
141
+ .map(([skill, count]) => ` - /${skill}: ${count} session${count > 1 ? "s" : ""}`)
142
+ .join("\n");
143
+ return [
144
+ `📊 **This Week's Summary**`,
145
+ ``,
146
+ `⏱ Total study time: **${timeStr}**`,
147
+ `📅 Sessions: **${stats.sessionCount}**`,
148
+ `🔥 Current streak: **${stats.streak} day${stats.streak !== 1 ? "s" : ""}**`,
149
+ topSkills ? `\n🛠 Most used skills:\n${topSkills}` : "",
150
+ ``,
151
+ stats.totalMinutes < 5 * 60
152
+ ? `💡 Tip: Even 30 minutes a day compounds significantly over a semester.`
153
+ : `✅ Solid week. Keep the consistency going.`,
154
+ ]
155
+ .filter(Boolean)
156
+ .join("\n");
157
+ }
158
+ // ─── Pi Extension Entry Point ──────────────────────────────────────────────
159
+ function run(context) {
160
+ const sessions = loadSessions();
161
+ // Record this session
162
+ const record = {
163
+ date: new Date().toISOString(),
164
+ durationMinutes: context.sessionDurationMinutes,
165
+ skillsUsed: context.skillsUsed,
166
+ topicsWorked: context.topicsWorked ?? [],
167
+ };
168
+ sessions.push(record);
169
+ saveSessions(sessions);
170
+ const stats = getWeeklyStats(sessions);
171
+ const nudge = getBurnoutNudge(context.sessionDurationMinutes, stats);
172
+ const weeklySummary = buildWeeklySummary(stats);
173
+ return { nudge, weeklySummary };
174
+ }
175
+ //# sourceMappingURL=progress-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress-tracker.js","sourceRoot":"","sources":["../../src/extensions/progress-tracker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * semester-detector.ts
3
+ *
4
+ * Extension: Semester Detector
5
+ * Triggers: on_startup, on_directory_change
6
+ *
7
+ * Searches for SEMESTER.md in the working directory and standard university
8
+ * folder locations, then injects the semester context into the Pi session.
9
+ */
10
+ export interface Course {
11
+ code: string;
12
+ name: string;
13
+ assignments?: Assignment[];
14
+ }
15
+ export interface Assignment {
16
+ name: string;
17
+ due: string;
18
+ submitted?: boolean;
19
+ }
20
+ export interface SemesterContext {
21
+ semester: string;
22
+ year: number;
23
+ week?: number;
24
+ year_of_study?: number;
25
+ courses: Course[];
26
+ active_project?: string;
27
+ notes?: string;
28
+ }
29
+ export interface DetectionResult {
30
+ found: boolean;
31
+ source?: string;
32
+ context?: SemesterContext;
33
+ error?: string;
34
+ }
35
+ /**
36
+ * Main detection function. Searches candidate paths for SEMESTER.md
37
+ * and returns the parsed context if found.
38
+ */
39
+ export declare function detectSemesterContext(): DetectionResult;
40
+ /**
41
+ * Generates a contextual greeting based on the detected semester context.
42
+ * Injected into the Pi session at startup.
43
+ */
44
+ export declare function generateGreeting(result: DetectionResult): string;
45
+ /**
46
+ * Called by Pi on_startup and on_directory_change.
47
+ * Returns the context injection for the active session.
48
+ */
49
+ export declare function run(): {
50
+ inject: string;
51
+ greeting: string;
52
+ };
53
+ //# sourceMappingURL=semester-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semester-detector.d.ts","sourceRoot":"","sources":["../../src/extensions/semester-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAuED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CAsBvD;AAID;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAiChE;AAID;;;GAGG;AACH,wBAAgB,GAAG,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAuB1D"}
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ /**
3
+ * semester-detector.ts
4
+ *
5
+ * Extension: Semester Detector
6
+ * Triggers: on_startup, on_directory_change
7
+ *
8
+ * Searches for SEMESTER.md in the working directory and standard university
9
+ * folder locations, then injects the semester context into the Pi session.
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.detectSemesterContext = detectSemesterContext;
46
+ exports.generateGreeting = generateGreeting;
47
+ exports.run = run;
48
+ const fs = __importStar(require("fs"));
49
+ const path = __importStar(require("path"));
50
+ const os = __importStar(require("os"));
51
+ // ─── Search Paths ──────────────────────────────────────────────────────────
52
+ function getSearchPaths() {
53
+ return [
54
+ process.cwd(),
55
+ path.join(os.homedir(), "university"),
56
+ path.join(os.homedir(), "uni"),
57
+ path.join(os.homedir(), "college"),
58
+ path.join(os.homedir(), "school"),
59
+ path.join(os.homedir(), "Documents", "university"),
60
+ path.join(os.homedir(), "Documents", "uni"),
61
+ ];
62
+ }
63
+ const SEMESTER_FILE = "SEMESTER.md";
64
+ // ─── Parser ────────────────────────────────────────────────────────────────
65
+ /**
66
+ * Parses a SEMESTER.md file into a SemesterContext object.
67
+ * Format is lenient — extracts what it can, leaves the rest as notes.
68
+ */
69
+ function parseSemesterMd(content) {
70
+ const lines = content.split("\n");
71
+ const context = {
72
+ semester: "Unknown",
73
+ year: new Date().getFullYear(),
74
+ courses: [],
75
+ };
76
+ for (const line of lines) {
77
+ const trimmed = line.trim();
78
+ // semester: Fall 2025
79
+ const semMatch = trimmed.match(/^semester[:\s]+(.+)/i);
80
+ if (semMatch)
81
+ context.semester = semMatch[1].trim();
82
+ // year: 2025
83
+ const yearMatch = trimmed.match(/^year[:\s]+(\d{4})/i);
84
+ if (yearMatch)
85
+ context.year = parseInt(yearMatch[1]);
86
+ // week: 7
87
+ const weekMatch = trimmed.match(/^week[:\s]+(\d+)/i);
88
+ if (weekMatch)
89
+ context.week = parseInt(weekMatch[1]);
90
+ // year_of_study: 2
91
+ const studyYearMatch = trimmed.match(/^year.of.study[:\s]+(\d)/i);
92
+ if (studyYearMatch)
93
+ context.year_of_study = parseInt(studyYearMatch[1]);
94
+ // - CS301: Operating Systems
95
+ const courseMatch = trimmed.match(/^[-*]\s+([A-Z]{2,4}\d{2,4})[:\s]+(.+)/);
96
+ if (courseMatch) {
97
+ context.courses.push({
98
+ code: courseMatch[1],
99
+ name: courseMatch[2].trim(),
100
+ });
101
+ }
102
+ // active_project: my-compiler
103
+ const projectMatch = trimmed.match(/^active.project[:\s]+(.+)/i);
104
+ if (projectMatch)
105
+ context.active_project = projectMatch[1].trim();
106
+ }
107
+ return context;
108
+ }
109
+ // ─── Detector ──────────────────────────────────────────────────────────────
110
+ /**
111
+ * Main detection function. Searches candidate paths for SEMESTER.md
112
+ * and returns the parsed context if found.
113
+ */
114
+ function detectSemesterContext() {
115
+ for (const searchPath of getSearchPaths()) {
116
+ const candidate = path.join(searchPath, SEMESTER_FILE);
117
+ try {
118
+ if (fs.existsSync(candidate)) {
119
+ const content = fs.readFileSync(candidate, "utf-8");
120
+ const context = parseSemesterMd(content);
121
+ return {
122
+ found: true,
123
+ source: candidate,
124
+ context,
125
+ };
126
+ }
127
+ }
128
+ catch (err) {
129
+ // Permission errors or broken symlinks — skip silently
130
+ continue;
131
+ }
132
+ }
133
+ return { found: false };
134
+ }
135
+ // ─── Greeting Generator ────────────────────────────────────────────────────
136
+ /**
137
+ * Generates a contextual greeting based on the detected semester context.
138
+ * Injected into the Pi session at startup.
139
+ */
140
+ function generateGreeting(result) {
141
+ if (!result.found || !result.context) {
142
+ return [
143
+ "👋 Hey! I'm **Pisces**, your CS co-pilot.",
144
+ "",
145
+ "I don't see a `SEMESTER.md` in your workspace yet. Want to set one up so I can stay context-aware of your courses and deadlines?",
146
+ "",
147
+ "Run `/semester-init` to get started, or just tell me what you're working on!",
148
+ ].join("\n");
149
+ }
150
+ const ctx = result.context;
151
+ const weekStr = ctx.week ? ` (Week ${ctx.week})` : "";
152
+ const courseList = ctx.courses.length > 0
153
+ ? ctx.courses.map((c) => ` - ${c.code}: ${c.name}`).join("\n")
154
+ : " - (no courses listed)";
155
+ const projectLine = ctx.active_project
156
+ ? `\n🔧 Active project: **${ctx.active_project}**`
157
+ : "";
158
+ return [
159
+ `👋 Hey! I'm **Pisces** — loaded up for **${ctx.semester} ${ctx.year}**${weekStr}.`,
160
+ "",
161
+ `📚 Your courses:`,
162
+ courseList,
163
+ projectLine,
164
+ "",
165
+ "What are we tackling today? `/homework`, `/project`, `/review`, `/explain`, `/leetcode`, `/exam`, or `/research`",
166
+ ]
167
+ .filter((l) => l !== undefined)
168
+ .join("\n");
169
+ }
170
+ // ─── Pi Extension Entry Point ──────────────────────────────────────────────
171
+ /**
172
+ * Called by Pi on_startup and on_directory_change.
173
+ * Returns the context injection for the active session.
174
+ */
175
+ function run() {
176
+ const result = detectSemesterContext();
177
+ let inject = "";
178
+ if (result.found && result.context) {
179
+ inject = [
180
+ "<!-- SEMESTER CONTEXT (auto-loaded from SEMESTER.md) -->",
181
+ `<!-- Semester: ${result.context.semester} ${result.context.year} -->`,
182
+ `<!-- Week: ${result.context.week ?? "unknown"} -->`,
183
+ `<!-- Year of study: ${result.context.year_of_study ?? "unknown"} -->`,
184
+ `<!-- Courses: ${result.context.courses.map((c) => c.code).join(", ")} -->`,
185
+ result.context.active_project
186
+ ? `<!-- Active project: ${result.context.active_project} -->`
187
+ : "",
188
+ ]
189
+ .filter(Boolean)
190
+ .join("\n");
191
+ }
192
+ return {
193
+ inject,
194
+ greeting: generateGreeting(result),
195
+ };
196
+ }
197
+ //# sourceMappingURL=semester-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semester-detector.js","sourceRoot":"","sources":["../../src/extensions/semester-detector.ts"],"names":[],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,146 @@
1
+ /**
2
+ * src/index.ts
3
+ *
4
+ * pi-cs (Pisces) — Package Entry Point
5
+ *
6
+ * This is the single file Pi loads when the package is activated.
7
+ * It wires together all extensions, registers lifecycle hooks, loads
8
+ * user config, and exposes the public API surface the Pi runtime calls.
9
+ *
10
+ * Lifecycle order:
11
+ * 1. onLoad() — package installed / Pi starts, config resolved
12
+ * 2. onStartup() — new session begins, context injected
13
+ * 3. onDirectoryChange() — cwd changed mid-session
14
+ * 4. onSkillCall() — user invokes a /skill command
15
+ * 5. onSessionEnd() — session closes, progress recorded
16
+ */
17
+ import { SemesterContext } from "./extensions/semester-detector";
18
+ import { FolderDetectionResult } from "./extensions/folder-detector";
19
+ export interface PiCsConfig {
20
+ student?: {
21
+ name?: string;
22
+ year_of_study?: number;
23
+ primary_language?: string;
24
+ timezone?: string;
25
+ };
26
+ explanations?: {
27
+ default_depth?: "beginner" | "intermediate" | "advanced";
28
+ prefer_visuals?: boolean;
29
+ use_analogies?: boolean;
30
+ };
31
+ code?: {
32
+ style?: "verbose" | "balanced" | "concise";
33
+ always_include_complexity?: boolean;
34
+ always_include_tests?: boolean;
35
+ };
36
+ integrity?: {
37
+ enabled?: boolean;
38
+ strictness?: "strict" | "balanced" | "relaxed";
39
+ };
40
+ productivity?: {
41
+ burnout_nudges?: boolean;
42
+ session_warning_minutes?: number;
43
+ weekly_summary?: boolean;
44
+ };
45
+ model?: {
46
+ default?: string;
47
+ code_heavy?: string;
48
+ quick?: string;
49
+ };
50
+ }
51
+ export interface SessionState {
52
+ startTime: Date;
53
+ skillsUsed: string[];
54
+ topicsWorked: string[];
55
+ semesterContext: SemesterContext | null;
56
+ folderContext: FolderDetectionResult | null;
57
+ warningIssuedAt: number | null;
58
+ }
59
+ export interface SkillCallContext {
60
+ skillName: string;
61
+ userInput: string;
62
+ sessionState: SessionState;
63
+ }
64
+ export interface StartupResult {
65
+ contextInjection: string;
66
+ greeting: string;
67
+ config: PiCsConfig;
68
+ }
69
+ export interface SkillCallResult {
70
+ proceed: boolean;
71
+ injection: string;
72
+ }
73
+ export interface SessionEndResult {
74
+ nudge: string | null;
75
+ summary: string | null;
76
+ }
77
+ export declare const PACKAGE_NAME = "pi-cs";
78
+ export declare const PACKAGE_VERSION = "0.1.0";
79
+ export declare const SKILLS: readonly ["homework", "project", "review", "explain", "leetcode", "exam", "research"];
80
+ export type SkillName = (typeof SKILLS)[number];
81
+ /**
82
+ * Loads and merges user config over package defaults.
83
+ * Never throws — falls back to defaults on any read/parse error.
84
+ */
85
+ export declare function loadConfig(): PiCsConfig;
86
+ /**
87
+ * Creates a fresh session state object. Called by Pi at session start.
88
+ */
89
+ export declare function createSessionState(): SessionState;
90
+ /**
91
+ * onLoad — called once when Pi installs or loads the package.
92
+ * Validates the environment and logs the package is ready.
93
+ */
94
+ export declare function onLoad(): {
95
+ ok: boolean;
96
+ message: string;
97
+ };
98
+ /**
99
+ * onStartup — called at the start of every Pi session.
100
+ * Runs semester + folder detectors, builds greeting and context injection.
101
+ */
102
+ export declare function onStartup(state: SessionState): StartupResult;
103
+ /**
104
+ * onDirectoryChange — called when the user `cd`s to a new directory.
105
+ * Re-runs context detectors so Pi stays accurate.
106
+ */
107
+ export declare function onDirectoryChange(state: SessionState): {
108
+ contextInjection: string;
109
+ message: string | null;
110
+ };
111
+ /**
112
+ * onSkillCall — called just before Pi executes a skill.
113
+ * Runs the integrity guard and records the skill in session state.
114
+ */
115
+ export declare function onSkillCall(context: SkillCallContext): SkillCallResult;
116
+ /**
117
+ * onSessionEnd — called when the Pi session closes.
118
+ * Records session stats, surfaces a burnout nudge and weekly summary if configured.
119
+ */
120
+ export declare function onSessionEnd(state: SessionState): SessionEndResult;
121
+ /**
122
+ * onMidSession — called periodically by Pi (e.g. every 30 min).
123
+ * Issues a burnout warning if the session has exceeded the configured threshold.
124
+ */
125
+ export declare function onMidSession(state: SessionState): {
126
+ warning: string | null;
127
+ };
128
+ /**
129
+ * Returns the active semester context for the current session.
130
+ * Useful for extensions or templates that need course/week info.
131
+ */
132
+ export declare function getActiveSemesterContext(state: SessionState): SemesterContext | null;
133
+ /**
134
+ * Returns the active project context for the current session.
135
+ */
136
+ export declare function getActiveProjectContext(state: SessionState): FolderDetectionResult["project"] | null;
137
+ /**
138
+ * Checks if a given skill name is valid (registered in this package).
139
+ */
140
+ export declare function isValidSkill(name: string): name is SkillName;
141
+ /**
142
+ * Returns a short summary of what pi-cs provides, for display in Pi's
143
+ * package listing or help output.
144
+ */
145
+ export declare function describe(): string;
146
+ //# sourceMappingURL=index.d.ts.map