timeback-cli 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.
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Caliper Types
3
+ *
4
+ * Types for the IMS Caliper Analytics standard with Timeback Profile extensions.
5
+ * Used for learning activity and time spent tracking.
6
+ *
7
+ * @see https://www.imsglobal.org/activity/caliper
8
+ */
9
+ import type { TimebackSubject } from './primitives';
10
+ export interface TimebackUser {
11
+ id: string;
12
+ type: 'TimebackUser';
13
+ email: string;
14
+ }
15
+ export interface TimebackActivityContext {
16
+ id: string;
17
+ type: 'TimebackActivityContext';
18
+ subject: TimebackSubject;
19
+ app?: {
20
+ name: string;
21
+ };
22
+ activity?: {
23
+ id?: string;
24
+ name?: string;
25
+ };
26
+ course: {
27
+ id: string;
28
+ name: string;
29
+ };
30
+ process?: boolean;
31
+ }
32
+ export interface CaliperEventBase {
33
+ '@context': 'http://purl.imsglobal.org/ctx/caliper/v1p2';
34
+ id: string;
35
+ type: string;
36
+ eventTime: string;
37
+ profile: 'TimebackProfile';
38
+ actor: TimebackUser;
39
+ action: string;
40
+ object: TimebackActivityContext;
41
+ edApp?: {
42
+ id: string;
43
+ name?: string;
44
+ };
45
+ }
46
+ export interface TimebackActivityMetric {
47
+ type: 'totalQuestions' | 'correctQuestions' | 'xpEarned' | 'masteredUnits';
48
+ value: number;
49
+ }
50
+ export interface TimebackActivityMetricsCollection {
51
+ id: string;
52
+ type: 'TimebackActivityMetricsCollection';
53
+ attempt?: number;
54
+ items: TimebackActivityMetric[];
55
+ extensions?: Record<string, unknown>;
56
+ }
57
+ export interface TimebackActivityEvent extends CaliperEventBase {
58
+ type: 'ActivityEvent';
59
+ action: 'Completed';
60
+ generated: TimebackActivityMetricsCollection;
61
+ }
62
+ export interface TimebackTimeMetric {
63
+ type: 'active' | 'inactive' | 'waste' | 'unknown' | 'anti-pattern';
64
+ value: number;
65
+ subType?: string;
66
+ }
67
+ export interface TimebackTimeSpentMetricsCollection {
68
+ id: string;
69
+ type: 'TimebackTimeSpentMetricsCollection';
70
+ items: TimebackTimeMetric[];
71
+ }
72
+ export interface TimebackTimeSpentEvent extends CaliperEventBase {
73
+ type: 'TimeSpentEvent';
74
+ action: 'SpentTime';
75
+ generated: TimebackTimeSpentMetricsCollection;
76
+ }
77
+ export type TimebackEvent = TimebackActivityEvent | TimebackTimeSpentEvent;
78
+ export interface CaliperEnvelope {
79
+ sensor: string;
80
+ sendTime: string;
81
+ dataVersion: 'http://purl.imsglobal.org/ctx/caliper/v1p2';
82
+ data: TimebackEvent[];
83
+ }
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Timeback Config Types
3
+ *
4
+ * Types for timeback.config.ts files.
5
+ */
6
+ import type { TimebackGrade, TimebackSubject } from './primitives';
7
+ /**
8
+ * Environment-specific course IDs.
9
+ * Populated by `timeback sync` for each environment.
10
+ */
11
+ export interface CourseIds {
12
+ staging?: string;
13
+ production?: string;
14
+ }
15
+ /**
16
+ * Course classification type.
17
+ */
18
+ export type CourseType = 'base' | 'hole-filling' | 'optional';
19
+ /**
20
+ * Course publication status.
21
+ */
22
+ export type PublishStatus = 'draft' | 'testing' | 'published' | 'deactivated';
23
+ /**
24
+ * Daily learning goals for a course.
25
+ */
26
+ export interface CourseGoals {
27
+ /** Target XP to earn per day */
28
+ dailyXp?: number;
29
+ /** Target lessons to complete per day */
30
+ dailyLessons?: number;
31
+ /** Target active learning minutes per day */
32
+ dailyActiveMinutes?: number;
33
+ /** Target accuracy percentage (0-100) */
34
+ dailyAccuracy?: number;
35
+ /** Target units to master per day */
36
+ dailyMasteredUnits?: number;
37
+ }
38
+ /**
39
+ * Aggregate metrics for a course.
40
+ */
41
+ export interface CourseMetrics {
42
+ /** Total XP available in the course */
43
+ totalXp?: number;
44
+ /** Total number of lessons/activities */
45
+ totalLessons?: number;
46
+ /** Total grade levels covered */
47
+ totalGrades?: number;
48
+ }
49
+ /**
50
+ * Course metadata (matches API metadata object).
51
+ */
52
+ export interface CourseMetadata {
53
+ /** Course classification (base, hole-filling, optional) */
54
+ courseType?: CourseType;
55
+ /** Whether this is supplemental to a base course */
56
+ isSupplemental?: boolean;
57
+ /** Whether this is a custom course for an individual student */
58
+ isCustom?: boolean;
59
+ /** Publication status */
60
+ publishStatus?: PublishStatus;
61
+ /** Contact email for course issues */
62
+ contactEmail?: string;
63
+ /** Primary application identifier */
64
+ primaryApp?: string;
65
+ /** Daily learning goals */
66
+ goals?: CourseGoals;
67
+ /** Aggregate metrics */
68
+ metrics?: CourseMetrics;
69
+ }
70
+ /**
71
+ * Default properties that apply to all courses unless overridden.
72
+ * Set these at the root level to avoid repetition.
73
+ */
74
+ export interface CourseDefaults {
75
+ /** Course code (e.g., "MATH101") */
76
+ courseCode?: string;
77
+ /** Course level (e.g., "AP", "Honors") */
78
+ level?: string;
79
+ /** Course metadata */
80
+ metadata?: CourseMetadata;
81
+ }
82
+ /**
83
+ * Configuration for a single course in a Timeback app.
84
+ */
85
+ export interface CourseConfig extends CourseDefaults {
86
+ /** Subject area (e.g., 'Math', 'Reading') */
87
+ subject: TimebackSubject;
88
+ /** Grade level (-1 = Pre-K, 0 = K, 1-12 = grades, 13 = AP) */
89
+ grade: TimebackGrade;
90
+ /** Timeback course IDs per environment (populated after sync) */
91
+ ids?: CourseIds | null;
92
+ }
93
+ /**
94
+ * Root configuration for a Timeback app.
95
+ * Define this in your timeback.config.ts file.
96
+ */
97
+ export interface TimebackConfig {
98
+ /** Display name for your app */
99
+ name: string;
100
+ /** Default properties applied to all courses */
101
+ defaults?: CourseDefaults;
102
+ /** Courses available in this app */
103
+ courses: CourseConfig[];
104
+ /** Caliper sensor URLs for event filtering */
105
+ sensors?: string[];
106
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * EduBridge Types
3
+ *
4
+ * Types for the EduBridge analytics aggregation API.
5
+ * Provides enrollment and metrics data.
6
+ */
7
+ /**
8
+ * EduBridge enrollment data.
9
+ * Note: EduBridge returns grades/subjects as strings, not typed values.
10
+ */
11
+ export interface EduBridgeEnrollment {
12
+ id: string;
13
+ role: string;
14
+ beginDate: string | null;
15
+ endDate: string | null;
16
+ metadata?: {
17
+ goals?: {
18
+ dailyXp?: number;
19
+ };
20
+ metrics?: {
21
+ totalXp?: number;
22
+ totalLessons?: number;
23
+ };
24
+ };
25
+ course: {
26
+ id: string;
27
+ title: string;
28
+ subjects: string[] | null;
29
+ grades: string[] | null;
30
+ };
31
+ school: {
32
+ id: string;
33
+ name: string;
34
+ };
35
+ }
36
+ /**
37
+ * EduBridge analytics facts indexed by date and subject.
38
+ */
39
+ export interface EduBridgeAnalyticsFacts {
40
+ [date: string]: {
41
+ [subject: string]: {
42
+ activityMetrics: {
43
+ xpEarned: number;
44
+ totalQuestions: number;
45
+ correctQuestions: number;
46
+ masteredUnits: number;
47
+ };
48
+ timeSpentMetrics: {
49
+ activeSeconds: number;
50
+ inactiveSeconds: number;
51
+ wasteSeconds: number;
52
+ };
53
+ apps: string[];
54
+ };
55
+ };
56
+ }
57
+ /**
58
+ * EduBridge enrollment analytics response.
59
+ */
60
+ export interface EduBridgeEnrollmentAnalyticsResponse {
61
+ message: string;
62
+ enrollmentId: string;
63
+ startDate: string;
64
+ endDate: string;
65
+ facts: EduBridgeAnalyticsFacts;
66
+ factsByApp: unknown;
67
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * TypeScript types for Timeback platform protocols.
3
+ */
4
+ export * from './primitives';
5
+ export * from './caliper';
6
+ export * from './config';
7
+ export * from './edubridge';
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Timeback Primitives
3
+ *
4
+ * Core enums and literal types used across Timeback protocols.
5
+ */
6
+ /**
7
+ * Valid Timeback subject values.
8
+ * Used in OneRoster courses and Caliper events.
9
+ */
10
+ export type TimebackSubject = 'Reading' | 'Language' | 'Vocabulary' | 'Social Studies' | 'Writing' | 'Science' | 'FastMath' | 'Math' | 'None' | 'Other';
11
+ /**
12
+ * Grade levels per Timeback OneRoster GradeEnum (numeric).
13
+ * -1 = Pre-K, 0 = Kindergarten, 1-12 = Grades 1-12, 13 = AP
14
+ *
15
+ * Use for input types where numbers are accepted.
16
+ */
17
+ export type TimebackGrade = -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13;
18
+ /**
19
+ * Grade levels as strings (API response format).
20
+ * The database stores grades as text, so API responses return strings.
21
+ *
22
+ * Use for response types.
23
+ */
24
+ export type TimebackGradeString = '-1' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | '13';
25
+ /**
26
+ * OneRoster assessment result score status values.
27
+ */
28
+ export type ScoreStatus = 'exempt' | 'fully graded' | 'not submitted' | 'partially graded' | 'submitted';
29
+ /**
30
+ * OneRoster organization types.
31
+ */
32
+ export type OrganizationType = 'department' | 'school' | 'district' | 'local' | 'state' | 'national';
33
+ /**
34
+ * OneRoster user role types.
35
+ */
36
+ export type OneRosterUserRole = 'administrator' | 'aide' | 'guardian' | 'parent' | 'proctor' | 'relative' | 'student' | 'teacher';
37
+ /**
38
+ * Lesson types for PowerPath integration.
39
+ */
40
+ export type LessonType = 'powerpath-100' | 'quiz' | 'test-out' | 'placement' | 'unit-test' | 'alpha-read-article' | null;
41
+ /**
42
+ * IMS Global error response format.
43
+ * Used across OneRoster, Caliper, and other 1EdTech protocols.
44
+ */
45
+ export interface IMSErrorResponse {
46
+ imsx_codeMajor: 'failure' | 'success';
47
+ imsx_severity: 'error' | 'warning' | 'status';
48
+ imsx_description: string;
49
+ imsx_CodeMinor?: {
50
+ imsx_codeMinorField: Array<{
51
+ imsx_codeMinorFieldName: string;
52
+ imsx_codeMinorFieldValue: string;
53
+ }>;
54
+ };
55
+ imsx_error_details?: Array<Record<string, string>>;
56
+ }
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "timeback-cli",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "exports": {
6
+ "./config": {
7
+ "types": "./dist/config.d.ts",
8
+ "import": "./dist/config.d.ts",
9
+ "default": "./dist/config.d.ts"
10
+ }
11
+ },
12
+ "types": "./dist/config.d.ts",
13
+ "bin": {
14
+ "timeback": "./dist/cli.js"
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "schema.json"
19
+ ],
20
+ "scripts": {
21
+ "build": "bun build.ts",
22
+ "dev": "DEBUG=1 bun src/cli.ts",
23
+ "dev:studio": "DEBUG=studio:* bun src/cli.ts studio",
24
+ "start": "bun dist/cli.js",
25
+ "unused": "bunx ts-unused-exports tsconfig.json --ignoreFiles='(dist|timeback\\.config\\.ts|src/config\\.ts)'"
26
+ },
27
+ "dependencies": {
28
+ "@clack/prompts": "^0.11.0",
29
+ "colorette": "^2.0.20",
30
+ "commander": "^14.0.2",
31
+ "jiti": "^2.6.1",
32
+ "zod": "^4.2.1"
33
+ },
34
+ "devDependencies": {
35
+ "@timeback/caliper": "0.1.0",
36
+ "@timeback/core": "0.1.0",
37
+ "@timeback/edubridge": "0.1.0",
38
+ "@timeback/internal-cli-infra": "0.0.0",
39
+ "@timeback/internal-client-infra": "0.0.0",
40
+ "@timeback/internal-utils": "0.0.0",
41
+ "@timeback/oneroster": "0.1.0",
42
+ "@timeback/types": "0.0.0",
43
+ "@types/bun": "latest",
44
+ "bun-plugin-dts": "^0.3.0",
45
+ "timeback-studio": "0.1.0"
46
+ },
47
+ "peerDependencies": {
48
+ "typescript": "^5"
49
+ }
50
+ }
package/schema.json ADDED
@@ -0,0 +1,221 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://timeback.dev/schemas/timeback.config.schema.json",
4
+ "title": "Timeback Config",
5
+ "description": "Configuration schema for timeback.config.ts files",
6
+ "type": "object",
7
+ "required": ["name", "courses"],
8
+ "properties": {
9
+ "$schema": {
10
+ "type": "string",
11
+ "description": "JSON Schema reference for editor support"
12
+ },
13
+ "name": {
14
+ "type": "string",
15
+ "minLength": 1,
16
+ "description": "Display name for your app"
17
+ },
18
+ "defaults": {
19
+ "$ref": "#/$defs/CourseDefaults",
20
+ "description": "Default properties applied to all courses"
21
+ },
22
+ "courses": {
23
+ "type": "array",
24
+ "minItems": 1,
25
+ "items": {
26
+ "$ref": "#/$defs/CourseConfig"
27
+ },
28
+ "description": "Courses available in this app"
29
+ }
30
+ },
31
+ "$defs": {
32
+ "TimebackSubject": {
33
+ "type": "string",
34
+ "enum": [
35
+ "Reading",
36
+ "Language",
37
+ "Vocabulary",
38
+ "Social Studies",
39
+ "Writing",
40
+ "Science",
41
+ "FastMath",
42
+ "Math",
43
+ "None"
44
+ ],
45
+ "description": "Subject area"
46
+ },
47
+ "TimebackGrade": {
48
+ "type": "integer",
49
+ "minimum": -1,
50
+ "maximum": 13,
51
+ "description": "Grade level (-1 = Pre-K, 0 = K, 1-12 = grades, 13 = AP)"
52
+ },
53
+ "CourseType": {
54
+ "type": "string",
55
+ "enum": ["base", "hole-filling", "optional"],
56
+ "description": "Course classification type"
57
+ },
58
+ "PublishStatus": {
59
+ "type": "string",
60
+ "enum": ["draft", "testing", "published", "deactivated"],
61
+ "description": "Course publication status"
62
+ },
63
+ "CourseGoals": {
64
+ "type": "object",
65
+ "description": "Daily learning goals for a course",
66
+ "properties": {
67
+ "dailyXp": {
68
+ "type": "integer",
69
+ "minimum": 1,
70
+ "description": "Target XP to earn per day"
71
+ },
72
+ "dailyLessons": {
73
+ "type": "integer",
74
+ "minimum": 1,
75
+ "description": "Target lessons to complete per day"
76
+ },
77
+ "dailyActiveMinutes": {
78
+ "type": "integer",
79
+ "minimum": 1,
80
+ "description": "Target active learning minutes per day"
81
+ },
82
+ "dailyAccuracy": {
83
+ "type": "integer",
84
+ "minimum": 0,
85
+ "maximum": 100,
86
+ "description": "Target accuracy percentage (0-100)"
87
+ },
88
+ "dailyMasteredUnits": {
89
+ "type": "integer",
90
+ "minimum": 1,
91
+ "description": "Target units to master per day"
92
+ }
93
+ },
94
+ "additionalProperties": false
95
+ },
96
+ "CourseMetrics": {
97
+ "type": "object",
98
+ "description": "Aggregate metrics for a course",
99
+ "properties": {
100
+ "totalXp": {
101
+ "type": "integer",
102
+ "minimum": 1,
103
+ "description": "Total XP available in the course"
104
+ },
105
+ "totalLessons": {
106
+ "type": "integer",
107
+ "minimum": 1,
108
+ "description": "Total number of lessons/activities"
109
+ },
110
+ "totalGrades": {
111
+ "type": "integer",
112
+ "minimum": 1,
113
+ "description": "Total grade levels covered"
114
+ }
115
+ },
116
+ "additionalProperties": false
117
+ },
118
+ "CourseIds": {
119
+ "type": ["object", "null"],
120
+ "description": "Environment-specific course IDs (populated by sync)",
121
+ "properties": {
122
+ "staging": {
123
+ "type": "string",
124
+ "description": "Course ID in staging environment"
125
+ },
126
+ "production": {
127
+ "type": "string",
128
+ "description": "Course ID in production environment"
129
+ }
130
+ },
131
+ "additionalProperties": false
132
+ },
133
+ "CourseMetadata": {
134
+ "type": "object",
135
+ "description": "Course metadata (matches API metadata object)",
136
+ "properties": {
137
+ "courseType": {
138
+ "$ref": "#/$defs/CourseType"
139
+ },
140
+ "isSupplemental": {
141
+ "type": "boolean",
142
+ "description": "Whether this is supplemental to a base course"
143
+ },
144
+ "isCustom": {
145
+ "type": "boolean",
146
+ "description": "Whether this is a custom course for an individual student"
147
+ },
148
+ "publishStatus": {
149
+ "$ref": "#/$defs/PublishStatus"
150
+ },
151
+ "contactEmail": {
152
+ "type": "string",
153
+ "format": "email",
154
+ "description": "Contact email for course issues"
155
+ },
156
+ "primaryApp": {
157
+ "type": "string",
158
+ "description": "Primary application identifier"
159
+ },
160
+ "goals": {
161
+ "$ref": "#/$defs/CourseGoals"
162
+ },
163
+ "metrics": {
164
+ "$ref": "#/$defs/CourseMetrics"
165
+ }
166
+ },
167
+ "additionalProperties": false
168
+ },
169
+ "CourseDefaults": {
170
+ "type": "object",
171
+ "description": "Default properties that apply to all courses unless overridden",
172
+ "properties": {
173
+ "courseCode": {
174
+ "type": "string",
175
+ "description": "Course code (e.g., 'MATH101')"
176
+ },
177
+ "level": {
178
+ "type": "string",
179
+ "description": "Course level (e.g., 'AP', 'Honors')"
180
+ },
181
+ "metadata": {
182
+ "$ref": "#/$defs/CourseMetadata"
183
+ }
184
+ },
185
+ "additionalProperties": false
186
+ },
187
+ "CourseConfig": {
188
+ "type": "object",
189
+ "description": "Configuration for a single course",
190
+ "required": ["subject", "grade"],
191
+ "allOf": [
192
+ {
193
+ "$ref": "#/$defs/CourseDefaults"
194
+ }
195
+ ],
196
+ "properties": {
197
+ "subject": {
198
+ "$ref": "#/$defs/TimebackSubject"
199
+ },
200
+ "grade": {
201
+ "$ref": "#/$defs/TimebackGrade"
202
+ },
203
+ "courseCode": {
204
+ "type": "string",
205
+ "description": "Course code (e.g., 'MATH101')"
206
+ },
207
+ "level": {
208
+ "type": "string",
209
+ "description": "Course level (e.g., 'AP', 'Honors')"
210
+ },
211
+ "metadata": {
212
+ "$ref": "#/$defs/CourseMetadata"
213
+ },
214
+ "ids": {
215
+ "$ref": "#/$defs/CourseIds"
216
+ }
217
+ },
218
+ "additionalProperties": false
219
+ }
220
+ }
221
+ }