trellis-hgl-core 0.6.0-beta.18
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/LICENSE +235 -0
- package/dist/channel/api/assert.d.ts +3 -0
- package/dist/channel/api/assert.d.ts.map +1 -0
- package/dist/channel/api/assert.js +11 -0
- package/dist/channel/api/assert.js.map +1 -0
- package/dist/channel/api/context.d.ts +21 -0
- package/dist/channel/api/context.d.ts.map +1 -0
- package/dist/channel/api/context.js +99 -0
- package/dist/channel/api/context.js.map +1 -0
- package/dist/channel/api/create.d.ts +9 -0
- package/dist/channel/api/create.d.ts.map +1 -0
- package/dist/channel/api/create.js +104 -0
- package/dist/channel/api/create.js.map +1 -0
- package/dist/channel/api/inbox.d.ts +51 -0
- package/dist/channel/api/inbox.d.ts.map +1 -0
- package/dist/channel/api/inbox.js +176 -0
- package/dist/channel/api/inbox.js.map +1 -0
- package/dist/channel/api/interrupt.d.ts +31 -0
- package/dist/channel/api/interrupt.d.ts.map +1 -0
- package/dist/channel/api/interrupt.js +102 -0
- package/dist/channel/api/interrupt.js.map +1 -0
- package/dist/channel/api/post-thread.d.ts +14 -0
- package/dist/channel/api/post-thread.d.ts.map +1 -0
- package/dist/channel/api/post-thread.js +106 -0
- package/dist/channel/api/post-thread.js.map +1 -0
- package/dist/channel/api/read.d.ts +17 -0
- package/dist/channel/api/read.d.ts.map +1 -0
- package/dist/channel/api/read.js +44 -0
- package/dist/channel/api/read.js.map +1 -0
- package/dist/channel/api/resolve.d.ts +21 -0
- package/dist/channel/api/resolve.d.ts.map +1 -0
- package/dist/channel/api/resolve.js +28 -0
- package/dist/channel/api/resolve.js.map +1 -0
- package/dist/channel/api/runtime.d.ts +70 -0
- package/dist/channel/api/runtime.d.ts.map +1 -0
- package/dist/channel/api/runtime.js +11 -0
- package/dist/channel/api/runtime.js.map +1 -0
- package/dist/channel/api/send.d.ts +4 -0
- package/dist/channel/api/send.d.ts.map +1 -0
- package/dist/channel/api/send.js +44 -0
- package/dist/channel/api/send.js.map +1 -0
- package/dist/channel/api/spawn.d.ts +13 -0
- package/dist/channel/api/spawn.d.ts.map +1 -0
- package/dist/channel/api/spawn.js +54 -0
- package/dist/channel/api/spawn.js.map +1 -0
- package/dist/channel/api/title.d.ts +5 -0
- package/dist/channel/api/title.d.ts.map +1 -0
- package/dist/channel/api/title.js +40 -0
- package/dist/channel/api/title.js.map +1 -0
- package/dist/channel/api/types.d.ts +64 -0
- package/dist/channel/api/types.d.ts.map +1 -0
- package/dist/channel/api/types.js +2 -0
- package/dist/channel/api/types.js.map +1 -0
- package/dist/channel/api/watch-channels.d.ts +40 -0
- package/dist/channel/api/watch-channels.d.ts.map +1 -0
- package/dist/channel/api/watch-channels.js +143 -0
- package/dist/channel/api/watch-channels.js.map +1 -0
- package/dist/channel/api/watch.d.ts +11 -0
- package/dist/channel/api/watch.d.ts.map +1 -0
- package/dist/channel/api/watch.js +17 -0
- package/dist/channel/api/watch.js.map +1 -0
- package/dist/channel/api/workers.d.ts +69 -0
- package/dist/channel/api/workers.d.ts.map +1 -0
- package/dist/channel/api/workers.js +145 -0
- package/dist/channel/api/workers.js.map +1 -0
- package/dist/channel/index.d.ts +38 -0
- package/dist/channel/index.d.ts.map +1 -0
- package/dist/channel/index.js +23 -0
- package/dist/channel/index.js.map +1 -0
- package/dist/channel/internal/store/channel-metadata.d.ts +23 -0
- package/dist/channel/internal/store/channel-metadata.d.ts.map +1 -0
- package/dist/channel/internal/store/channel-metadata.js +94 -0
- package/dist/channel/internal/store/channel-metadata.js.map +1 -0
- package/dist/channel/internal/store/delivery.d.ts +27 -0
- package/dist/channel/internal/store/delivery.d.ts.map +1 -0
- package/dist/channel/internal/store/delivery.js +37 -0
- package/dist/channel/internal/store/delivery.js.map +1 -0
- package/dist/channel/internal/store/events.d.ts +203 -0
- package/dist/channel/internal/store/events.d.ts.map +1 -0
- package/dist/channel/internal/store/events.js +185 -0
- package/dist/channel/internal/store/events.js.map +1 -0
- package/dist/channel/internal/store/filter.d.ts +22 -0
- package/dist/channel/internal/store/filter.d.ts.map +1 -0
- package/dist/channel/internal/store/filter.js +78 -0
- package/dist/channel/internal/store/filter.js.map +1 -0
- package/dist/channel/internal/store/inbox.d.ts +17 -0
- package/dist/channel/internal/store/inbox.d.ts.map +1 -0
- package/dist/channel/internal/store/inbox.js +30 -0
- package/dist/channel/internal/store/inbox.js.map +1 -0
- package/dist/channel/internal/store/lock.d.ts +17 -0
- package/dist/channel/internal/store/lock.d.ts.map +1 -0
- package/dist/channel/internal/store/lock.js +88 -0
- package/dist/channel/internal/store/lock.js.map +1 -0
- package/dist/channel/internal/store/paths.d.ts +43 -0
- package/dist/channel/internal/store/paths.d.ts.map +1 -0
- package/dist/channel/internal/store/paths.js +233 -0
- package/dist/channel/internal/store/paths.js.map +1 -0
- package/dist/channel/internal/store/schema.d.ts +77 -0
- package/dist/channel/internal/store/schema.d.ts.map +1 -0
- package/dist/channel/internal/store/schema.js +127 -0
- package/dist/channel/internal/store/schema.js.map +1 -0
- package/dist/channel/internal/store/seq.d.ts +12 -0
- package/dist/channel/internal/store/seq.d.ts.map +1 -0
- package/dist/channel/internal/store/seq.js +133 -0
- package/dist/channel/internal/store/seq.js.map +1 -0
- package/dist/channel/internal/store/thread-state.d.ts +37 -0
- package/dist/channel/internal/store/thread-state.d.ts.map +1 -0
- package/dist/channel/internal/store/thread-state.js +206 -0
- package/dist/channel/internal/store/thread-state.js.map +1 -0
- package/dist/channel/internal/store/watch.d.ts +10 -0
- package/dist/channel/internal/store/watch.d.ts.map +1 -0
- package/dist/channel/internal/store/watch.js +122 -0
- package/dist/channel/internal/store/watch.js.map +1 -0
- package/dist/channel/internal/store/worker-state.d.ts +49 -0
- package/dist/channel/internal/store/worker-state.d.ts.map +1 -0
- package/dist/channel/internal/store/worker-state.js +207 -0
- package/dist/channel/internal/store/worker-state.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/mem/adapters/claude.d.ts +22 -0
- package/dist/mem/adapters/claude.d.ts.map +1 -0
- package/dist/mem/adapters/claude.js +252 -0
- package/dist/mem/adapters/claude.js.map +1 -0
- package/dist/mem/adapters/codex.d.ts +35 -0
- package/dist/mem/adapters/codex.d.ts.map +1 -0
- package/dist/mem/adapters/codex.js +222 -0
- package/dist/mem/adapters/codex.js.map +1 -0
- package/dist/mem/adapters/opencode.d.ts +19 -0
- package/dist/mem/adapters/opencode.d.ts.map +1 -0
- package/dist/mem/adapters/opencode.js +25 -0
- package/dist/mem/adapters/opencode.js.map +1 -0
- package/dist/mem/context.d.ts +23 -0
- package/dist/mem/context.d.ts.map +1 -0
- package/dist/mem/context.js +118 -0
- package/dist/mem/context.js.map +1 -0
- package/dist/mem/dialogue.d.ts +17 -0
- package/dist/mem/dialogue.d.ts.map +1 -0
- package/dist/mem/dialogue.js +51 -0
- package/dist/mem/dialogue.js.map +1 -0
- package/dist/mem/filter.d.ts +31 -0
- package/dist/mem/filter.d.ts.map +1 -0
- package/dist/mem/filter.js +70 -0
- package/dist/mem/filter.js.map +1 -0
- package/dist/mem/index.d.ts +18 -0
- package/dist/mem/index.d.ts.map +1 -0
- package/dist/mem/index.js +17 -0
- package/dist/mem/index.js.map +1 -0
- package/dist/mem/internal/jsonl.d.ts +35 -0
- package/dist/mem/internal/jsonl.d.ts.map +1 -0
- package/dist/mem/internal/jsonl.js +125 -0
- package/dist/mem/internal/jsonl.js.map +1 -0
- package/dist/mem/internal/paths.d.ts +18 -0
- package/dist/mem/internal/paths.d.ts.map +1 -0
- package/dist/mem/internal/paths.js +51 -0
- package/dist/mem/internal/paths.js.map +1 -0
- package/dist/mem/phase.d.ts +45 -0
- package/dist/mem/phase.d.ts.map +1 -0
- package/dist/mem/phase.js +220 -0
- package/dist/mem/phase.js.map +1 -0
- package/dist/mem/projects.d.ts +13 -0
- package/dist/mem/projects.d.ts.map +1 -0
- package/dist/mem/projects.js +37 -0
- package/dist/mem/projects.js.map +1 -0
- package/dist/mem/search.d.ts +32 -0
- package/dist/mem/search.d.ts.map +1 -0
- package/dist/mem/search.js +125 -0
- package/dist/mem/search.js.map +1 -0
- package/dist/mem/sessions.d.ts +37 -0
- package/dist/mem/sessions.d.ts.map +1 -0
- package/dist/mem/sessions.js +270 -0
- package/dist/mem/sessions.js.map +1 -0
- package/dist/mem/types.d.ts +176 -0
- package/dist/mem/types.d.ts.map +1 -0
- package/dist/mem/types.js +10 -0
- package/dist/mem/types.js.map +1 -0
- package/dist/task/index.d.ts +9 -0
- package/dist/task/index.d.ts.map +1 -0
- package/dist/task/index.js +9 -0
- package/dist/task/index.js.map +1 -0
- package/dist/task/paths.d.ts +37 -0
- package/dist/task/paths.d.ts.map +1 -0
- package/dist/task/paths.js +49 -0
- package/dist/task/paths.js.map +1 -0
- package/dist/task/phase.d.ts +27 -0
- package/dist/task/phase.d.ts.map +1 -0
- package/dist/task/phase.js +24 -0
- package/dist/task/phase.js.map +1 -0
- package/dist/task/records.d.ts +39 -0
- package/dist/task/records.d.ts.map +1 -0
- package/dist/task/records.js +89 -0
- package/dist/task/records.js.map +1 -0
- package/dist/task/schema.d.ts +77 -0
- package/dist/task/schema.d.ts.map +1 -0
- package/dist/task/schema.js +220 -0
- package/dist/task/schema.js.map +1 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +4 -0
- package/dist/testing/index.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-based advisory lock primitive.
|
|
3
|
+
*
|
|
4
|
+
* Uses `open(path, "wx")` (O_EXCL) for atomic creation across processes.
|
|
5
|
+
* Each lockfile stores the holder's pid for forensic + stale-lock
|
|
6
|
+
* recovery. If a lock file exists but the owning pid is no longer alive,
|
|
7
|
+
* the next `acquireLock` will steal it.
|
|
8
|
+
*/
|
|
9
|
+
import fs from "node:fs";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
const DEFAULT_RETRY_INTERVAL_MS = 25;
|
|
12
|
+
const DEFAULT_MAX_WAIT_MS = 5000;
|
|
13
|
+
export async function acquireLock(lockFile, opts = {}) {
|
|
14
|
+
const interval = opts.retryIntervalMs ?? DEFAULT_RETRY_INTERVAL_MS;
|
|
15
|
+
const deadline = Date.now() + (opts.maxWaitMs ?? DEFAULT_MAX_WAIT_MS);
|
|
16
|
+
fs.mkdirSync(path.dirname(lockFile), { recursive: true });
|
|
17
|
+
while (true) {
|
|
18
|
+
try {
|
|
19
|
+
const fd = fs.openSync(lockFile, "wx");
|
|
20
|
+
fs.writeSync(fd, String(process.pid));
|
|
21
|
+
fs.closeSync(fd);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
if (err.code !== "EEXIST")
|
|
26
|
+
throw err;
|
|
27
|
+
}
|
|
28
|
+
if (await checkAndStealStale(lockFile))
|
|
29
|
+
continue;
|
|
30
|
+
if (Date.now() >= deadline) {
|
|
31
|
+
throw new Error(`Failed to acquire lock ${lockFile} within ${opts.maxWaitMs ?? DEFAULT_MAX_WAIT_MS}ms`);
|
|
32
|
+
}
|
|
33
|
+
await sleep(interval);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export function releaseLock(lockFile) {
|
|
37
|
+
try {
|
|
38
|
+
const content = fs.readFileSync(lockFile, "utf-8").trim();
|
|
39
|
+
if (content === String(process.pid)) {
|
|
40
|
+
fs.unlinkSync(lockFile);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// already gone
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export async function withLock(lockFile, fn, opts) {
|
|
48
|
+
await acquireLock(lockFile, opts);
|
|
49
|
+
try {
|
|
50
|
+
return await fn();
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
releaseLock(lockFile);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function checkAndStealStale(lockFile) {
|
|
57
|
+
let holderPid = 0;
|
|
58
|
+
try {
|
|
59
|
+
holderPid = Number(fs.readFileSync(lockFile, "utf-8").trim());
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
if (!holderPid || !pidAlive(holderPid)) {
|
|
65
|
+
try {
|
|
66
|
+
fs.unlinkSync(lockFile);
|
|
67
|
+
process.stderr.write(`[channel lock] stale lock from dead pid ${holderPid} stolen at ${lockFile}\n`);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
function pidAlive(pid) {
|
|
77
|
+
try {
|
|
78
|
+
process.kill(pid, 0);
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function sleep(ms) {
|
|
86
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../../../../src/channel/internal/store/lock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type ChannelRef, type ChannelScope } from "./schema.js";
|
|
2
|
+
/** Top-level Trellis channels directory. */
|
|
3
|
+
export declare function channelRoot(): string;
|
|
4
|
+
/**
|
|
5
|
+
* Derive a per-project bucket name from an absolute cwd, mirroring
|
|
6
|
+
* Claude Code's `~/.claude/projects/<sanitized-cwd>/` convention.
|
|
7
|
+
*/
|
|
8
|
+
export declare function projectKey(cwd: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Project key for the current CLI invocation. Reads
|
|
11
|
+
* `TRELLIS_CHANNEL_PROJECT` env first, then falls back to deriving from
|
|
12
|
+
* `process.cwd()`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function currentProjectKey(): string;
|
|
15
|
+
export declare function projectDir(project?: string): string;
|
|
16
|
+
export declare function channelDir(name: string, project?: string): string;
|
|
17
|
+
export declare function eventsPath(name: string, project?: string): string;
|
|
18
|
+
export declare function seqSidecarPath(name: string, project?: string): string;
|
|
19
|
+
export declare function lockPath(name: string, project?: string): string;
|
|
20
|
+
export declare function workerFile(name: string, worker: string, suffix: string, project?: string): string;
|
|
21
|
+
export declare function workerLockPath(name: string, worker: string, project?: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* One-shot migration: move legacy flat channels at `<root>/<name>/` into
|
|
24
|
+
* a `_legacy/` bucket so the new project-scoped layout can use the top
|
|
25
|
+
* level. Idempotent.
|
|
26
|
+
*/
|
|
27
|
+
export declare function migrateLegacyChannels(): void;
|
|
28
|
+
export declare function ensureBucketMarker(project: string): void;
|
|
29
|
+
export declare function listProjects(): string[];
|
|
30
|
+
/**
|
|
31
|
+
* List channel names inside a project bucket — subdirectories that
|
|
32
|
+
* contain an `events.jsonl` file. Used by the cross-channel watcher for
|
|
33
|
+
* dynamic channel discovery.
|
|
34
|
+
*/
|
|
35
|
+
export declare function listChannelNamesInProject(project: string): string[];
|
|
36
|
+
export interface ResolveChannelOptions {
|
|
37
|
+
scope?: ChannelScope;
|
|
38
|
+
cwd?: string;
|
|
39
|
+
}
|
|
40
|
+
export declare function resolveChannelProjectForCreate(name: string, opts?: ResolveChannelOptions): ChannelRef;
|
|
41
|
+
export declare function resolveExistingChannelRef(name: string, opts?: ResolveChannelOptions): ChannelRef;
|
|
42
|
+
export declare function selectExistingChannelProject(name: string): string;
|
|
43
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../../src/channel/internal/store/paths.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,YAAY,EAClB,MAAM,aAAa,CAAC;AAErB,4CAA4C;AAC5C,wBAAgB,WAAW,IAAI,MAAM,CAIpC;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI9C;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAI1C;AAED,wBAAgB,UAAU,CAAC,OAAO,GAAE,MAA4B,GAAG,MAAM,CAExE;AAID,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAA4B,GACpC,MAAM,CAER;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAA4B,GACpC,MAAM,CAER;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAA4B,GACpC,MAAM,CAER;AAED,wBAAgB,QAAQ,CACtB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAA4B,GACpC,MAAM,CAER;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,MAA4B,GACpC,MAAM,CAER;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,MAA4B,GACpC,MAAM,CAER;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CA2C5C;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAOxD;AAED,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAqBvC;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBnE;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,qBAA0B,GAC/B,UAAU,CAcZ;AAED,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,qBAA0B,GAC/B,UAAU,CAsEZ;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjE"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { GLOBAL_PROJECT_KEY, } from "./schema.js";
|
|
5
|
+
/** Top-level Trellis channels directory. */
|
|
6
|
+
export function channelRoot() {
|
|
7
|
+
const env = process.env.TRELLIS_CHANNEL_ROOT;
|
|
8
|
+
if (env && env.length > 0)
|
|
9
|
+
return path.resolve(env);
|
|
10
|
+
return path.join(os.homedir(), ".trellis", "channels");
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Derive a per-project bucket name from an absolute cwd, mirroring
|
|
14
|
+
* Claude Code's `~/.claude/projects/<sanitized-cwd>/` convention.
|
|
15
|
+
*/
|
|
16
|
+
export function projectKey(cwd) {
|
|
17
|
+
const abs = path.resolve(cwd);
|
|
18
|
+
const slashes = abs.replace(/[\\/_]/g, "-");
|
|
19
|
+
return slashes.replace(/[^A-Za-z0-9.-]/g, "-");
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Project key for the current CLI invocation. Reads
|
|
23
|
+
* `TRELLIS_CHANNEL_PROJECT` env first, then falls back to deriving from
|
|
24
|
+
* `process.cwd()`.
|
|
25
|
+
*/
|
|
26
|
+
export function currentProjectKey() {
|
|
27
|
+
const env = process.env.TRELLIS_CHANNEL_PROJECT;
|
|
28
|
+
if (env && env.length > 0)
|
|
29
|
+
return env;
|
|
30
|
+
return projectKey(process.cwd());
|
|
31
|
+
}
|
|
32
|
+
export function projectDir(project = currentProjectKey()) {
|
|
33
|
+
return path.join(channelRoot(), project);
|
|
34
|
+
}
|
|
35
|
+
const BUCKET_MARKER = ".bucket";
|
|
36
|
+
export function channelDir(name, project = currentProjectKey()) {
|
|
37
|
+
return path.join(projectDir(project), name);
|
|
38
|
+
}
|
|
39
|
+
export function eventsPath(name, project = currentProjectKey()) {
|
|
40
|
+
return path.join(channelDir(name, project), "events.jsonl");
|
|
41
|
+
}
|
|
42
|
+
export function seqSidecarPath(name, project = currentProjectKey()) {
|
|
43
|
+
return path.join(channelDir(name, project), ".seq");
|
|
44
|
+
}
|
|
45
|
+
export function lockPath(name, project = currentProjectKey()) {
|
|
46
|
+
return path.join(channelDir(name, project), `${name}.lock`);
|
|
47
|
+
}
|
|
48
|
+
export function workerFile(name, worker, suffix, project = currentProjectKey()) {
|
|
49
|
+
return path.join(channelDir(name, project), `${worker}.${suffix}`);
|
|
50
|
+
}
|
|
51
|
+
export function workerLockPath(name, worker, project = currentProjectKey()) {
|
|
52
|
+
return path.join(channelDir(name, project), `${worker}.spawnlock`);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* One-shot migration: move legacy flat channels at `<root>/<name>/` into
|
|
56
|
+
* a `_legacy/` bucket so the new project-scoped layout can use the top
|
|
57
|
+
* level. Idempotent.
|
|
58
|
+
*/
|
|
59
|
+
export function migrateLegacyChannels() {
|
|
60
|
+
const root = channelRoot();
|
|
61
|
+
if (!fs.existsSync(root))
|
|
62
|
+
return;
|
|
63
|
+
const legacy = path.join(root, "_legacy");
|
|
64
|
+
let moved = 0;
|
|
65
|
+
let entries;
|
|
66
|
+
try {
|
|
67
|
+
entries = fs.readdirSync(root);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
for (const entry of entries) {
|
|
73
|
+
if (entry === "_legacy" || entry === "_default")
|
|
74
|
+
continue;
|
|
75
|
+
const dir = path.join(root, entry);
|
|
76
|
+
let stat;
|
|
77
|
+
try {
|
|
78
|
+
stat = fs.statSync(dir);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (!stat.isDirectory())
|
|
84
|
+
continue;
|
|
85
|
+
if (fs.existsSync(path.join(dir, BUCKET_MARKER)))
|
|
86
|
+
continue;
|
|
87
|
+
if (!fs.existsSync(path.join(dir, "events.jsonl")))
|
|
88
|
+
continue;
|
|
89
|
+
fs.mkdirSync(legacy, { recursive: true });
|
|
90
|
+
const target = path.join(legacy, entry);
|
|
91
|
+
try {
|
|
92
|
+
fs.renameSync(dir, target);
|
|
93
|
+
moved++;
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
process.stderr.write(`[channel migrate] failed to move ${entry} to _legacy/: ${err instanceof Error ? err.message : err}\n`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (moved > 0) {
|
|
100
|
+
fs.mkdirSync(legacy, { recursive: true });
|
|
101
|
+
fs.writeFileSync(path.join(legacy, BUCKET_MARKER), "");
|
|
102
|
+
process.stderr.write(`[channel migrate] moved ${moved} legacy channel(s) to ${legacy}\n`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export function ensureBucketMarker(project) {
|
|
106
|
+
const dir = projectDir(project);
|
|
107
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
108
|
+
const marker = path.join(dir, BUCKET_MARKER);
|
|
109
|
+
if (!fs.existsSync(marker)) {
|
|
110
|
+
fs.writeFileSync(marker, "");
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
export function listProjects() {
|
|
114
|
+
const root = channelRoot();
|
|
115
|
+
if (!fs.existsSync(root))
|
|
116
|
+
return [];
|
|
117
|
+
const out = [];
|
|
118
|
+
for (const entry of fs.readdirSync(root)) {
|
|
119
|
+
const dir = path.join(root, entry);
|
|
120
|
+
try {
|
|
121
|
+
if (!fs.statSync(dir).isDirectory())
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (fs.existsSync(path.join(dir, BUCKET_MARKER)) ||
|
|
128
|
+
entry === "_legacy" ||
|
|
129
|
+
entry === "_default" ||
|
|
130
|
+
entry === GLOBAL_PROJECT_KEY) {
|
|
131
|
+
out.push(entry);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* List channel names inside a project bucket — subdirectories that
|
|
138
|
+
* contain an `events.jsonl` file. Used by the cross-channel watcher for
|
|
139
|
+
* dynamic channel discovery.
|
|
140
|
+
*/
|
|
141
|
+
export function listChannelNamesInProject(project) {
|
|
142
|
+
const dir = projectDir(project);
|
|
143
|
+
if (!fs.existsSync(dir))
|
|
144
|
+
return [];
|
|
145
|
+
const out = [];
|
|
146
|
+
let entries;
|
|
147
|
+
try {
|
|
148
|
+
entries = fs.readdirSync(dir);
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
for (const entry of entries) {
|
|
154
|
+
if (entry.startsWith("."))
|
|
155
|
+
continue;
|
|
156
|
+
const channelEvents = path.join(dir, entry, "events.jsonl");
|
|
157
|
+
if (fs.existsSync(channelEvents))
|
|
158
|
+
out.push(entry);
|
|
159
|
+
}
|
|
160
|
+
return out;
|
|
161
|
+
}
|
|
162
|
+
export function resolveChannelProjectForCreate(name, opts = {}) {
|
|
163
|
+
const scope = opts.scope ?? "project";
|
|
164
|
+
const project = scope === "global"
|
|
165
|
+
? GLOBAL_PROJECT_KEY
|
|
166
|
+
: opts.cwd
|
|
167
|
+
? projectKey(opts.cwd)
|
|
168
|
+
: currentProjectKey();
|
|
169
|
+
return {
|
|
170
|
+
name,
|
|
171
|
+
scope,
|
|
172
|
+
project,
|
|
173
|
+
dir: channelDir(name, project),
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
export function resolveExistingChannelRef(name, opts = {}) {
|
|
177
|
+
migrateLegacyChannels();
|
|
178
|
+
if (opts.scope) {
|
|
179
|
+
const project = opts.scope === "global"
|
|
180
|
+
? GLOBAL_PROJECT_KEY
|
|
181
|
+
: opts.cwd
|
|
182
|
+
? projectKey(opts.cwd)
|
|
183
|
+
: currentProjectKey();
|
|
184
|
+
if (!fs.existsSync(eventsPath(name, project))) {
|
|
185
|
+
throw new Error(`Channel '${name}' not found in ${opts.scope} scope (${project})`);
|
|
186
|
+
}
|
|
187
|
+
process.env.TRELLIS_CHANNEL_PROJECT = project;
|
|
188
|
+
return { name, scope: opts.scope, project, dir: channelDir(name, project) };
|
|
189
|
+
}
|
|
190
|
+
const current = currentProjectKey();
|
|
191
|
+
const projectMatches = listProjects()
|
|
192
|
+
.filter((project) => project !== GLOBAL_PROJECT_KEY)
|
|
193
|
+
.filter((project) => fs.existsSync(eventsPath(name, project)));
|
|
194
|
+
const globalExists = fs.existsSync(eventsPath(name, GLOBAL_PROJECT_KEY));
|
|
195
|
+
if (globalExists && projectMatches.length > 0) {
|
|
196
|
+
throw new Error(`Channel '${name}' exists in global and project scopes. Use --scope global or --scope project.`);
|
|
197
|
+
}
|
|
198
|
+
if (globalExists) {
|
|
199
|
+
process.env.TRELLIS_CHANNEL_PROJECT = GLOBAL_PROJECT_KEY;
|
|
200
|
+
return {
|
|
201
|
+
name,
|
|
202
|
+
scope: "global",
|
|
203
|
+
project: GLOBAL_PROJECT_KEY,
|
|
204
|
+
dir: channelDir(name, GLOBAL_PROJECT_KEY),
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
if (fs.existsSync(eventsPath(name, current))) {
|
|
208
|
+
process.env.TRELLIS_CHANNEL_PROJECT = current;
|
|
209
|
+
return {
|
|
210
|
+
name,
|
|
211
|
+
scope: "project",
|
|
212
|
+
project: current,
|
|
213
|
+
dir: channelDir(name, current),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
if (projectMatches.length === 1) {
|
|
217
|
+
process.env.TRELLIS_CHANNEL_PROJECT = projectMatches[0];
|
|
218
|
+
return {
|
|
219
|
+
name,
|
|
220
|
+
scope: "project",
|
|
221
|
+
project: projectMatches[0],
|
|
222
|
+
dir: channelDir(name, projectMatches[0]),
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
if (projectMatches.length > 1) {
|
|
226
|
+
throw new Error(`Channel '${name}' exists in multiple project buckets: ${projectMatches.join(", ")}. Run from the owning project cwd or use --scope.`);
|
|
227
|
+
}
|
|
228
|
+
throw new Error(`Channel '${name}' not found in current project bucket (${current}) or any known scope`);
|
|
229
|
+
}
|
|
230
|
+
export function selectExistingChannelProject(name) {
|
|
231
|
+
return resolveExistingChannelRef(name).project;
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../../src/channel/internal/store/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
export declare const GLOBAL_PROJECT_KEY = "_global";
|
|
2
|
+
export type ChannelScope = "project" | "global";
|
|
3
|
+
/**
|
|
4
|
+
* Channel structural type. `chat` is timeline-first; `forum` is a topic
|
|
5
|
+
* area whose threads are individual topics. Legacy event logs may carry
|
|
6
|
+
* the old `"threads"` / `"thread"` values — readers do NOT normalize them
|
|
7
|
+
* to `forum`; they are treated as non-forum channels. New writes always
|
|
8
|
+
* emit `"forum"`.
|
|
9
|
+
*/
|
|
10
|
+
export type ChannelType = "chat" | "forum";
|
|
11
|
+
export type ThreadAction = "opened" | "comment" | "status" | "labels" | "assignees" | "summary" | "processed" | "rename";
|
|
12
|
+
export type ContextTarget = "channel" | "thread";
|
|
13
|
+
export type ContextMutationAction = "add" | "delete";
|
|
14
|
+
export type EventOrigin = "cli" | "api" | "worker";
|
|
15
|
+
/**
|
|
16
|
+
* Worker inbox delivery policy. `explicitOnly` consumes only messages
|
|
17
|
+
* whose `to` targets the worker (current CLI behavior).
|
|
18
|
+
* `broadcastAndExplicit` also consumes broadcast messages (no `to`).
|
|
19
|
+
* Applies to `kind:"message"` events only.
|
|
20
|
+
*/
|
|
21
|
+
export type InboxPolicy = "explicitOnly" | "broadcastAndExplicit";
|
|
22
|
+
export declare const INBOX_POLICIES: ReadonlySet<InboxPolicy>;
|
|
23
|
+
export declare function parseInboxPolicy(v: string | undefined): InboxPolicy | undefined;
|
|
24
|
+
export declare const CHANNEL_TYPES: ReadonlySet<ChannelType>;
|
|
25
|
+
export declare const THREAD_ACTIONS: ReadonlySet<ThreadAction>;
|
|
26
|
+
export declare const EVENT_ORIGINS: ReadonlySet<EventOrigin>;
|
|
27
|
+
export interface FileContextEntry {
|
|
28
|
+
type: "file";
|
|
29
|
+
path: string;
|
|
30
|
+
}
|
|
31
|
+
export interface RawContextEntry {
|
|
32
|
+
type: "raw";
|
|
33
|
+
text: string;
|
|
34
|
+
}
|
|
35
|
+
export type ContextEntry = FileContextEntry | RawContextEntry;
|
|
36
|
+
/**
|
|
37
|
+
* Legacy alias kept while old code spells the field "linkedContext". New
|
|
38
|
+
* APIs use `ContextEntry`.
|
|
39
|
+
*
|
|
40
|
+
* @deprecated Use {@link ContextEntry} instead.
|
|
41
|
+
*/
|
|
42
|
+
export type LinkedContextEntry = ContextEntry;
|
|
43
|
+
export interface ChannelRef {
|
|
44
|
+
name: string;
|
|
45
|
+
scope: ChannelScope;
|
|
46
|
+
/** Storage project bucket key (not the metadata `project` slug). */
|
|
47
|
+
project: string;
|
|
48
|
+
dir: string;
|
|
49
|
+
}
|
|
50
|
+
export interface ChannelMetadata {
|
|
51
|
+
type: ChannelType;
|
|
52
|
+
title?: string;
|
|
53
|
+
description?: string;
|
|
54
|
+
context?: ContextEntry[];
|
|
55
|
+
labels?: string[];
|
|
56
|
+
}
|
|
57
|
+
export declare function parseChannelScope(v: string | undefined): ChannelScope | undefined;
|
|
58
|
+
export declare function parseChannelType(v: string | undefined): ChannelType;
|
|
59
|
+
export declare function parseThreadAction(v: string): ThreadAction;
|
|
60
|
+
export declare function parseEventOrigin(v: string | undefined): EventOrigin | undefined;
|
|
61
|
+
export declare function normalizeThreadKey(v: string): string;
|
|
62
|
+
/**
|
|
63
|
+
* Build a context entry list from absolute file paths + raw strings. The
|
|
64
|
+
* inputs are typically a CLI flag list and a raw-text list. Returns
|
|
65
|
+
* `undefined` when both lists are empty so callers can spread the field
|
|
66
|
+
* only when present.
|
|
67
|
+
*/
|
|
68
|
+
export declare function buildContextEntries(files: string[] | undefined, raw: string[] | undefined): ContextEntry[] | undefined;
|
|
69
|
+
export declare function asStringArray(value: unknown): string[] | undefined;
|
|
70
|
+
export declare function asContextEntries(value: unknown): ContextEntry[] | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* Identity key for a context entry, used for add/delete projection.
|
|
73
|
+
* File entries identify by absolute path; raw entries identify by the
|
|
74
|
+
* full text body.
|
|
75
|
+
*/
|
|
76
|
+
export declare function contextEntryKey(entry: ContextEntry): string;
|
|
77
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/channel/internal/store/schema.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAE5C,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC;AAChD;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3C,MAAM,MAAM,YAAY,GACpB,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,WAAW,GACX,SAAS,GACT,WAAW,GACX,QAAQ,CAAC;AAEb,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEjD,MAAM,MAAM,qBAAqB,GAAG,KAAK,GAAG,QAAQ,CAAC;AAErD,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,sBAAsB,CAAC;AAElE,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,WAAW,CAGlD,CAAC;AAEH,wBAAgB,gBAAgB,CAC9B,CAAC,EAAE,MAAM,GAAG,SAAS,GACpB,WAAW,GAAG,SAAS,CAQzB;AAED,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,WAAW,CAGjD,CAAC;AAEH,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,YAAY,CASnD,CAAC;AAEH,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,WAAW,CAIjD,CAAC;AAEH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG,eAAe,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAE9C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,YAAY,CAAC;IACpB,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,MAAM,GAAG,SAAS,GACpB,YAAY,GAAG,SAAS,CAM1B;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,CASnE;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,YAAY,CAOzD;AAED,wBAAgB,gBAAgB,CAC9B,CAAC,EAAE,MAAM,GAAG,SAAS,GACpB,WAAW,GAAG,SAAS,CAQzB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CASpD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,EAC3B,GAAG,EAAE,MAAM,EAAE,GAAG,SAAS,GACxB,YAAY,EAAE,GAAG,SAAS,CAgB5B;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,SAAS,CAGlE;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,GACb,YAAY,EAAE,GAAG,SAAS,CAU5B;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAE3D"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
export const GLOBAL_PROJECT_KEY = "_global";
|
|
3
|
+
export const INBOX_POLICIES = new Set([
|
|
4
|
+
"explicitOnly",
|
|
5
|
+
"broadcastAndExplicit",
|
|
6
|
+
]);
|
|
7
|
+
export function parseInboxPolicy(v) {
|
|
8
|
+
if (v === undefined)
|
|
9
|
+
return undefined;
|
|
10
|
+
if (!INBOX_POLICIES.has(v)) {
|
|
11
|
+
throw new Error(`Invalid inbox policy '${v}'. Must be one of: ${[...INBOX_POLICIES].join(", ")}`);
|
|
12
|
+
}
|
|
13
|
+
return v;
|
|
14
|
+
}
|
|
15
|
+
export const CHANNEL_TYPES = new Set([
|
|
16
|
+
"chat",
|
|
17
|
+
"forum",
|
|
18
|
+
]);
|
|
19
|
+
export const THREAD_ACTIONS = new Set([
|
|
20
|
+
"opened",
|
|
21
|
+
"comment",
|
|
22
|
+
"status",
|
|
23
|
+
"labels",
|
|
24
|
+
"assignees",
|
|
25
|
+
"summary",
|
|
26
|
+
"processed",
|
|
27
|
+
"rename",
|
|
28
|
+
]);
|
|
29
|
+
export const EVENT_ORIGINS = new Set([
|
|
30
|
+
"cli",
|
|
31
|
+
"api",
|
|
32
|
+
"worker",
|
|
33
|
+
]);
|
|
34
|
+
export function parseChannelScope(v) {
|
|
35
|
+
if (v === undefined)
|
|
36
|
+
return undefined;
|
|
37
|
+
if (v !== "project" && v !== "global") {
|
|
38
|
+
throw new Error("Invalid --scope. Must be one of: project, global");
|
|
39
|
+
}
|
|
40
|
+
return v;
|
|
41
|
+
}
|
|
42
|
+
export function parseChannelType(v) {
|
|
43
|
+
if (v === undefined)
|
|
44
|
+
return "chat";
|
|
45
|
+
if (v === "thread" || v === "threads") {
|
|
46
|
+
throw new Error(`Invalid --type '${v}'. Use '--type forum'.`);
|
|
47
|
+
}
|
|
48
|
+
if (!CHANNEL_TYPES.has(v)) {
|
|
49
|
+
throw new Error("Invalid --type. Must be one of: chat, forum");
|
|
50
|
+
}
|
|
51
|
+
return v;
|
|
52
|
+
}
|
|
53
|
+
export function parseThreadAction(v) {
|
|
54
|
+
if (!THREAD_ACTIONS.has(v)) {
|
|
55
|
+
throw new Error(`Invalid thread action '${v}'. Must be one of: ${[...THREAD_ACTIONS].join(", ")}`);
|
|
56
|
+
}
|
|
57
|
+
return v;
|
|
58
|
+
}
|
|
59
|
+
export function parseEventOrigin(v) {
|
|
60
|
+
if (v === undefined)
|
|
61
|
+
return undefined;
|
|
62
|
+
if (!EVENT_ORIGINS.has(v)) {
|
|
63
|
+
throw new Error(`Invalid origin '${v}'. Must be one of: ${[...EVENT_ORIGINS].join(", ")}`);
|
|
64
|
+
}
|
|
65
|
+
return v;
|
|
66
|
+
}
|
|
67
|
+
export function normalizeThreadKey(v) {
|
|
68
|
+
const trimmed = v.trim();
|
|
69
|
+
if (!trimmed)
|
|
70
|
+
throw new Error("Thread key must not be empty");
|
|
71
|
+
if (!/^[A-Za-z0-9._-]+$/.test(trimmed)) {
|
|
72
|
+
throw new Error("Thread key may only contain letters, numbers, '.', '_' and '-'");
|
|
73
|
+
}
|
|
74
|
+
return trimmed;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Build a context entry list from absolute file paths + raw strings. The
|
|
78
|
+
* inputs are typically a CLI flag list and a raw-text list. Returns
|
|
79
|
+
* `undefined` when both lists are empty so callers can spread the field
|
|
80
|
+
* only when present.
|
|
81
|
+
*/
|
|
82
|
+
export function buildContextEntries(files, raw) {
|
|
83
|
+
const entries = [];
|
|
84
|
+
for (const file of files ?? []) {
|
|
85
|
+
const value = file.trim();
|
|
86
|
+
if (!path.isAbsolute(value)) {
|
|
87
|
+
throw new Error(`context file must be absolute path: ${file}`);
|
|
88
|
+
}
|
|
89
|
+
entries.push({ type: "file", path: value });
|
|
90
|
+
}
|
|
91
|
+
for (const text of raw ?? []) {
|
|
92
|
+
if (!text.trim()) {
|
|
93
|
+
throw new Error("context raw text must not be empty");
|
|
94
|
+
}
|
|
95
|
+
entries.push({ type: "raw", text });
|
|
96
|
+
}
|
|
97
|
+
return entries.length > 0 ? entries : undefined;
|
|
98
|
+
}
|
|
99
|
+
export function asStringArray(value) {
|
|
100
|
+
if (!Array.isArray(value))
|
|
101
|
+
return undefined;
|
|
102
|
+
return value.filter((item) => typeof item === "string");
|
|
103
|
+
}
|
|
104
|
+
export function asContextEntries(value) {
|
|
105
|
+
if (!Array.isArray(value))
|
|
106
|
+
return undefined;
|
|
107
|
+
const entries = value.filter((entry) => {
|
|
108
|
+
if (!entry || typeof entry !== "object")
|
|
109
|
+
return false;
|
|
110
|
+
const candidate = entry;
|
|
111
|
+
if (candidate.type === "file")
|
|
112
|
+
return typeof candidate.path === "string";
|
|
113
|
+
if (candidate.type === "raw")
|
|
114
|
+
return typeof candidate.text === "string";
|
|
115
|
+
return false;
|
|
116
|
+
});
|
|
117
|
+
return entries.length > 0 ? entries : undefined;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Identity key for a context entry, used for add/delete projection.
|
|
121
|
+
* File entries identify by absolute path; raw entries identify by the
|
|
122
|
+
* full text body.
|
|
123
|
+
*/
|
|
124
|
+
export function contextEntryKey(entry) {
|
|
125
|
+
return entry.type === "file" ? `file:${entry.path}` : `raw:${entry.text}`;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../../src/channel/internal/store/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute the next seq to assign by reconciling the `.seq` sidecar with
|
|
3
|
+
* the JSONL tail. Repairs the sidecar when it is missing, corrupted,
|
|
4
|
+
* lower than the JSONL tail, or ahead of the JSONL tail (for example,
|
|
5
|
+
* after manual corruption or a stale future reservation).
|
|
6
|
+
*
|
|
7
|
+
* Caller must hold the channel lock when invoking this and the
|
|
8
|
+
* subsequent JSONL append + sidecar write.
|
|
9
|
+
*/
|
|
10
|
+
export declare function reconcileSeq(jsonlPath: string, sidecarPath: string): Promise<number>;
|
|
11
|
+
export declare function writeSidecar(sidecarPath: string, seq: number): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=seq.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seq.d.ts","sourceRoot":"","sources":["../../../../src/channel/internal/store/seq.ts"],"names":[],"mappings":"AA+FA;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,CAiBjB;AAED,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,IAAI,CAAC,CAKf"}
|