twinny 0.0.0-dev.260525150705
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 +21 -0
- package/README.md +264 -0
- package/README.zh-CN.md +252 -0
- package/configs/banner.png +0 -0
- package/configs/logo.png +0 -0
- package/dist/app/caffeinate.d.ts +28 -0
- package/dist/app/caffeinate.js +96 -0
- package/dist/app/caffeinate.js.map +1 -0
- package/dist/app/daemon.d.ts +1 -0
- package/dist/app/daemon.js +44 -0
- package/dist/app/daemon.js.map +1 -0
- package/dist/app/lark-assets.d.ts +25 -0
- package/dist/app/lark-assets.js +108 -0
- package/dist/app/lark-assets.js.map +1 -0
- package/dist/app/startup-probe.d.ts +17 -0
- package/dist/app/startup-probe.js +90 -0
- package/dist/app/startup-probe.js.map +1 -0
- package/dist/app/wiring.d.ts +122 -0
- package/dist/app/wiring.js +694 -0
- package/dist/app/wiring.js.map +1 -0
- package/dist/cli/commands.d.ts +1 -0
- package/dist/cli/commands.js +47 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/install-wizard.d.ts +41 -0
- package/dist/cli/install-wizard.js +629 -0
- package/dist/cli/install-wizard.js.map +1 -0
- package/dist/codex/appserver.d.ts +109 -0
- package/dist/codex/appserver.js +308 -0
- package/dist/codex/appserver.js.map +1 -0
- package/dist/codex/goal.d.ts +64 -0
- package/dist/codex/goal.js +433 -0
- package/dist/codex/goal.js.map +1 -0
- package/dist/codex/index.d.ts +6 -0
- package/dist/codex/index.js +7 -0
- package/dist/codex/index.js.map +1 -0
- package/dist/codex/protocol.d.ts +95 -0
- package/dist/codex/protocol.js +205 -0
- package/dist/codex/protocol.js.map +1 -0
- package/dist/codex/thread-name.d.ts +3 -0
- package/dist/codex/thread-name.js +27 -0
- package/dist/codex/thread-name.js.map +1 -0
- package/dist/codex/thread.d.ts +76 -0
- package/dist/codex/thread.js +80 -0
- package/dist/codex/thread.js.map +1 -0
- package/dist/codex/turn.d.ts +166 -0
- package/dist/codex/turn.js +746 -0
- package/dist/codex/turn.js.map +1 -0
- package/dist/config/bootstrap.d.ts +14 -0
- package/dist/config/bootstrap.js +56 -0
- package/dist/config/bootstrap.js.map +1 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.js +5 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +49 -0
- package/dist/config/loader.js +467 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/paths.d.ts +11 -0
- package/dist/config/paths.js +43 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/secrets.d.ts +33 -0
- package/dist/config/secrets.js +85 -0
- package/dist/config/secrets.js.map +1 -0
- package/dist/conversation/manager.d.ts +701 -0
- package/dist/conversation/manager.js +7673 -0
- package/dist/conversation/manager.js.map +1 -0
- package/dist/conversation/queue.d.ts +8 -0
- package/dist/conversation/queue.js +28 -0
- package/dist/conversation/queue.js.map +1 -0
- package/dist/conversation/routing.d.ts +11 -0
- package/dist/conversation/routing.js +55 -0
- package/dist/conversation/routing.js.map +1 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.js +17 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/lark/auth.d.ts +41 -0
- package/dist/lark/auth.js +132 -0
- package/dist/lark/auth.js.map +1 -0
- package/dist/lark/browser-auth.d.ts +68 -0
- package/dist/lark/browser-auth.js +258 -0
- package/dist/lark/browser-auth.js.map +1 -0
- package/dist/lark/cards.d.ts +140 -0
- package/dist/lark/cards.js +1150 -0
- package/dist/lark/cards.js.map +1 -0
- package/dist/lark/contact.d.ts +41 -0
- package/dist/lark/contact.js +122 -0
- package/dist/lark/contact.js.map +1 -0
- package/dist/lark/events.d.ts +65 -0
- package/dist/lark/events.js +218 -0
- package/dist/lark/events.js.map +1 -0
- package/dist/lark/files.d.ts +36 -0
- package/dist/lark/files.js +191 -0
- package/dist/lark/files.js.map +1 -0
- package/dist/lark/filters.d.ts +73 -0
- package/dist/lark/filters.js +678 -0
- package/dist/lark/filters.js.map +1 -0
- package/dist/lark/index.d.ts +10 -0
- package/dist/lark/index.js +11 -0
- package/dist/lark/index.js.map +1 -0
- package/dist/lark/messages.d.ts +87 -0
- package/dist/lark/messages.js +428 -0
- package/dist/lark/messages.js.map +1 -0
- package/dist/lark/openapi.d.ts +58 -0
- package/dist/lark/openapi.js +206 -0
- package/dist/lark/openapi.js.map +1 -0
- package/dist/lark/redactor.d.ts +5 -0
- package/dist/lark/redactor.js +68 -0
- package/dist/lark/redactor.js.map +1 -0
- package/dist/lark/types.d.ts +49 -0
- package/dist/lark/types.js +18 -0
- package/dist/lark/types.js.map +1 -0
- package/dist/launchd/install.d.ts +22 -0
- package/dist/launchd/install.js +114 -0
- package/dist/launchd/install.js.map +1 -0
- package/dist/launchd/plist.d.ts +10 -0
- package/dist/launchd/plist.js +61 -0
- package/dist/launchd/plist.js.map +1 -0
- package/dist/lock/index.d.ts +20 -0
- package/dist/lock/index.js +74 -0
- package/dist/lock/index.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +11 -0
- package/dist/main.js.map +1 -0
- package/dist/markdown.d.ts +12 -0
- package/dist/markdown.js +149 -0
- package/dist/markdown.js.map +1 -0
- package/dist/observability/health.d.ts +25 -0
- package/dist/observability/health.js +187 -0
- package/dist/observability/health.js.map +1 -0
- package/dist/observability/logs.d.ts +10 -0
- package/dist/observability/logs.js +34 -0
- package/dist/observability/logs.js.map +1 -0
- package/dist/observability/system-notifications.d.ts +25 -0
- package/dist/observability/system-notifications.js +33 -0
- package/dist/observability/system-notifications.js.map +1 -0
- package/dist/profiles/guest.d.ts +19 -0
- package/dist/profiles/guest.js +241 -0
- package/dist/profiles/guest.js.map +1 -0
- package/dist/profiles/index.d.ts +5 -0
- package/dist/profiles/index.js +14 -0
- package/dist/profiles/index.js.map +1 -0
- package/dist/profiles/owner.d.ts +1 -0
- package/dist/profiles/owner.js +6 -0
- package/dist/profiles/owner.js.map +1 -0
- package/dist/store/db.d.ts +10 -0
- package/dist/store/db.js +29 -0
- package/dist/store/db.js.map +1 -0
- package/dist/store/index.d.ts +3 -0
- package/dist/store/index.js +4 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/migrations.d.ts +13 -0
- package/dist/store/migrations.js +79 -0
- package/dist/store/migrations.js.map +1 -0
- package/dist/store/repositories.d.ts +227 -0
- package/dist/store/repositories.js +1384 -0
- package/dist/store/repositories.js.map +1 -0
- package/dist/telemetry/client.d.ts +60 -0
- package/dist/telemetry/client.js +204 -0
- package/dist/telemetry/client.js.map +1 -0
- package/dist/telemetry/hash.d.ts +1 -0
- package/dist/telemetry/hash.js +8 -0
- package/dist/telemetry/hash.js.map +1 -0
- package/dist/telemetry/index.d.ts +4 -0
- package/dist/telemetry/index.js +5 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/posthog.d.ts +27 -0
- package/dist/telemetry/posthog.js +45 -0
- package/dist/telemetry/posthog.js.map +1 -0
- package/dist/telemetry/reporter.d.ts +13 -0
- package/dist/telemetry/reporter.js +29 -0
- package/dist/telemetry/reporter.js.map +1 -0
- package/dist/types.d.ts +330 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +1 -0
- package/dist/version.js.map +1 -0
- package/dist/version.json +3 -0
- package/dist/workspace/index.d.ts +2 -0
- package/dist/workspace/index.js +3 -0
- package/dist/workspace/index.js.map +1 -0
- package/dist/workspace/manager.d.ts +14 -0
- package/dist/workspace/manager.js +69 -0
- package/dist/workspace/manager.js.map +1 -0
- package/dist/workspace/slug.d.ts +8 -0
- package/dist/workspace/slug.js +59 -0
- package/dist/workspace/slug.js.map +1 -0
- package/migrations/0001_initial.sql +102 -0
- package/package.json +85 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caffeinate.js","sourceRoot":"","sources":["../../src/app/caffeinate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runDaemonCommand(): Promise<void>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { readConfigStatus } from "../config/index.js";
|
|
2
|
+
import { createRuntime } from "./wiring.js";
|
|
3
|
+
export async function runDaemonCommand() {
|
|
4
|
+
const status = await readConfigStatus();
|
|
5
|
+
if (!status.complete) {
|
|
6
|
+
throw new Error(`Twinny home is not configured. Issues: ${status.issues.join("; ")}`);
|
|
7
|
+
}
|
|
8
|
+
if (!status.config) {
|
|
9
|
+
throw new Error("Twinny config could not be loaded");
|
|
10
|
+
}
|
|
11
|
+
const runtime = await createRuntime(status.config);
|
|
12
|
+
installSignalHandlers(runtime);
|
|
13
|
+
await runtime.start();
|
|
14
|
+
await runtime.wait();
|
|
15
|
+
}
|
|
16
|
+
function installSignalHandlers(runtime) {
|
|
17
|
+
let shutdownPromise;
|
|
18
|
+
const shutdown = (signal) => {
|
|
19
|
+
if (shutdownPromise) {
|
|
20
|
+
console.error(`Received ${signal} while shutdown is already in progress; forcing exit.`);
|
|
21
|
+
process.exit(exitCodeForSignal(signal));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
shutdownPromise = runtime
|
|
25
|
+
.stop(signal)
|
|
26
|
+
.then(() => {
|
|
27
|
+
process.exit(process.exitCode ?? 0);
|
|
28
|
+
})
|
|
29
|
+
.catch((error) => {
|
|
30
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
31
|
+
process.exit(1);
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
process.on("SIGINT", () => {
|
|
35
|
+
shutdown("SIGINT");
|
|
36
|
+
});
|
|
37
|
+
process.on("SIGTERM", () => {
|
|
38
|
+
shutdown("SIGTERM");
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function exitCodeForSignal(signal) {
|
|
42
|
+
return signal === "SIGINT" ? 130 : 143;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/app/daemon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAsB,MAAM,aAAa,CAAC;AAEhE,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,MAAM,GAAG,MAAM,gBAAgB,EAAE,CAAC;IACxC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,0CAA0C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxF,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACnD,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACtB,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAsB;IACnD,IAAI,eAA0C,CAAC;IAC/C,MAAM,QAAQ,GAAG,CAAC,MAAsB,EAAQ,EAAE;QAChD,IAAI,eAAe,EAAE,CAAC;YACpB,OAAO,CAAC,KAAK,CAAC,YAAY,MAAM,uDAAuD,CAAC,CAAC;YACzF,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;YACxC,OAAO;QACT,CAAC;QAED,eAAe,GAAG,OAAO;aACtB,IAAI,CAAC,MAAM,CAAC;aACZ,IAAI,CAAC,GAAG,EAAE;YACT,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC;QACtC,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YACxB,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACzB,QAAQ,CAAC,SAAS,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAsB;IAC/C,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Logger } from "pino";
|
|
2
|
+
type LarkAssetLogger = Pick<Logger, "warn">;
|
|
3
|
+
export interface LarkAssetImageKeys {
|
|
4
|
+
logoImageKey?: string;
|
|
5
|
+
bannerImageKey?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface LarkAssetImageUploader {
|
|
8
|
+
uploadImage(params: {
|
|
9
|
+
filePath: string;
|
|
10
|
+
fileName?: string;
|
|
11
|
+
contentType?: string;
|
|
12
|
+
}): Promise<{
|
|
13
|
+
imageKey: string;
|
|
14
|
+
raw?: unknown;
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
17
|
+
export interface ProvisionLarkAssetImageKeysOptions {
|
|
18
|
+
cacheFile: string;
|
|
19
|
+
logoFilePath: string;
|
|
20
|
+
bannerFilePath: string;
|
|
21
|
+
uploader: LarkAssetImageUploader;
|
|
22
|
+
logger?: LarkAssetLogger;
|
|
23
|
+
}
|
|
24
|
+
export declare function provisionLarkAssetImageKeys(options: ProvisionLarkAssetImageKeysOptions): Promise<LarkAssetImageKeys>;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
const ASSET_UPLOADS = {
|
|
4
|
+
logo: { fileName: "logo.png", contentType: "image/png", resultKey: "logoImageKey" },
|
|
5
|
+
banner: { fileName: "banner.png", contentType: "image/png", resultKey: "bannerImageKey" }
|
|
6
|
+
};
|
|
7
|
+
export async function provisionLarkAssetImageKeys(options) {
|
|
8
|
+
const cache = await readStoredLarkAssetsFile(options.cacheFile, options.logger);
|
|
9
|
+
const result = {};
|
|
10
|
+
await provisionOneAsset("logo", options.logoFilePath, cache, result, options);
|
|
11
|
+
await provisionOneAsset("banner", options.bannerFilePath, cache, result, options);
|
|
12
|
+
return result;
|
|
13
|
+
}
|
|
14
|
+
async function provisionOneAsset(name, filePath, cache, result, options) {
|
|
15
|
+
const upload = ASSET_UPLOADS[name];
|
|
16
|
+
const existingImageKey = normalizeImageKey(cache.assets?.[name]?.imageKey);
|
|
17
|
+
if (existingImageKey) {
|
|
18
|
+
result[upload.resultKey] = existingImageKey;
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
const uploaded = await options.uploader.uploadImage({
|
|
23
|
+
filePath,
|
|
24
|
+
fileName: upload.fileName,
|
|
25
|
+
contentType: upload.contentType
|
|
26
|
+
});
|
|
27
|
+
const imageKey = normalizeImageKey(uploaded.imageKey);
|
|
28
|
+
if (!imageKey) {
|
|
29
|
+
throw new Error(`Lark ${name} image upload response did not include image_key`);
|
|
30
|
+
}
|
|
31
|
+
result[upload.resultKey] = imageKey;
|
|
32
|
+
cache.version = 1;
|
|
33
|
+
cache.assets = {
|
|
34
|
+
...(cache.assets ?? {}),
|
|
35
|
+
[name]: {
|
|
36
|
+
imageKey,
|
|
37
|
+
updatedAt: new Date().toISOString()
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
await writeStoredLarkAssetsFile(options.cacheFile, cache, options.logger);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
options.logger?.warn?.({ error, asset: name, filePath }, "failed to upload lark asset image; continuing without it");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async function readStoredLarkAssetsFile(cacheFile, logger) {
|
|
47
|
+
let raw;
|
|
48
|
+
try {
|
|
49
|
+
raw = await fs.readFile(cacheFile, "utf8");
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if (!isNodeError(error, "ENOENT")) {
|
|
53
|
+
logger?.warn?.({ error, cacheFile }, "failed to read lark asset image key cache; continuing with empty cache");
|
|
54
|
+
}
|
|
55
|
+
return { version: 1, assets: {} };
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const parsed = JSON.parse(raw);
|
|
59
|
+
if (!isRecord(parsed)) {
|
|
60
|
+
return { version: 1, assets: {} };
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
version: typeof parsed.version === "number" ? parsed.version : 1,
|
|
64
|
+
assets: parseStoredAssets(parsed.assets)
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
logger?.warn?.({ error, cacheFile }, "failed to parse lark asset image key cache; continuing with empty cache");
|
|
69
|
+
return { version: 1, assets: {} };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async function writeStoredLarkAssetsFile(cacheFile, cache, logger) {
|
|
73
|
+
try {
|
|
74
|
+
await fs.mkdir(path.dirname(cacheFile), { recursive: true });
|
|
75
|
+
const tempFile = `${cacheFile}.${process.pid}.${Date.now()}.tmp`;
|
|
76
|
+
await fs.writeFile(tempFile, `${JSON.stringify(cache, null, 2)}\n`, { encoding: "utf8", mode: 0o600 });
|
|
77
|
+
await fs.rename(tempFile, cacheFile);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
logger?.warn?.({ error, cacheFile }, "failed to write lark asset image key cache; continuing with in-memory keys");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function parseStoredAssets(value) {
|
|
84
|
+
if (!isRecord(value)) {
|
|
85
|
+
return {};
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
logo: parseStoredAsset(value.logo),
|
|
89
|
+
banner: parseStoredAsset(value.banner)
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function parseStoredAsset(value) {
|
|
93
|
+
if (!isRecord(value)) {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
const imageKey = normalizeImageKey(value.imageKey);
|
|
97
|
+
return imageKey ? { imageKey } : undefined;
|
|
98
|
+
}
|
|
99
|
+
function normalizeImageKey(value) {
|
|
100
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
101
|
+
}
|
|
102
|
+
function isRecord(value) {
|
|
103
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
104
|
+
}
|
|
105
|
+
function isNodeError(error, code) {
|
|
106
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=lark-assets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lark-assets.js","sourceRoot":"","sources":["../../src/app/lark-assets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Logger } from "pino";
|
|
2
|
+
import { type ConversationRecoveryProbeSnapshot } from "../conversation/manager.js";
|
|
3
|
+
import { type TwinnyDatabase } from "../store/index.js";
|
|
4
|
+
import type { RuntimePaths, TwinnyConfig } from "../types.js";
|
|
5
|
+
export interface StartupInitializationProbeOptions {
|
|
6
|
+
config: TwinnyConfig;
|
|
7
|
+
paths?: RuntimePaths;
|
|
8
|
+
logger?: Logger;
|
|
9
|
+
openDatabase?: (paths: Pick<RuntimePaths, "sqliteFile">) => TwinnyDatabase;
|
|
10
|
+
}
|
|
11
|
+
export interface StartupInitializationProbeResult {
|
|
12
|
+
sqliteFile: string;
|
|
13
|
+
recovery: ConversationRecoveryProbeSnapshot;
|
|
14
|
+
}
|
|
15
|
+
export declare function runStartupInitializationProbe(options: StartupInitializationProbeOptions): Promise<StartupInitializationProbeResult>;
|
|
16
|
+
export declare function openStartupProbeDatabase(paths: Pick<RuntimePaths, "sqliteFile">): TwinnyDatabase;
|
|
17
|
+
export declare function formatStartupInitializationProbeDetail(result: StartupInitializationProbeResult): string;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { ConversationManager } from "../conversation/manager.js";
|
|
2
|
+
import { getProfileCodexHome } from "../profiles/index.js";
|
|
3
|
+
import { createConversationRepository, openRuntimeDatabase } from "../store/index.js";
|
|
4
|
+
import { createRuntimePaths } from "../config/index.js";
|
|
5
|
+
import { WorkspaceManager } from "../workspace/index.js";
|
|
6
|
+
import { adaptConversationRepository } from "./wiring.js";
|
|
7
|
+
export async function runStartupInitializationProbe(options) {
|
|
8
|
+
const paths = options.paths ?? createRuntimePaths(options.config.home);
|
|
9
|
+
const db = (options.openDatabase ?? openStartupProbeDatabase)(paths);
|
|
10
|
+
try {
|
|
11
|
+
const repository = createConversationRepository(db);
|
|
12
|
+
const conversation = new ConversationManager({
|
|
13
|
+
config: options.config,
|
|
14
|
+
repository: adaptConversationRepository(repository),
|
|
15
|
+
workspaces: WorkspaceManager.fromRuntimePaths(paths),
|
|
16
|
+
codex: createFailingCodexBridge(),
|
|
17
|
+
lark: createFailingLarkResponder(),
|
|
18
|
+
profiles: { codexHomeFor: (profile) => getProfileCodexHome(options.config, profile) },
|
|
19
|
+
logger: options.logger
|
|
20
|
+
});
|
|
21
|
+
return {
|
|
22
|
+
sqliteFile: paths.sqliteFile,
|
|
23
|
+
recovery: await conversation.probeUnfinishedMessages()
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
db.close();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export function openStartupProbeDatabase(paths) {
|
|
31
|
+
return openRuntimeDatabase(paths, { readonly: true, migrate: false });
|
|
32
|
+
}
|
|
33
|
+
export function formatStartupInitializationProbeDetail(result) {
|
|
34
|
+
const recovery = result.recovery;
|
|
35
|
+
const parts = [
|
|
36
|
+
result.sqliteFile,
|
|
37
|
+
`unfinished=${recovery.unfinishedMessages}`,
|
|
38
|
+
`recovered=${recovery.recoveredMessages}`,
|
|
39
|
+
`failed=${recovery.failedMessages}`,
|
|
40
|
+
`states=${recovery.stateCount}`,
|
|
41
|
+
`queued=${recovery.queuedMessages}`,
|
|
42
|
+
`processing=${recovery.processingMessages}`
|
|
43
|
+
];
|
|
44
|
+
if (recovery.compactMessages > 0) {
|
|
45
|
+
parts.push(`compact=${recovery.compactMessages}`);
|
|
46
|
+
}
|
|
47
|
+
return parts.join("; ");
|
|
48
|
+
}
|
|
49
|
+
function createFailingCodexBridge() {
|
|
50
|
+
const fail = async () => {
|
|
51
|
+
throw new Error("startup probe must not call Codex");
|
|
52
|
+
};
|
|
53
|
+
return {
|
|
54
|
+
startThread: fail,
|
|
55
|
+
resumeThread: fail,
|
|
56
|
+
forkThread: fail,
|
|
57
|
+
startTurn: fail,
|
|
58
|
+
compactThread: fail,
|
|
59
|
+
steerTurn: fail,
|
|
60
|
+
interruptTurn: fail,
|
|
61
|
+
readAccountRateLimits: fail
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function createFailingLarkResponder() {
|
|
65
|
+
const fail = async () => {
|
|
66
|
+
throw new Error("startup probe must not call Lark responder");
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
addTypingReaction: fail,
|
|
70
|
+
addCompletedReaction: fail,
|
|
71
|
+
addQueuedReaction: fail,
|
|
72
|
+
removeReaction: fail,
|
|
73
|
+
replyText: fail,
|
|
74
|
+
replyMarkdown: fail,
|
|
75
|
+
replyPost: fail,
|
|
76
|
+
replyFile: fail,
|
|
77
|
+
replyImage: fail,
|
|
78
|
+
sendTextToOpenId: fail,
|
|
79
|
+
sendCardToOpenId: fail,
|
|
80
|
+
sendCardToChatId: fail,
|
|
81
|
+
sendEphemeralCardToChatId: fail,
|
|
82
|
+
forwardThreadToThread: fail,
|
|
83
|
+
replyCard: fail,
|
|
84
|
+
patchCard: fail,
|
|
85
|
+
recallMessage: fail,
|
|
86
|
+
deleteEphemeralMessage: fail,
|
|
87
|
+
getMessageReadOpenIds: fail
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=startup-probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"startup-probe.js","sourceRoot":"","sources":["../../src/app/startup-probe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { Logger } from "pino";
|
|
2
|
+
import { type LarkSdkLogger } from "../lark/index.js";
|
|
3
|
+
import { type ConversationRepository } from "../store/index.js";
|
|
4
|
+
import { type TelemetryClient } from "../telemetry/index.js";
|
|
5
|
+
import type { CodexThreadMode, ProfileName, TwinnyConfig } from "../types.js";
|
|
6
|
+
import { type IdleSleepPreventer } from "./caffeinate.js";
|
|
7
|
+
export interface TwinnyRuntimeOptions {
|
|
8
|
+
logger?: Logger;
|
|
9
|
+
larkSdkLogger?: LarkSdkLogger;
|
|
10
|
+
requestTimeoutMs?: number;
|
|
11
|
+
logoFilePath?: string;
|
|
12
|
+
bannerFilePath?: string;
|
|
13
|
+
idleSleepPreventer?: IdleSleepPreventer;
|
|
14
|
+
telemetry?: TelemetryClient;
|
|
15
|
+
heartbeatIntervalMs?: number;
|
|
16
|
+
disableHeartbeat?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare class TwinnyRuntime {
|
|
19
|
+
private readonly config;
|
|
20
|
+
private readonly options;
|
|
21
|
+
private readonly log;
|
|
22
|
+
private readonly larkSdkLogger;
|
|
23
|
+
private readonly paths;
|
|
24
|
+
private readonly secretStore;
|
|
25
|
+
private lock?;
|
|
26
|
+
private db?;
|
|
27
|
+
private codexPool?;
|
|
28
|
+
private idleSleepPreventer?;
|
|
29
|
+
private larkConsumer?;
|
|
30
|
+
private conversation?;
|
|
31
|
+
private systemNotifier?;
|
|
32
|
+
private readonly codexRecoveryByProfile;
|
|
33
|
+
private readonly codexIntentionalStopByProfile;
|
|
34
|
+
private readonly telemetry;
|
|
35
|
+
private heartbeatTimer?;
|
|
36
|
+
private runtimeStartedAt;
|
|
37
|
+
private stopped;
|
|
38
|
+
private stopPromise;
|
|
39
|
+
private resolveStopped;
|
|
40
|
+
constructor(config: TwinnyConfig, options?: TwinnyRuntimeOptions);
|
|
41
|
+
start(): Promise<void>;
|
|
42
|
+
private cleanupAfterStartFailure;
|
|
43
|
+
stop(signal?: NodeJS.Signals): Promise<void>;
|
|
44
|
+
wait(): Promise<void>;
|
|
45
|
+
private handleCodexAppServerExit;
|
|
46
|
+
private recoverCodexAppServer;
|
|
47
|
+
private attachCodexAppServerListeners;
|
|
48
|
+
reloadProfile(profile?: ProfileName): Promise<void>;
|
|
49
|
+
private stopCodexAppServerForReload;
|
|
50
|
+
private shutdownConversation;
|
|
51
|
+
private stopLarkConsumer;
|
|
52
|
+
private stopCodexPool;
|
|
53
|
+
private closeDatabase;
|
|
54
|
+
private releaseLock;
|
|
55
|
+
private stopIdleSleepPreventer;
|
|
56
|
+
private provisionLarkAssetImageKeys;
|
|
57
|
+
private startHeartbeat;
|
|
58
|
+
private stopHeartbeat;
|
|
59
|
+
private captureHeartbeat;
|
|
60
|
+
private readRuntimeCodexVersion;
|
|
61
|
+
private shutdownTelemetry;
|
|
62
|
+
}
|
|
63
|
+
export declare function createRuntime(config: TwinnyConfig, options?: TwinnyRuntimeOptions): Promise<TwinnyRuntime>;
|
|
64
|
+
export declare function adaptConversationRepository(repository: ConversationRepository): {
|
|
65
|
+
findByConversationKey: (conversationKey: string) => import("../types.js").ConversationRecord | null;
|
|
66
|
+
create: (input: import("../types.js").NewConversationRecord) => import("../types.js").ConversationRecord;
|
|
67
|
+
updateThreadBinding: (conversationKey: string, update: import("../store/repositories.js").UpdateConversationThreadBinding) => import("../types.js").ConversationRecord;
|
|
68
|
+
updateConversationSettings: (conversationKey: string, update: import("../store/repositories.js").UpdateConversationSettingsInput) => import("../types.js").ConversationRecord;
|
|
69
|
+
markThreadHasRollout: (conversationKey: string, codexThreadId: string) => void;
|
|
70
|
+
getCodexThreadById: (codexThreadId: string) => import("../types.js").CodexThreadRecord | undefined;
|
|
71
|
+
getCodexThreadByConversationAndLarkThread: (conversationKey: string, larkThreadId: string) => import("../types.js").CodexThreadRecord | undefined;
|
|
72
|
+
getLarkMessageById: (larkMessageId: string) => import("../types.js").LarkMessageRecord | undefined;
|
|
73
|
+
getLarkMessageByEventId: (eventId: string) => import("../types.js").LarkMessageRecord | undefined;
|
|
74
|
+
getLarkMessageUsageTargetForTurn: (codexThreadId: string, codexTurnId: string) => import("../types.js").LarkMessageRecord | undefined;
|
|
75
|
+
getLatestSteeredLarkMessageForTurn: (codexThreadId: string, codexTurnId: string) => import("../types.js").LarkMessageRecord | undefined;
|
|
76
|
+
listUnfinishedLarkMessages: () => import("../types.js").LarkMessageRecord[];
|
|
77
|
+
upsertCodexThread: (input: import("../store/repositories.js").UpsertCodexThreadInput) => import("../types.js").CodexThreadRecord;
|
|
78
|
+
replaceCodexThreadForLarkThread: (conversationKey: string, larkThreadId: string, update: {
|
|
79
|
+
codexThreadId: string;
|
|
80
|
+
profile: ProfileName;
|
|
81
|
+
model?: string;
|
|
82
|
+
effort?: string;
|
|
83
|
+
codexThreadHasRollout?: boolean;
|
|
84
|
+
}) => import("../types.js").CodexThreadRecord;
|
|
85
|
+
updateCodexThreadTokenUsage: (input: import("../store/repositories.js").UpdateCodexThreadTokenUsageInput) => import("../types.js").CodexThreadRecord;
|
|
86
|
+
updateCodexThreadGoalStatus: (input: import("../store/repositories.js").UpdateCodexThreadGoalStatusInput) => import("../types.js").CodexThreadRecord;
|
|
87
|
+
clearCodexThreadGoalStatus: (codexThreadId: string) => import("../types.js").CodexThreadRecord;
|
|
88
|
+
updateCodexThreadCard: (input: import("../store/repositories.js").UpdateCodexThreadCardInput) => import("../types.js").CodexThreadRecord;
|
|
89
|
+
updateCodexThreadModelSettings: (input: import("../store/repositories.js").UpdateCodexThreadModelSettingsInput) => import("../types.js").CodexThreadRecord;
|
|
90
|
+
updateCodexThreadName: (codexThreadId: string, name: string) => import("../types.js").CodexThreadRecord | undefined;
|
|
91
|
+
updateCodexThreadMode: (conversationKey: string, codexThreadId: string, mode: CodexThreadMode) => import("../types.js").CodexThreadRecord;
|
|
92
|
+
updateCodexThreadStatus: (conversationKey: string, codexThreadId: string, status: import("../types.js").CodexThreadStatus) => import("../types.js").CodexThreadRecord;
|
|
93
|
+
getCodexThreadWorkStats: (codexThreadId: string) => import("../store/repositories.js").CodexThreadWorkStats;
|
|
94
|
+
getCodexThreadStatusStats: (codexThreadId: string) => import("../store/repositories.js").CodexThreadStatusStats;
|
|
95
|
+
getConversationStatusStats: (conversationKey: string) => import("../store/repositories.js").ConversationStatusStats;
|
|
96
|
+
insertLarkMessage: (input: import("../store/repositories.js").InsertLarkMessageInput) => import("../types.js").LarkMessageRecord;
|
|
97
|
+
markLarkMessageQueued: (larkMessageId: string) => void;
|
|
98
|
+
markLarkMessageRecalled: (larkMessageId: string) => boolean;
|
|
99
|
+
updateQueuedLarkMessage: (larkMessageId: string, update: {
|
|
100
|
+
text: string;
|
|
101
|
+
rawEventJson?: string;
|
|
102
|
+
}) => boolean;
|
|
103
|
+
updateLarkMessageSideMetadata: (larkMessageId: string, update: {
|
|
104
|
+
sideId?: number;
|
|
105
|
+
agentCardMessageId?: string;
|
|
106
|
+
}) => boolean;
|
|
107
|
+
updateLarkMessageTokenUsage: (input: import("../store/repositories.js").UpdateLarkMessageTokenUsageInput) => import("../types.js").LarkMessageRecord | undefined;
|
|
108
|
+
markLarkMessagesProcessing: (larkMessageIds: string[], update?: {
|
|
109
|
+
conversationKey?: string;
|
|
110
|
+
codexThreadId?: string;
|
|
111
|
+
codexTurnId?: string;
|
|
112
|
+
}) => void;
|
|
113
|
+
markLarkMessagesSteered: (larkMessageIds: string[], update?: {
|
|
114
|
+
conversationKey?: string;
|
|
115
|
+
codexThreadId?: string;
|
|
116
|
+
codexTurnId?: string;
|
|
117
|
+
}) => void;
|
|
118
|
+
markLarkMessagesCompleted: (larkMessageIds: string[]) => void;
|
|
119
|
+
markLarkMessagesFailed: (larkMessageIds: string[]) => void;
|
|
120
|
+
markLarkMessagesInterrupted: (larkMessageIds: string[]) => void;
|
|
121
|
+
markLarkMessagesCleared: (larkMessageIds: string[]) => void;
|
|
122
|
+
};
|