@codetreker/daynight 0.29.0 → 0.32.1
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 +173 -44
- package/config.example.yml +10 -3
- package/dist/api/index.d.ts +1 -1
- package/dist/api/index.js +1 -1
- package/dist/api/index.js.map +1 -1
- package/dist/api/task-properties.d.ts +1 -0
- package/dist/api/task-properties.js +5 -0
- package/dist/api/task-properties.js.map +1 -1
- package/dist/cli/agent-cli-aliases.d.ts +21 -0
- package/dist/cli/agent-cli-aliases.js +57 -0
- package/dist/cli/agent-cli-aliases.js.map +1 -0
- package/dist/cli/application.js +5 -0
- package/dist/cli/application.js.map +1 -1
- package/dist/cli/cancellation.d.ts +1 -1
- package/dist/cli/cancellation.js.map +1 -1
- package/dist/cli/codex-agent-environment.d.ts +5 -0
- package/dist/cli/codex-agent-environment.js +28 -0
- package/dist/cli/codex-agent-environment.js.map +1 -0
- package/dist/cli/commands.js +1 -0
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/schema.d.ts +5 -1
- package/dist/cli/schema.js.map +1 -1
- package/dist/commands/controller/archive-upload.d.ts +9 -0
- package/dist/commands/controller/archive-upload.js +137 -0
- package/dist/commands/controller/archive-upload.js.map +1 -0
- package/dist/commands/controller/definition.d.ts +1 -0
- package/dist/commands/controller/definition.js +9 -1
- package/dist/commands/controller/definition.js.map +1 -1
- package/dist/commands/controller/independent-archive.d.ts +7 -0
- package/dist/commands/controller/independent-archive.js +71 -0
- package/dist/commands/controller/independent-archive.js.map +1 -0
- package/dist/commands/controller/independent.js +51 -25
- package/dist/commands/controller/independent.js.map +1 -1
- package/dist/commands/controller/index.js +14 -1
- package/dist/commands/controller/index.js.map +1 -1
- package/dist/commands/controller/journal-format.d.ts +4 -0
- package/dist/commands/controller/journal-format.js +66 -0
- package/dist/commands/controller/journal-format.js.map +1 -0
- package/dist/commands/controller/launch-ticket.js +3 -2
- package/dist/commands/controller/launch-ticket.js.map +1 -1
- package/dist/commands/controller/lifecycle-store.d.ts +7 -5
- package/dist/commands/controller/lifecycle-store.js +132 -91
- package/dist/commands/controller/lifecycle-store.js.map +1 -1
- package/dist/commands/controller/local-content.d.ts +11 -6
- package/dist/commands/controller/local-content.js +29 -21
- package/dist/commands/controller/local-content.js.map +1 -1
- package/dist/commands/controller/paths.d.ts +2 -0
- package/dist/commands/controller/paths.js +34 -0
- package/dist/commands/controller/paths.js.map +1 -0
- package/dist/commands/controller/pending-content.d.ts +20 -0
- package/dist/commands/controller/pending-content.js +159 -0
- package/dist/commands/controller/pending-content.js.map +1 -0
- package/dist/commands/controller/providers/codex.js +5 -1
- package/dist/commands/controller/providers/codex.js.map +1 -1
- package/dist/commands/controller/providers/types.d.ts +4 -0
- package/dist/commands/controller/resume-lease-format.d.ts +4 -0
- package/dist/commands/controller/resume-lease-format.js +35 -0
- package/dist/commands/controller/resume-lease-format.js.map +1 -0
- package/dist/commands/controller/resume.js +88 -23
- package/dist/commands/controller/resume.js.map +1 -1
- package/dist/commands/controller/runtime.js +11 -1
- package/dist/commands/controller/runtime.js.map +1 -1
- package/dist/commands/controller/sqlite/journal/001-baseline.sql +17 -0
- package/dist/commands/controller/sqlite/journal/002-projection.sql +8 -0
- package/dist/commands/controller/sqlite/journal/003-operation-acknowledgements.sql +1 -0
- package/dist/commands/controller/sqlite/journal/004-projection-gap.sql +1 -0
- package/dist/commands/controller/sqlite/journal/005-resources.sql +7 -0
- package/dist/commands/controller/sqlite/journal/006-pending-content.sql +12 -0
- package/dist/commands/controller/sqlite/resume-lease/001-baseline.sql +7 -0
- package/dist/commands/project/definition.js +1 -1
- package/dist/commands/project/definition.js.map +1 -1
- package/dist/commands/review/definition.js +3 -3
- package/dist/commands/review/definition.js.map +1 -1
- package/dist/commands/review/listing.js +1 -1
- package/dist/commands/review/listing.js.map +1 -1
- package/dist/commands/review/runtime.js +3 -1
- package/dist/commands/review/runtime.js.map +1 -1
- package/dist/commands/review/sqlite/001-baseline.sql +65 -0
- package/dist/commands/review/sqlite/002-publications.sql +15 -0
- package/dist/commands/review/store-format.d.ts +2 -0
- package/dist/commands/review/store-format.js +35 -0
- package/dist/commands/review/store-format.js.map +1 -0
- package/dist/commands/review/store.d.ts +8 -1
- package/dist/commands/review/store.js +46 -176
- package/dist/commands/review/store.js.map +1 -1
- package/dist/commands/skill/read.d.ts +2 -0
- package/dist/commands/skill/read.js +36 -0
- package/dist/commands/skill/read.js.map +1 -0
- package/dist/commands/skill/skills/using-daynight/references/authorization.md +1 -0
- package/dist/commands/skill/skills/using-daynight/references/autopilot-managed-task.md +19 -7
- package/dist/commands/skill/skills/using-daynight/references/goal.md +33 -8
- package/dist/commands/skill/skills/using-daynight/references/run-task.md +1 -1
- package/dist/commands/skill/skills/using-daynight/references/task-content.md +1 -0
- package/dist/commands/skill/usage.md +162 -0
- package/dist/commands/task/definition.js +1 -1
- package/dist/commands/task/definition.js.map +1 -1
- package/dist/commands/worker/backends/sqlite/001-baseline.sql +4 -0
- package/dist/commands/worker/backends/web-process.js +11 -11
- package/dist/commands/worker/backends/web-process.js.map +1 -1
- package/dist/commands/worker/backends/web-record.d.ts +11 -0
- package/dist/commands/worker/backends/web-record.js +151 -0
- package/dist/commands/worker/backends/web-record.js.map +1 -0
- package/dist/commands/worker/backends/web-store-format.d.ts +2 -0
- package/dist/commands/worker/backends/web-store-format.js +33 -0
- package/dist/commands/worker/backends/web-store-format.js.map +1 -0
- package/dist/commands/worker/backends/web-store.d.ts +5 -1
- package/dist/commands/worker/backends/web-store.js +44 -170
- package/dist/commands/worker/backends/web-store.js.map +1 -1
- package/dist/commands/worker/backends/web.d.ts +1 -0
- package/dist/commands/worker/backends/web.js +13 -4
- package/dist/commands/worker/backends/web.js.map +1 -1
- package/dist/commands/worker/cleanup.d.ts +1 -1
- package/dist/commands/worker/cleanup.js.map +1 -1
- package/dist/commands/worker/coordinator.js +1 -1
- package/dist/commands/worker/coordinator.js.map +1 -1
- package/dist/commands/worker/definition.js +2 -2
- package/dist/commands/worker/definition.js.map +1 -1
- package/dist/commands/worker/diagnostics.d.ts +3 -0
- package/dist/commands/worker/diagnostics.js +15 -0
- package/dist/commands/worker/diagnostics.js.map +1 -1
- package/dist/commands/worker/execution.d.ts +2 -0
- package/dist/commands/worker/execution.js +17 -4
- package/dist/commands/worker/execution.js.map +1 -1
- package/dist/commands/worker/herdr/agents.d.ts +9 -1
- package/dist/commands/worker/herdr/agents.js +22 -6
- package/dist/commands/worker/herdr/agents.js.map +1 -1
- package/dist/commands/worker/herdr/arguments.d.ts +4 -0
- package/dist/commands/worker/herdr/arguments.js +17 -0
- package/dist/commands/worker/herdr/arguments.js.map +1 -1
- package/dist/commands/worker/herdr/codex-config.d.ts +8 -0
- package/dist/commands/worker/herdr/codex-config.js +75 -0
- package/dist/commands/worker/herdr/codex-config.js.map +1 -0
- package/dist/commands/worker/herdr/preflight.js +1 -18
- package/dist/commands/worker/herdr/preflight.js.map +1 -1
- package/dist/commands/worker/herdr.d.ts +6 -2
- package/dist/commands/worker/herdr.js +3 -2
- package/dist/commands/worker/herdr.js.map +1 -1
- package/dist/commands/worker/prompts.js +7 -2
- package/dist/commands/worker/prompts.js.map +1 -1
- package/dist/commands/worker/runtime.js +68 -7
- package/dist/commands/worker/runtime.js.map +1 -1
- package/dist/commands/worker/sqlite/005-baseline.sql +18 -0
- package/dist/commands/worker/store-format.d.ts +2 -0
- package/dist/commands/worker/store-format.js +35 -0
- package/dist/commands/worker/store-format.js.map +1 -0
- package/dist/commands/worker/store.d.ts +2 -0
- package/dist/commands/worker/store.js +36 -69
- package/dist/commands/worker/store.js.map +1 -1
- package/dist/config/agent-cli-aliases.d.ts +5 -0
- package/dist/config/agent-cli-aliases.js +37 -0
- package/dist/config/agent-cli-aliases.js.map +1 -0
- package/dist/config/paths.d.ts +1 -1
- package/dist/config/paths.js +6 -2
- package/dist/config/paths.js.map +1 -1
- package/dist/platform/diagnostics.js +3 -0
- package/dist/platform/diagnostics.js.map +1 -1
- package/dist/platform/instance-lock.d.ts +15 -0
- package/dist/platform/instance-lock.js +45 -3
- package/dist/platform/instance-lock.js.map +1 -1
- package/dist/platform/sqlite-access.d.ts +40 -0
- package/dist/platform/sqlite-access.js +333 -0
- package/dist/platform/sqlite-access.js.map +1 -0
- package/dist/platform/sqlite-error.d.ts +39 -0
- package/dist/platform/sqlite-error.js +36 -0
- package/dist/platform/sqlite-error.js.map +1 -0
- package/dist/platform/sqlite-format.d.ts +31 -0
- package/dist/platform/sqlite-format.js +98 -0
- package/dist/platform/sqlite-format.js.map +1 -0
- package/dist/platform/sqlite-sql.d.ts +12 -0
- package/dist/platform/sqlite-sql.js +61 -0
- package/dist/platform/sqlite-sql.js.map +1 -0
- package/dist/session/archive.d.ts +25 -0
- package/dist/session/archive.js +100 -0
- package/dist/session/archive.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { SqliteAccessError } from "./sqlite-error.js";
|
|
2
|
+
const validVersion = (value) => Number.isInteger(value) && value > 0 && value <= 2_147_483_647;
|
|
3
|
+
export const currentSqliteVersion = (format) => {
|
|
4
|
+
if (!validVersion(format.baseline.version))
|
|
5
|
+
throw new TypeError("SQLite baseline must be a positive signed 32-bit integer.");
|
|
6
|
+
let current = format.baseline.version;
|
|
7
|
+
for (const migration of format.migrations) {
|
|
8
|
+
if (!validVersion(migration.toVersion) || migration.toVersion !== current + 1)
|
|
9
|
+
throw new TypeError("SQLite migration versions must be consecutive after the baseline.");
|
|
10
|
+
current = migration.toVersion;
|
|
11
|
+
}
|
|
12
|
+
return current;
|
|
13
|
+
};
|
|
14
|
+
const versionOf = (db) => db.pragma("user_version", { simple: true });
|
|
15
|
+
const invalid = (format, version, cause) => new SqliteAccessError("invalid-format", { database: format.name, phase: "inspect", fromVersion: version, toVersion: currentSqliteVersion(format) }, cause === undefined ? {} : { cause });
|
|
16
|
+
export const inspectSqlite = (db, format) => {
|
|
17
|
+
const target = currentSqliteVersion(format), version = versionOf(db);
|
|
18
|
+
if (!Number.isInteger(version) || version < 0 || version > target || version !== 0 && version < format.baseline.version)
|
|
19
|
+
throw new SqliteAccessError("unsupported-version", { database: format.name, phase: "inspect", fromVersion: version, toVersion: target });
|
|
20
|
+
try {
|
|
21
|
+
if (version === 0) {
|
|
22
|
+
const objects = db.prepare("SELECT name FROM sqlite_schema WHERE name NOT GLOB 'sqlite_*'").all();
|
|
23
|
+
return { kind: objects.length === 0 ? "empty" : "unversioned", version: 0 };
|
|
24
|
+
}
|
|
25
|
+
format.validateVersioned(db, version);
|
|
26
|
+
return { kind: version === target ? "current" : "outdated", version };
|
|
27
|
+
}
|
|
28
|
+
catch (cause) {
|
|
29
|
+
if (cause instanceof SqliteAccessError)
|
|
30
|
+
throw cause;
|
|
31
|
+
throw invalid(format, version, cause);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
export const assertCurrentSqlite = (db, format) => {
|
|
35
|
+
if (!db.inTransaction)
|
|
36
|
+
throw new Error("SQLite format assertion requires a transaction.");
|
|
37
|
+
const version = versionOf(db), target = currentSqliteVersion(format);
|
|
38
|
+
if (version !== target)
|
|
39
|
+
throw new SqliteAccessError("unsupported-version", { database: format.name, phase: "assert-current", fromVersion: version, toVersion: target });
|
|
40
|
+
};
|
|
41
|
+
const quoteIdentifier = (name) => `"${name.replaceAll('"', '""')}"`;
|
|
42
|
+
const resetUnversionedSqlite = (db) => {
|
|
43
|
+
if (db.pragma("foreign_keys", { simple: true }) !== 0)
|
|
44
|
+
throw new Error("SQLite unversioned reset requires foreign_keys=OFF before beginning the transaction.");
|
|
45
|
+
const objects = db.prepare("SELECT name, type FROM main.sqlite_schema WHERE type IN ('trigger', 'view') AND name NOT GLOB 'sqlite_*' ORDER BY type, name").all();
|
|
46
|
+
for (const object of objects)
|
|
47
|
+
db.exec(`DROP ${object.type.toUpperCase()} main.${quoteIdentifier(object.name)}`);
|
|
48
|
+
const virtualTables = db.pragma("main.table_list")
|
|
49
|
+
.filter(table => table.schema === "main" && !table.name.startsWith("sqlite_") && table.type === "virtual");
|
|
50
|
+
for (const table of virtualTables)
|
|
51
|
+
db.exec(`DROP TABLE main.${quoteIdentifier(table.name)}`);
|
|
52
|
+
if (virtualTables.length !== 0) {
|
|
53
|
+
// FTS5 external content can retain its cached shadow flag after its virtual table is dropped.
|
|
54
|
+
// RESET reloads the schema and keeps schema writes disabled: https://sqlite.org/pragma.html#pragma_writable_schema
|
|
55
|
+
db.pragma("writable_schema = RESET");
|
|
56
|
+
}
|
|
57
|
+
const tables = db.pragma("main.table_list")
|
|
58
|
+
.filter(table => table.schema === "main" && !table.name.startsWith("sqlite_") && (table.type === "table" || table.type === "shadow"));
|
|
59
|
+
for (const table of tables)
|
|
60
|
+
db.exec(`DROP TABLE main.${quoteIdentifier(table.name)}`);
|
|
61
|
+
};
|
|
62
|
+
export const upgradeSqlite = (db, format) => {
|
|
63
|
+
if (!db.inTransaction)
|
|
64
|
+
throw new Error("SQLite migration requires an immediate transaction.");
|
|
65
|
+
const source = inspectSqlite(db, format);
|
|
66
|
+
if (source.kind === "current")
|
|
67
|
+
return null;
|
|
68
|
+
let version = source.version;
|
|
69
|
+
if (source.kind === "empty" || source.kind === "unversioned") {
|
|
70
|
+
try {
|
|
71
|
+
if (source.kind === "unversioned")
|
|
72
|
+
resetUnversionedSqlite(db);
|
|
73
|
+
format.baseline.create(db);
|
|
74
|
+
format.validateVersioned(db, format.baseline.version);
|
|
75
|
+
db.pragma(`user_version = ${format.baseline.version}`);
|
|
76
|
+
version = format.baseline.version;
|
|
77
|
+
}
|
|
78
|
+
catch (cause) {
|
|
79
|
+
throw new SqliteAccessError("migration-failed", { database: format.name, phase: source.kind === "empty" ? "initialize" : "reset", fromVersion: source.version, toVersion: currentSqliteVersion(format), stepVersion: format.baseline.version }, { cause, outcome: "unknown" });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
for (const migration of format.migrations) {
|
|
83
|
+
if (migration.toVersion <= version)
|
|
84
|
+
continue;
|
|
85
|
+
try {
|
|
86
|
+
migration.up(db, source);
|
|
87
|
+
format.validateVersioned(db, migration.toVersion);
|
|
88
|
+
db.pragma(`user_version = ${migration.toVersion}`);
|
|
89
|
+
version = migration.toVersion;
|
|
90
|
+
}
|
|
91
|
+
catch (cause) {
|
|
92
|
+
throw new SqliteAccessError("migration-failed", { database: format.name, phase: "migrate", fromVersion: source.version, toVersion: currentSqliteVersion(format), stepVersion: migration.toVersion }, { cause, outcome: "unknown" });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
format.validateVersioned(db, version);
|
|
96
|
+
return { fromVersion: source.version, toVersion: version, initialized: source.kind === "empty", reset: source.kind === "unversioned" };
|
|
97
|
+
};
|
|
98
|
+
//# sourceMappingURL=sqlite-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-format.js","sourceRoot":"","sources":["../../src/platform/sqlite-format.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type SqliteSchemaObject = {
|
|
2
|
+
readonly name: string;
|
|
3
|
+
readonly type: string;
|
|
4
|
+
readonly sql: string | null;
|
|
5
|
+
};
|
|
6
|
+
export type SqliteSchemaStep = {
|
|
7
|
+
readonly version: number;
|
|
8
|
+
readonly sql: string;
|
|
9
|
+
};
|
|
10
|
+
export declare const loadSqliteSql: (resource: URL) => string;
|
|
11
|
+
export declare const loadSqliteSequence: (directory: URL) => readonly [SqliteSchemaStep, ...SqliteSchemaStep[]];
|
|
12
|
+
export declare const sqliteSchemaSnapshots: (steps: readonly SqliteSchemaStep[]) => ReadonlyMap<number, readonly SqliteSchemaObject[]>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { readFileSync, readdirSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
4
|
+
import Database from "better-sqlite3";
|
|
5
|
+
export const loadSqliteSql = (resource) => {
|
|
6
|
+
const sql = readFileSync(resource, "utf8");
|
|
7
|
+
if (sql.trim().length === 0)
|
|
8
|
+
throw new Error(`SQLite SQL resource is empty: ${resource.href}`);
|
|
9
|
+
return sql;
|
|
10
|
+
};
|
|
11
|
+
export const loadSqliteSequence = (directory) => {
|
|
12
|
+
const files = readdirSync(directory, { withFileTypes: true }).filter(entry => entry.name.toLowerCase().endsWith(".sql")).sort((a, b) => a.name < b.name ? -1 : a.name === b.name ? 0 : 1);
|
|
13
|
+
if (files.length === 0)
|
|
14
|
+
throw new Error(`SQLite SQL sequence is empty: ${directory.href}`);
|
|
15
|
+
let width, previous;
|
|
16
|
+
const resources = files.map(entry => {
|
|
17
|
+
const resource = pathToFileURL(path.join(fileURLToPath(directory), entry.name));
|
|
18
|
+
const match = /^([0-9]{3,})-([a-z][a-z0-9]*(?:-[a-z0-9]+)*)\.sql$/.exec(entry.name);
|
|
19
|
+
if (!entry.isFile() || match === null)
|
|
20
|
+
throw new Error(`Invalid SQLite SQL filename: ${resource.href}`);
|
|
21
|
+
const prefix = match[1], version = Number(prefix);
|
|
22
|
+
if (!Number.isInteger(version) || version < 1 || version > 2_147_483_647)
|
|
23
|
+
throw new Error(`SQLite SQL version must be a positive signed 32-bit integer: ${resource.href}`);
|
|
24
|
+
if (width !== undefined && prefix.length !== width)
|
|
25
|
+
throw new Error(`SQLite SQL version prefixes must use the same zero-padding width: ${resource.href}`);
|
|
26
|
+
if (version === previous)
|
|
27
|
+
throw new Error(`Duplicate SQLite SQL version: ${resource.href}`);
|
|
28
|
+
if (previous !== undefined && version !== previous + 1)
|
|
29
|
+
throw new Error(`SQLite SQL versions must be consecutive after the baseline: ${resource.href}`);
|
|
30
|
+
width = prefix.length;
|
|
31
|
+
previous = version;
|
|
32
|
+
return { version, resource };
|
|
33
|
+
});
|
|
34
|
+
const steps = resources.map(({ version, resource }) => Object.freeze({ version, sql: loadSqliteSql(resource) }));
|
|
35
|
+
return Object.freeze(steps);
|
|
36
|
+
};
|
|
37
|
+
export const sqliteSchemaSnapshots = (steps) => {
|
|
38
|
+
const db = new Database(":memory:"), snapshots = new Map();
|
|
39
|
+
let failed = false, failure;
|
|
40
|
+
try {
|
|
41
|
+
for (const step of steps) {
|
|
42
|
+
db.exec(step.sql);
|
|
43
|
+
const objects = db.prepare("SELECT name, type, sql FROM sqlite_schema WHERE name NOT GLOB 'sqlite_*' ORDER BY name").all();
|
|
44
|
+
snapshots.set(step.version, Object.freeze(objects.map(object => Object.freeze(object))));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (cause) {
|
|
48
|
+
failed = true;
|
|
49
|
+
failure = cause;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
db.close();
|
|
53
|
+
}
|
|
54
|
+
catch (close) {
|
|
55
|
+
throw failed ? new AggregateError([failure, close], "SQLite reference schema construction and connection shutdown failed.") : close;
|
|
56
|
+
}
|
|
57
|
+
if (failed)
|
|
58
|
+
throw failure;
|
|
59
|
+
return snapshots;
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=sqlite-sql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-sql.js","sourceRoot":"","sources":["../../src/platform/sqlite-sql.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type SessionFence, type SessionProvider, type SessionResource, type TimelineEntry } from "./protocol.js";
|
|
2
|
+
export declare const SESSION_ARCHIVE_MAX_BYTES: number;
|
|
3
|
+
export declare const SESSION_ARCHIVE_RESOURCE_MAX_BYTES: number;
|
|
4
|
+
export type SessionArchive = SessionFence & {
|
|
5
|
+
readonly schemaVersion: 1;
|
|
6
|
+
readonly controllerId: string;
|
|
7
|
+
readonly controllerInstanceId: string;
|
|
8
|
+
readonly provider: SessionProvider;
|
|
9
|
+
readonly nativeSessionId: string | null;
|
|
10
|
+
readonly entries: readonly TimelineEntry[];
|
|
11
|
+
readonly resources: readonly {
|
|
12
|
+
readonly resource: SessionResource;
|
|
13
|
+
readonly data: string | null;
|
|
14
|
+
}[];
|
|
15
|
+
};
|
|
16
|
+
export type SessionArchiveStatus = {
|
|
17
|
+
readonly state: "pending" | "ready" | "failed" | "unavailable";
|
|
18
|
+
readonly sha256: string | null;
|
|
19
|
+
readonly byteLength: string | null;
|
|
20
|
+
readonly errorCode: string | null;
|
|
21
|
+
};
|
|
22
|
+
export declare const parseSessionArchiveStatus: (value: unknown) => SessionArchiveStatus;
|
|
23
|
+
export declare const parseSessionArchive: (value: unknown) => SessionArchive;
|
|
24
|
+
/** Structural parsing is synchronous; binary integrity is checked before use. */
|
|
25
|
+
export declare const verifySessionArchiveResources: (archive: SessionArchive) => Promise<void>;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { parseSessionResource, parseTimelineEntry } from "./protocol.js";
|
|
2
|
+
// Archives are inert display records, never native resume or command inputs.
|
|
3
|
+
export const SESSION_ARCHIVE_MAX_BYTES = 64 * 1024 * 1024;
|
|
4
|
+
export const SESSION_ARCHIVE_RESOURCE_MAX_BYTES = 8 * 1024 * 1024;
|
|
5
|
+
const invalid = () => { throw new Error("Invalid Daynight session archive."); };
|
|
6
|
+
const exact = (value, keys) => {
|
|
7
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
8
|
+
return invalid();
|
|
9
|
+
const data = value;
|
|
10
|
+
if (Object.keys(data).length !== keys.length || keys.some(key => !Object.hasOwn(data, key)))
|
|
11
|
+
return invalid();
|
|
12
|
+
return data;
|
|
13
|
+
};
|
|
14
|
+
const uuid = (value) => typeof value === "string" && /^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/.test(value) ? value : invalid();
|
|
15
|
+
const sequence = (value) => typeof value === "string" && /^[1-9][0-9]{0,18}$/.test(value) && BigInt(value) <= 9223372036854775807n ? value : invalid();
|
|
16
|
+
const hash = (value) => typeof value === "string" && /^[0-9a-f]{64}$/.test(value) ? value : invalid();
|
|
17
|
+
export const parseSessionArchiveStatus = (value) => {
|
|
18
|
+
const data = exact(value, ["state", "sha256", "byteLength", "errorCode"]);
|
|
19
|
+
if (!["pending", "ready", "failed", "unavailable"].includes(String(data.state)))
|
|
20
|
+
return invalid();
|
|
21
|
+
if (data.state === "ready") {
|
|
22
|
+
const byteLength = sequence(data.byteLength);
|
|
23
|
+
if (BigInt(byteLength) > BigInt(SESSION_ARCHIVE_MAX_BYTES) || data.errorCode !== null)
|
|
24
|
+
return invalid();
|
|
25
|
+
return { state: "ready", sha256: hash(data.sha256), byteLength, errorCode: null };
|
|
26
|
+
}
|
|
27
|
+
if (data.sha256 !== null || data.byteLength !== null || (data.errorCode !== null && (typeof data.errorCode !== "string" || !/^[a-z_]{1,64}$/.test(data.errorCode))))
|
|
28
|
+
return invalid();
|
|
29
|
+
if (data.state !== "failed" && data.errorCode !== null)
|
|
30
|
+
return invalid();
|
|
31
|
+
return { state: data.state, sha256: null, byteLength: null, errorCode: data.errorCode };
|
|
32
|
+
};
|
|
33
|
+
export const parseSessionArchive = (value) => {
|
|
34
|
+
const test = !!value && typeof value === "object" && Object.hasOwn(value, "testExecutionId");
|
|
35
|
+
const data = exact(value, ["schemaVersion", "sessionId", test ? "testExecutionId" : "claimId", "executionGeneration", "controllerId", "controllerInstanceId", "provider", "nativeSessionId", "entries", "resources"]);
|
|
36
|
+
if (data.schemaVersion !== 1 || !["codex", "claude", "copilot"].includes(String(data.provider)))
|
|
37
|
+
return invalid();
|
|
38
|
+
if (data.nativeSessionId !== null && (typeof data.nativeSessionId !== "string" || !data.nativeSessionId.trim() || !data.nativeSessionId.isWellFormed() || /\p{Cc}/u.test(data.nativeSessionId) || new TextEncoder().encode(data.nativeSessionId).byteLength > 256))
|
|
39
|
+
return invalid();
|
|
40
|
+
if (!Array.isArray(data.entries) || data.entries.length > 100_000 || !Array.isArray(data.resources) || data.resources.length > 1000)
|
|
41
|
+
return invalid();
|
|
42
|
+
const entries = data.entries.map(parseTimelineEntry), ids = new Set();
|
|
43
|
+
let previous = 0n;
|
|
44
|
+
for (const entry of entries) {
|
|
45
|
+
if (ids.has(entry.entryId) || BigInt(entry.entrySeq) <= previous)
|
|
46
|
+
return invalid();
|
|
47
|
+
ids.add(entry.entryId);
|
|
48
|
+
previous = BigInt(entry.entrySeq);
|
|
49
|
+
}
|
|
50
|
+
const resourceIds = new Set();
|
|
51
|
+
const resources = data.resources.map(raw => {
|
|
52
|
+
const item = exact(raw, ["resource", "data"]), resource = parseSessionResource(item.resource);
|
|
53
|
+
if (resourceIds.has(resource.resourceId) || resource.status === "pending")
|
|
54
|
+
return invalid();
|
|
55
|
+
resourceIds.add(resource.resourceId);
|
|
56
|
+
if (resource.status === "available") {
|
|
57
|
+
if (typeof item.data !== "string" || item.data.length > Math.ceil(SESSION_ARCHIVE_RESOURCE_MAX_BYTES / 3) * 4 || item.data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/.test(item.data))
|
|
58
|
+
return invalid();
|
|
59
|
+
let decoded;
|
|
60
|
+
try {
|
|
61
|
+
decoded = atob(item.data);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return invalid();
|
|
65
|
+
}
|
|
66
|
+
if (btoa(decoded) !== item.data || decoded.length > SESSION_ARCHIVE_RESOURCE_MAX_BYTES || String(decoded.length) !== resource.byteLength || resource.sha256 === null)
|
|
67
|
+
return invalid();
|
|
68
|
+
hash(resource.sha256);
|
|
69
|
+
}
|
|
70
|
+
else if (item.data !== null)
|
|
71
|
+
return invalid();
|
|
72
|
+
return { resource, data: item.data };
|
|
73
|
+
});
|
|
74
|
+
for (const entry of entries) {
|
|
75
|
+
const parts = entry.kind === "tool_call" ? entry.output : entry.kind === "user_message" || entry.kind === "assistant_message" ? entry.content : [];
|
|
76
|
+
if (parts.some(part => part.type === "resource" && !resourceIds.has(part.resourceId)))
|
|
77
|
+
return invalid();
|
|
78
|
+
}
|
|
79
|
+
const result = {
|
|
80
|
+
schemaVersion: 1, sessionId: uuid(data.sessionId), executionGeneration: sequence(data.executionGeneration),
|
|
81
|
+
...(test ? { testExecutionId: uuid(data.testExecutionId) } : { claimId: uuid(data.claimId) }),
|
|
82
|
+
controllerId: uuid(data.controllerId), controllerInstanceId: uuid(data.controllerInstanceId),
|
|
83
|
+
provider: data.provider, nativeSessionId: data.nativeSessionId, entries, resources,
|
|
84
|
+
};
|
|
85
|
+
if (new TextEncoder().encode(JSON.stringify(result)).byteLength > SESSION_ARCHIVE_MAX_BYTES)
|
|
86
|
+
return invalid();
|
|
87
|
+
return result;
|
|
88
|
+
};
|
|
89
|
+
/** Structural parsing is synchronous; binary integrity is checked before use. */
|
|
90
|
+
export const verifySessionArchiveResources = async (archive) => {
|
|
91
|
+
for (const { resource, data } of archive.resources) {
|
|
92
|
+
if (data === null)
|
|
93
|
+
continue;
|
|
94
|
+
const bytes = Uint8Array.from(atob(data), value => value.charCodeAt(0));
|
|
95
|
+
const digest = Array.from(new Uint8Array(await crypto.subtle.digest("SHA-256", bytes)), value => value.toString(16).padStart(2, "0")).join("");
|
|
96
|
+
if (digest !== resource.sha256)
|
|
97
|
+
return invalid();
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=archive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/session/archive.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codetreker/daynight",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.1",
|
|
4
4
|
"description": "A client command toolkit for development workflows",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"node": ">=22"
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
|
-
"build": "node scripts/clean-dist.ts && tsc -p tsconfig.build.json && node scripts/copy-
|
|
23
|
+
"build": "node scripts/clean-dist.ts && tsc -p tsconfig.build.json && node scripts/copy-resources.ts",
|
|
24
24
|
"typecheck": "tsc --noEmit",
|
|
25
25
|
"test": "pnpm run build && vitest run",
|
|
26
26
|
"test:apfs": "DAYNIGHT_TEST_APFS=1 vitest run test/commands/review/apfs.test.ts",
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"vite": "8.3.4",
|
|
55
55
|
"vitest": "5.0.5"
|
|
56
56
|
},
|
|
57
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "10f492efd001e6a4ae5a7fbc8b697af53fa71a45"
|
|
58
58
|
}
|