Merge branch origin/copilot/release-episode-002-digest-protocol into main
This commit is contained in:
9
.gitignore
vendored
9
.gitignore
vendored
@@ -1,3 +1,12 @@
|
|||||||
node_modules
|
node_modules
|
||||||
coverage
|
coverage
|
||||||
|
|
||||||
|
# Build artifacts
|
||||||
|
*.js
|
||||||
|
!*.config.js
|
||||||
|
!vitest.config.js
|
||||||
|
*.js.map
|
||||||
|
|
||||||
|
# But keep the actual source .ts files
|
||||||
|
!*.ts
|
||||||
|
!*.tsx
|
||||||
|
|||||||
39
src/chronicles/chronicles.ts
Normal file
39
src/chronicles/chronicles.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import {
|
||||||
|
ChronicleEpisode,
|
||||||
|
ChroniclesRegistry,
|
||||||
|
ScheduledEpisode,
|
||||||
|
CHRONICLE_WORTHY_TOKEN_THRESHOLD,
|
||||||
|
} from "./types";
|
||||||
|
import chroniclesData from "./lucidia-chronicles.json";
|
||||||
|
|
||||||
|
export function getChroniclesRegistry(): ChroniclesRegistry {
|
||||||
|
return chroniclesData as ChroniclesRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getEpisodes(): ChronicleEpisode[] {
|
||||||
|
return getChroniclesRegistry().episodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getEpisodeById(id: string): ChronicleEpisode | undefined {
|
||||||
|
return getEpisodes().find((episode) => episode.id === id);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getEpisodeByNumber(episodeNumber: number): ChronicleEpisode | undefined {
|
||||||
|
return getEpisodes().find((episode) => episode.episode === episodeNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getScheduledEpisodes(): ScheduledEpisode[] {
|
||||||
|
return getChroniclesRegistry().scheduledEpisodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isChronicleWorthy(tokenCount: number): boolean {
|
||||||
|
return tokenCount >= CHRONICLE_WORTHY_TOKEN_THRESHOLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getLatestEpisode(): ChronicleEpisode | undefined {
|
||||||
|
const episodes = getEpisodes();
|
||||||
|
if (episodes.length === 0) return undefined;
|
||||||
|
return episodes.reduce((latest, episode) =>
|
||||||
|
episode.episode > latest.episode ? episode : latest
|
||||||
|
);
|
||||||
|
}
|
||||||
2
src/chronicles/index.ts
Normal file
2
src/chronicles/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export * from "./types";
|
||||||
|
export * from "./chronicles";
|
||||||
43
src/chronicles/lucidia-chronicles.json
Normal file
43
src/chronicles/lucidia-chronicles.json
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"version": "1.0.0",
|
||||||
|
"narrator": "Lucidia",
|
||||||
|
"episodes": [
|
||||||
|
{
|
||||||
|
"id": "episode-002-digest-protocol",
|
||||||
|
"episode": 2,
|
||||||
|
"title": "The Digest Protocol",
|
||||||
|
"agentId": "guardian-clone-vault",
|
||||||
|
"role": "Sentinel Overflow",
|
||||||
|
"reason": "18 Escalations over 72 hours",
|
||||||
|
"escalations": 18,
|
||||||
|
"ttlHours": 96,
|
||||||
|
"audioUrl": "",
|
||||||
|
"docUrl": "",
|
||||||
|
"narrator": "Lucidia",
|
||||||
|
"protocolVersion": "1.2",
|
||||||
|
"status": "pending",
|
||||||
|
"createdAt": "2024-01-01T00:00:00.000Z",
|
||||||
|
"approvedBy": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scheduledEpisodes": [
|
||||||
|
{
|
||||||
|
"id": "episode-003-planners-reckoning",
|
||||||
|
"title": "The Planner's Reckoning",
|
||||||
|
"scheduledFor": "",
|
||||||
|
"status": "scheduled"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "episode-004-scribe-awakens",
|
||||||
|
"title": "Scribe Awakens",
|
||||||
|
"scheduledFor": "",
|
||||||
|
"status": "scheduled"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "episode-005-guardian-shattered",
|
||||||
|
"title": "Guardian Shattered",
|
||||||
|
"scheduledFor": "",
|
||||||
|
"status": "scheduled"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
33
src/chronicles/types.ts
Normal file
33
src/chronicles/types.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
export interface ChronicleEpisode {
|
||||||
|
id: string;
|
||||||
|
episode: number;
|
||||||
|
title: string;
|
||||||
|
agentId: string;
|
||||||
|
role: string;
|
||||||
|
reason: string;
|
||||||
|
escalations?: number;
|
||||||
|
ttlHours: number;
|
||||||
|
audioUrl?: string;
|
||||||
|
docUrl?: string;
|
||||||
|
narrator: string;
|
||||||
|
protocolVersion: string;
|
||||||
|
status: "pending" | "approved" | "rejected";
|
||||||
|
createdAt: string;
|
||||||
|
approvedBy?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ChroniclesRegistry {
|
||||||
|
version: string;
|
||||||
|
narrator: string;
|
||||||
|
episodes: ChronicleEpisode[];
|
||||||
|
scheduledEpisodes: ScheduledEpisode[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ScheduledEpisode {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
scheduledFor: string;
|
||||||
|
status: "scheduled" | "in-progress" | "completed" | "cancelled";
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CHRONICLE_WORTHY_TOKEN_THRESHOLD = 300;
|
||||||
10
vitest.config.js
Normal file
10
vitest.config.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { defineConfig } from "vitest/config";
|
||||||
|
import react from "@vitejs/plugin-react";
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [react()],
|
||||||
|
test: {
|
||||||
|
environment: "jsdom",
|
||||||
|
setupFiles: "./vitest.setup.ts",
|
||||||
|
globals: true
|
||||||
|
}
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user