Merge branch origin/copilot/release-episode-002-digest-protocol into main

This commit is contained in:
Alexa Amundson
2025-11-25 13:36:36 -06:00
6 changed files with 136 additions and 0 deletions

9
.gitignore vendored
View File

@@ -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

View 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
View File

@@ -0,0 +1,2 @@
export * from "./types";
export * from "./chronicles";

View 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
View 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
View 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
}
});