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.
Files changed (191) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +264 -0
  3. package/README.zh-CN.md +252 -0
  4. package/configs/banner.png +0 -0
  5. package/configs/logo.png +0 -0
  6. package/dist/app/caffeinate.d.ts +28 -0
  7. package/dist/app/caffeinate.js +96 -0
  8. package/dist/app/caffeinate.js.map +1 -0
  9. package/dist/app/daemon.d.ts +1 -0
  10. package/dist/app/daemon.js +44 -0
  11. package/dist/app/daemon.js.map +1 -0
  12. package/dist/app/lark-assets.d.ts +25 -0
  13. package/dist/app/lark-assets.js +108 -0
  14. package/dist/app/lark-assets.js.map +1 -0
  15. package/dist/app/startup-probe.d.ts +17 -0
  16. package/dist/app/startup-probe.js +90 -0
  17. package/dist/app/startup-probe.js.map +1 -0
  18. package/dist/app/wiring.d.ts +122 -0
  19. package/dist/app/wiring.js +694 -0
  20. package/dist/app/wiring.js.map +1 -0
  21. package/dist/cli/commands.d.ts +1 -0
  22. package/dist/cli/commands.js +47 -0
  23. package/dist/cli/commands.js.map +1 -0
  24. package/dist/cli/install-wizard.d.ts +41 -0
  25. package/dist/cli/install-wizard.js +629 -0
  26. package/dist/cli/install-wizard.js.map +1 -0
  27. package/dist/codex/appserver.d.ts +109 -0
  28. package/dist/codex/appserver.js +308 -0
  29. package/dist/codex/appserver.js.map +1 -0
  30. package/dist/codex/goal.d.ts +64 -0
  31. package/dist/codex/goal.js +433 -0
  32. package/dist/codex/goal.js.map +1 -0
  33. package/dist/codex/index.d.ts +6 -0
  34. package/dist/codex/index.js +7 -0
  35. package/dist/codex/index.js.map +1 -0
  36. package/dist/codex/protocol.d.ts +95 -0
  37. package/dist/codex/protocol.js +205 -0
  38. package/dist/codex/protocol.js.map +1 -0
  39. package/dist/codex/thread-name.d.ts +3 -0
  40. package/dist/codex/thread-name.js +27 -0
  41. package/dist/codex/thread-name.js.map +1 -0
  42. package/dist/codex/thread.d.ts +76 -0
  43. package/dist/codex/thread.js +80 -0
  44. package/dist/codex/thread.js.map +1 -0
  45. package/dist/codex/turn.d.ts +166 -0
  46. package/dist/codex/turn.js +746 -0
  47. package/dist/codex/turn.js.map +1 -0
  48. package/dist/config/bootstrap.d.ts +14 -0
  49. package/dist/config/bootstrap.js +56 -0
  50. package/dist/config/bootstrap.js.map +1 -0
  51. package/dist/config/index.d.ts +4 -0
  52. package/dist/config/index.js +5 -0
  53. package/dist/config/index.js.map +1 -0
  54. package/dist/config/loader.d.ts +49 -0
  55. package/dist/config/loader.js +467 -0
  56. package/dist/config/loader.js.map +1 -0
  57. package/dist/config/paths.d.ts +11 -0
  58. package/dist/config/paths.js +43 -0
  59. package/dist/config/paths.js.map +1 -0
  60. package/dist/config/secrets.d.ts +33 -0
  61. package/dist/config/secrets.js +85 -0
  62. package/dist/config/secrets.js.map +1 -0
  63. package/dist/conversation/manager.d.ts +701 -0
  64. package/dist/conversation/manager.js +7673 -0
  65. package/dist/conversation/manager.js.map +1 -0
  66. package/dist/conversation/queue.d.ts +8 -0
  67. package/dist/conversation/queue.js +28 -0
  68. package/dist/conversation/queue.js.map +1 -0
  69. package/dist/conversation/routing.d.ts +11 -0
  70. package/dist/conversation/routing.js +55 -0
  71. package/dist/conversation/routing.js.map +1 -0
  72. package/dist/errors.d.ts +6 -0
  73. package/dist/errors.js +17 -0
  74. package/dist/errors.js.map +1 -0
  75. package/dist/index.d.ts +3 -0
  76. package/dist/index.js +4 -0
  77. package/dist/index.js.map +1 -0
  78. package/dist/lark/auth.d.ts +41 -0
  79. package/dist/lark/auth.js +132 -0
  80. package/dist/lark/auth.js.map +1 -0
  81. package/dist/lark/browser-auth.d.ts +68 -0
  82. package/dist/lark/browser-auth.js +258 -0
  83. package/dist/lark/browser-auth.js.map +1 -0
  84. package/dist/lark/cards.d.ts +140 -0
  85. package/dist/lark/cards.js +1150 -0
  86. package/dist/lark/cards.js.map +1 -0
  87. package/dist/lark/contact.d.ts +41 -0
  88. package/dist/lark/contact.js +122 -0
  89. package/dist/lark/contact.js.map +1 -0
  90. package/dist/lark/events.d.ts +65 -0
  91. package/dist/lark/events.js +218 -0
  92. package/dist/lark/events.js.map +1 -0
  93. package/dist/lark/files.d.ts +36 -0
  94. package/dist/lark/files.js +191 -0
  95. package/dist/lark/files.js.map +1 -0
  96. package/dist/lark/filters.d.ts +73 -0
  97. package/dist/lark/filters.js +678 -0
  98. package/dist/lark/filters.js.map +1 -0
  99. package/dist/lark/index.d.ts +10 -0
  100. package/dist/lark/index.js +11 -0
  101. package/dist/lark/index.js.map +1 -0
  102. package/dist/lark/messages.d.ts +87 -0
  103. package/dist/lark/messages.js +428 -0
  104. package/dist/lark/messages.js.map +1 -0
  105. package/dist/lark/openapi.d.ts +58 -0
  106. package/dist/lark/openapi.js +206 -0
  107. package/dist/lark/openapi.js.map +1 -0
  108. package/dist/lark/redactor.d.ts +5 -0
  109. package/dist/lark/redactor.js +68 -0
  110. package/dist/lark/redactor.js.map +1 -0
  111. package/dist/lark/types.d.ts +49 -0
  112. package/dist/lark/types.js +18 -0
  113. package/dist/lark/types.js.map +1 -0
  114. package/dist/launchd/install.d.ts +22 -0
  115. package/dist/launchd/install.js +114 -0
  116. package/dist/launchd/install.js.map +1 -0
  117. package/dist/launchd/plist.d.ts +10 -0
  118. package/dist/launchd/plist.js +61 -0
  119. package/dist/launchd/plist.js.map +1 -0
  120. package/dist/lock/index.d.ts +20 -0
  121. package/dist/lock/index.js +74 -0
  122. package/dist/lock/index.js.map +1 -0
  123. package/dist/main.d.ts +2 -0
  124. package/dist/main.js +11 -0
  125. package/dist/main.js.map +1 -0
  126. package/dist/markdown.d.ts +12 -0
  127. package/dist/markdown.js +149 -0
  128. package/dist/markdown.js.map +1 -0
  129. package/dist/observability/health.d.ts +25 -0
  130. package/dist/observability/health.js +187 -0
  131. package/dist/observability/health.js.map +1 -0
  132. package/dist/observability/logs.d.ts +10 -0
  133. package/dist/observability/logs.js +34 -0
  134. package/dist/observability/logs.js.map +1 -0
  135. package/dist/observability/system-notifications.d.ts +25 -0
  136. package/dist/observability/system-notifications.js +33 -0
  137. package/dist/observability/system-notifications.js.map +1 -0
  138. package/dist/profiles/guest.d.ts +19 -0
  139. package/dist/profiles/guest.js +241 -0
  140. package/dist/profiles/guest.js.map +1 -0
  141. package/dist/profiles/index.d.ts +5 -0
  142. package/dist/profiles/index.js +14 -0
  143. package/dist/profiles/index.js.map +1 -0
  144. package/dist/profiles/owner.d.ts +1 -0
  145. package/dist/profiles/owner.js +6 -0
  146. package/dist/profiles/owner.js.map +1 -0
  147. package/dist/store/db.d.ts +10 -0
  148. package/dist/store/db.js +29 -0
  149. package/dist/store/db.js.map +1 -0
  150. package/dist/store/index.d.ts +3 -0
  151. package/dist/store/index.js +4 -0
  152. package/dist/store/index.js.map +1 -0
  153. package/dist/store/migrations.d.ts +13 -0
  154. package/dist/store/migrations.js +79 -0
  155. package/dist/store/migrations.js.map +1 -0
  156. package/dist/store/repositories.d.ts +227 -0
  157. package/dist/store/repositories.js +1384 -0
  158. package/dist/store/repositories.js.map +1 -0
  159. package/dist/telemetry/client.d.ts +60 -0
  160. package/dist/telemetry/client.js +204 -0
  161. package/dist/telemetry/client.js.map +1 -0
  162. package/dist/telemetry/hash.d.ts +1 -0
  163. package/dist/telemetry/hash.js +8 -0
  164. package/dist/telemetry/hash.js.map +1 -0
  165. package/dist/telemetry/index.d.ts +4 -0
  166. package/dist/telemetry/index.js +5 -0
  167. package/dist/telemetry/index.js.map +1 -0
  168. package/dist/telemetry/posthog.d.ts +27 -0
  169. package/dist/telemetry/posthog.js +45 -0
  170. package/dist/telemetry/posthog.js.map +1 -0
  171. package/dist/telemetry/reporter.d.ts +13 -0
  172. package/dist/telemetry/reporter.js +29 -0
  173. package/dist/telemetry/reporter.js.map +1 -0
  174. package/dist/types.d.ts +330 -0
  175. package/dist/types.js +9 -0
  176. package/dist/types.js.map +1 -0
  177. package/dist/version.d.ts +1 -0
  178. package/dist/version.js +1 -0
  179. package/dist/version.js.map +1 -0
  180. package/dist/version.json +3 -0
  181. package/dist/workspace/index.d.ts +2 -0
  182. package/dist/workspace/index.js +3 -0
  183. package/dist/workspace/index.js.map +1 -0
  184. package/dist/workspace/manager.d.ts +14 -0
  185. package/dist/workspace/manager.js +69 -0
  186. package/dist/workspace/manager.js.map +1 -0
  187. package/dist/workspace/slug.d.ts +8 -0
  188. package/dist/workspace/slug.js +59 -0
  189. package/dist/workspace/slug.js.map +1 -0
  190. package/migrations/0001_initial.sql +102 -0
  191. package/package.json +85 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plist.js","sourceRoot":"","sources":["../../src/launchd/plist.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { CheckOptions, LockOptions } from "proper-lockfile";
2
+ import type { RuntimePaths } from "../types.js";
3
+ export interface TwinnyLockMetadata {
4
+ pid: number;
5
+ acquiredAt: number;
6
+ }
7
+ export interface TwinnyRuntimeLock {
8
+ lockFile: string;
9
+ metadata: TwinnyLockMetadata;
10
+ release: () => Promise<void>;
11
+ }
12
+ export interface AcquireTwinnyLockOptions extends Pick<LockOptions, "stale" | "update" | "retries" | "onCompromised"> {
13
+ }
14
+ export interface CheckTwinnyLockOptions extends Pick<CheckOptions, "stale"> {
15
+ }
16
+ export declare function getTwinnyLockFile(twinnyHome: string): string;
17
+ export declare function acquireTwinnyLock(target: string | Pick<RuntimePaths, "lockFile">, options?: AcquireTwinnyLockOptions): Promise<TwinnyRuntimeLock>;
18
+ export declare function isTwinnyLockHeld(target: string | Pick<RuntimePaths, "lockFile">, options?: CheckTwinnyLockOptions): Promise<boolean>;
19
+ export declare function readTwinnyLockMetadata(target: string | Pick<RuntimePaths, "lockFile">, options?: CheckTwinnyLockOptions): Promise<TwinnyLockMetadata | undefined>;
20
+ export declare function readTwinnyLockPid(target: string | Pick<RuntimePaths, "lockFile">, options?: CheckTwinnyLockOptions): Promise<number | undefined>;
@@ -0,0 +1,74 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import * as properLockfile from "proper-lockfile";
4
+ export function getTwinnyLockFile(twinnyHome) {
5
+ return path.join(twinnyHome, "runtime", "twinny.lock");
6
+ }
7
+ export async function acquireTwinnyLock(target, options = {}) {
8
+ const lockFile = resolveLockFile(target);
9
+ await fs.mkdir(path.dirname(lockFile), { recursive: true });
10
+ await fs.appendFile(lockFile, "");
11
+ const releaseProperLock = await properLockfile.lock(lockFile, {
12
+ ...options,
13
+ realpath: false
14
+ });
15
+ const metadata = { pid: process.pid, acquiredAt: Date.now() };
16
+ let released = false;
17
+ await fs.writeFile(lockFile, `${JSON.stringify(metadata)}\n`, "utf8");
18
+ return {
19
+ lockFile,
20
+ metadata,
21
+ release: async () => {
22
+ if (released) {
23
+ return;
24
+ }
25
+ released = true;
26
+ await fs.writeFile(lockFile, "", "utf8");
27
+ await releaseProperLock();
28
+ }
29
+ };
30
+ }
31
+ export async function isTwinnyLockHeld(target, options = {}) {
32
+ const lockFile = resolveLockFile(target);
33
+ try {
34
+ return await properLockfile.check(lockFile, {
35
+ ...options,
36
+ realpath: false
37
+ });
38
+ }
39
+ catch (error) {
40
+ if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
41
+ return false;
42
+ }
43
+ throw error;
44
+ }
45
+ }
46
+ export async function readTwinnyLockMetadata(target, options = {}) {
47
+ const lockFile = resolveLockFile(target);
48
+ const held = await isTwinnyLockHeld({ lockFile }, options);
49
+ if (!held) {
50
+ return undefined;
51
+ }
52
+ const raw = await fs.readFile(lockFile, "utf8");
53
+ if (raw.trim() === "") {
54
+ return undefined;
55
+ }
56
+ const parsed = JSON.parse(raw);
57
+ if (typeof parsed.pid !== "number" || typeof parsed.acquiredAt !== "number") {
58
+ return undefined;
59
+ }
60
+ return {
61
+ pid: parsed.pid,
62
+ acquiredAt: parsed.acquiredAt
63
+ };
64
+ }
65
+ export async function readTwinnyLockPid(target, options = {}) {
66
+ return (await readTwinnyLockMetadata(target, options))?.pid;
67
+ }
68
+ function resolveLockFile(target) {
69
+ if (typeof target === "string") {
70
+ return getTwinnyLockFile(target);
71
+ }
72
+ return target.lockFile;
73
+ }
74
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lock/index.ts"],"names":[],"mappings":"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"}
package/dist/main.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/main.js ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from "./cli/commands.js";
3
+ import { toErrorMessage } from "./errors.js";
4
+ try {
5
+ await runCli(process.argv);
6
+ }
7
+ catch (error) {
8
+ console.error(toErrorMessage(error));
9
+ process.exitCode = 1;
10
+ }
11
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,IAAI,CAAC;IACH,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;IACrC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC"}
@@ -0,0 +1,12 @@
1
+ export interface TextRange {
2
+ start: number;
3
+ end: number;
4
+ }
5
+ export interface MarkdownLine {
6
+ text: string;
7
+ start: number;
8
+ end: number;
9
+ }
10
+ export declare function markdownLines(markdown: string): MarkdownLine[];
11
+ export declare function markdownCodeRanges(markdown: string): TextRange[];
12
+ export declare function isPositionInTextRanges(position: number, ranges: TextRange[]): boolean;
@@ -0,0 +1,149 @@
1
+ export function markdownLines(markdown) {
2
+ const lines = [];
3
+ const lineEndPattern = /\r?\n/g;
4
+ let cursor = 0;
5
+ for (const match of markdown.matchAll(lineEndPattern)) {
6
+ const index = match.index ?? 0;
7
+ const lineEnd = index + match[0].length;
8
+ lines.push({ text: markdown.slice(cursor, index), start: cursor, end: lineEnd });
9
+ cursor = lineEnd;
10
+ }
11
+ if (cursor < markdown.length) {
12
+ lines.push({ text: markdown.slice(cursor), start: cursor, end: markdown.length });
13
+ }
14
+ return lines;
15
+ }
16
+ export function markdownCodeRanges(markdown) {
17
+ const blockRanges = markdownCodeBlockRanges(markdown);
18
+ const inlineRanges = markdownInlineCodeRanges(markdown, blockRanges);
19
+ return mergeTextRanges([...blockRanges, ...inlineRanges]);
20
+ }
21
+ export function isPositionInTextRanges(position, ranges) {
22
+ for (const range of ranges) {
23
+ if (position < range.start) {
24
+ return false;
25
+ }
26
+ if (position < range.end) {
27
+ return true;
28
+ }
29
+ }
30
+ return false;
31
+ }
32
+ function markdownCodeBlockRanges(markdown) {
33
+ const ranges = [];
34
+ let fence;
35
+ for (const line of markdownLines(markdown)) {
36
+ if (fence) {
37
+ if (isClosingFence(line.text, fence)) {
38
+ ranges.push({ start: fence.start, end: line.end });
39
+ fence = undefined;
40
+ }
41
+ continue;
42
+ }
43
+ const openingFence = openingMarkdownFence(line.text);
44
+ if (openingFence) {
45
+ fence = { ...openingFence, start: line.start };
46
+ continue;
47
+ }
48
+ if (isIndentedCodeLine(line.text)) {
49
+ ranges.push({ start: line.start, end: line.end });
50
+ }
51
+ }
52
+ if (fence) {
53
+ ranges.push({ start: fence.start, end: markdown.length });
54
+ }
55
+ return mergeTextRanges(ranges);
56
+ }
57
+ function markdownInlineCodeRanges(markdown, blockRanges) {
58
+ const ranges = [];
59
+ let index = 0;
60
+ while (index < markdown.length) {
61
+ const blockRange = rangeContainingOrAfter(index, blockRanges);
62
+ if (blockRange && index >= blockRange.start) {
63
+ index = blockRange.end;
64
+ continue;
65
+ }
66
+ if (markdown[index] !== "`") {
67
+ index += 1;
68
+ continue;
69
+ }
70
+ const length = countBackticks(markdown, index);
71
+ const close = findClosingBacktickRun(markdown, index + length, length, blockRanges);
72
+ if (close === -1) {
73
+ index += length;
74
+ continue;
75
+ }
76
+ const end = close + length;
77
+ ranges.push({ start: index, end });
78
+ index = end;
79
+ }
80
+ return ranges;
81
+ }
82
+ function openingMarkdownFence(line) {
83
+ const match = /^ {0,3}(`{3,}|~{3,})/.exec(line);
84
+ if (!match) {
85
+ return undefined;
86
+ }
87
+ const sequence = match[1];
88
+ return {
89
+ char: sequence[0],
90
+ length: sequence.length
91
+ };
92
+ }
93
+ function isClosingFence(line, fence) {
94
+ const match = /^ {0,3}(`+|~+)[ \t]*$/.exec(line);
95
+ if (!match) {
96
+ return false;
97
+ }
98
+ const sequence = match[1];
99
+ return sequence[0] === fence.char && sequence.length >= fence.length;
100
+ }
101
+ function isIndentedCodeLine(line) {
102
+ return line.trim().length > 0 && /^(?: {4,}|\t)/.test(line);
103
+ }
104
+ function findClosingBacktickRun(markdown, start, length, blockRanges) {
105
+ let index = start;
106
+ while (index < markdown.length) {
107
+ const blockRange = rangeContainingOrAfter(index, blockRanges);
108
+ if (blockRange && index >= blockRange.start) {
109
+ index = blockRange.end;
110
+ continue;
111
+ }
112
+ if (markdown[index] !== "`") {
113
+ index += 1;
114
+ continue;
115
+ }
116
+ const runLength = countBackticks(markdown, index);
117
+ if (runLength === length) {
118
+ return index;
119
+ }
120
+ index += runLength;
121
+ }
122
+ return -1;
123
+ }
124
+ function countBackticks(markdown, start) {
125
+ let index = start;
126
+ while (markdown[index] === "`") {
127
+ index += 1;
128
+ }
129
+ return index - start;
130
+ }
131
+ function rangeContainingOrAfter(position, ranges) {
132
+ return ranges.find((range) => position < range.end);
133
+ }
134
+ function mergeTextRanges(ranges) {
135
+ const sorted = ranges
136
+ .filter((range) => range.end > range.start)
137
+ .sort((left, right) => left.start - right.start || left.end - right.end);
138
+ const merged = [];
139
+ for (const range of sorted) {
140
+ const previous = merged.at(-1);
141
+ if (previous && range.start <= previous.end) {
142
+ previous.end = Math.max(previous.end, range.end);
143
+ continue;
144
+ }
145
+ merged.push({ ...range });
146
+ }
147
+ return merged;
148
+ }
149
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import fs from "node:fs/promises";
2
+ import { type SecretStore } from "../config/index.js";
3
+ import { LarkBotDirectory, LarkOpenApiClient, TenantAccessTokenManager } from "../lark/index.js";
4
+ import type { HealthSnapshot, TwinnyConfig } from "../types.js";
5
+ export declare function runDoctorCommand(): Promise<void>;
6
+ export declare function runDoctorChecks(): Promise<HealthSnapshot>;
7
+ export declare function checkCaffeinateBinary(options?: {
8
+ command?: string;
9
+ platform?: NodeJS.Platform;
10
+ access?: typeof fs.access;
11
+ }): Promise<string>;
12
+ export declare function checkLarkBotOpenId(config: Pick<TwinnyConfig, "auth">, appSecret: string, options?: {
13
+ tokenManager?: TenantAccessTokenManager;
14
+ openApiClient?: LarkOpenApiClient;
15
+ botDirectory?: Pick<LarkBotDirectory, "getBotOpenId">;
16
+ }): Promise<string>;
17
+ export declare function checkLarkRequiredScopes(config: Pick<TwinnyConfig, "auth">, appSecret: string, options?: {
18
+ tokenManager?: TenantAccessTokenManager;
19
+ openApiClient?: Pick<LarkOpenApiClient, "request">;
20
+ requiredScopes?: readonly string[];
21
+ }): Promise<string>;
22
+ export declare function resolveDoctorLarkAppSecret(account: string, secretStore: SecretStore): Promise<{
23
+ value: string;
24
+ detail: "present";
25
+ }>;
@@ -0,0 +1,187 @@
1
+ import { constants as fsConstants } from "node:fs";
2
+ import fs from "node:fs/promises";
3
+ import { execa } from "execa";
4
+ import { DEFAULT_CAFFEINATE_COMMAND } from "../app/caffeinate.js";
5
+ import { formatStartupInitializationProbeDetail, runStartupInitializationProbe } from "../app/startup-probe.js";
6
+ import { readConfigStatus, resolveLarkAppSecret, SecurityCliSecretStore } from "../config/index.js";
7
+ import { LARK_REQUIRED_SCOPES, LarkBotDirectory, LarkOpenApiClient, resolveLarkEndpoints, TenantAccessTokenManager } from "../lark/index.js";
8
+ import { isTwinnyLockHeld, readTwinnyLockMetadata } from "../lock/index.js";
9
+ import { openRuntimeDatabase } from "../store/index.js";
10
+ import { toErrorMessage } from "../errors.js";
11
+ export async function runDoctorCommand() {
12
+ const snapshot = await runDoctorChecks();
13
+ for (const check of snapshot.checks) {
14
+ const marker = check.ok ? "OK" : "FAIL";
15
+ console.log(`${marker} ${check.name}${check.detail ? ` - ${check.detail}` : ""}`);
16
+ }
17
+ if (!snapshot.ok) {
18
+ process.exitCode = 1;
19
+ }
20
+ }
21
+ export async function runDoctorChecks() {
22
+ const checks = [];
23
+ const configStatus = await readConfigStatus();
24
+ checks.push({
25
+ name: "config",
26
+ ok: configStatus.complete,
27
+ detail: configStatus.complete ? configStatus.paths.configFile : configStatus.issues.join("; ")
28
+ });
29
+ if (!configStatus.config) {
30
+ return { ok: false, checks };
31
+ }
32
+ const config = configStatus.config;
33
+ const secretStore = new SecurityCliSecretStore();
34
+ let appSecret;
35
+ await checkAsync(checks, "lark app_secret", async () => {
36
+ const secret = await resolveDoctorLarkAppSecret(config.homeIdentity.keychainAccounts.larkAppSecret, secretStore);
37
+ appSecret = secret.value;
38
+ return secret.detail;
39
+ });
40
+ await checkAsync(checks, "codex binary", async () => {
41
+ const result = await execa(config.codex.binary, ["--version"], { reject: false });
42
+ if (result.exitCode !== 0) {
43
+ throw new Error(result.stderr || `exit ${result.exitCode}`);
44
+ }
45
+ return result.stdout.trim();
46
+ });
47
+ await checkAsync(checks, "caffeinate binary", async () => {
48
+ return checkCaffeinateBinary();
49
+ });
50
+ await checkAsync(checks, "sqlite", async () => {
51
+ const db = openRuntimeDatabase(configStatus.paths);
52
+ db.close();
53
+ return configStatus.paths.sqliteFile;
54
+ });
55
+ await checkAsync(checks, "startup initialization", async () => {
56
+ return formatStartupInitializationProbeDetail(await runStartupInitializationProbe({
57
+ config,
58
+ paths: configStatus.paths
59
+ }));
60
+ });
61
+ await checkAsync(checks, "singleton lock", async () => {
62
+ const held = await isTwinnyLockHeld(configStatus.paths);
63
+ if (!held) {
64
+ return "not running";
65
+ }
66
+ const metadata = await readTwinnyLockMetadata(configStatus.paths);
67
+ return metadata ? `held by pid ${metadata.pid}` : "held";
68
+ });
69
+ const resolvedAppSecret = appSecret;
70
+ if (resolvedAppSecret) {
71
+ await checkAsync(checks, "lark tenant token", async () => {
72
+ const manager = new TenantAccessTokenManager({
73
+ appId: config.auth.larkAppId,
74
+ appSecret: resolvedAppSecret,
75
+ baseUrl: resolveLarkEndpoints(config.auth.larkBrand).openApi
76
+ });
77
+ await manager.getTenantAccessToken();
78
+ return "reachable";
79
+ });
80
+ await checkAsync(checks, "lark bot open_id", async () => {
81
+ return checkLarkBotOpenId(config, resolvedAppSecret);
82
+ });
83
+ await checkAsync(checks, "lark required scopes", async () => {
84
+ return checkLarkRequiredScopes(config, resolvedAppSecret);
85
+ });
86
+ }
87
+ return {
88
+ ok: checks.every((check) => check.ok),
89
+ checks
90
+ };
91
+ }
92
+ export async function checkCaffeinateBinary(options = {}) {
93
+ const platform = options.platform ?? process.platform;
94
+ if (platform !== "darwin") {
95
+ return `not required on ${platform}`;
96
+ }
97
+ const command = options.command ?? DEFAULT_CAFFEINATE_COMMAND;
98
+ await (options.access ?? fs.access)(command, fsConstants.X_OK);
99
+ return command;
100
+ }
101
+ export async function checkLarkBotOpenId(config, appSecret, options = {}) {
102
+ const botDirectory = options.botDirectory ?? (() => {
103
+ const tokenManager = options.tokenManager ?? new TenantAccessTokenManager({
104
+ appId: config.auth.larkAppId,
105
+ appSecret,
106
+ baseUrl: resolveLarkEndpoints(config.auth.larkBrand).openApi
107
+ });
108
+ const openApiClient = options.openApiClient ?? new LarkOpenApiClient({
109
+ tokenManager,
110
+ baseUrl: resolveLarkEndpoints(config.auth.larkBrand).openApi
111
+ });
112
+ return new LarkBotDirectory({ openApiClient });
113
+ })();
114
+ const botOpenId = await botDirectory.getBotOpenId();
115
+ if (!botOpenId) {
116
+ throw new Error("missing bot open_id");
117
+ }
118
+ return botOpenId;
119
+ }
120
+ export async function checkLarkRequiredScopes(config, appSecret, options = {}) {
121
+ const openApiClient = options.openApiClient ?? (() => {
122
+ const tokenManager = options.tokenManager ?? new TenantAccessTokenManager({
123
+ appId: config.auth.larkAppId,
124
+ appSecret,
125
+ baseUrl: resolveLarkEndpoints(config.auth.larkBrand).openApi
126
+ });
127
+ return new LarkOpenApiClient({
128
+ tokenManager,
129
+ baseUrl: resolveLarkEndpoints(config.auth.larkBrand).openApi
130
+ });
131
+ })();
132
+ const requiredScopes = options.requiredScopes ?? LARK_REQUIRED_SCOPES;
133
+ const grantedScopes = await getGrantedLarkScopes(openApiClient);
134
+ const missingScopes = requiredScopes.filter((scope) => !grantedScopes.has(scope));
135
+ if (missingScopes.length > 0) {
136
+ throw new Error(`missing: ${missingScopes.join(", ")}`);
137
+ }
138
+ return `${requiredScopes.length} required scopes granted`;
139
+ }
140
+ export async function resolveDoctorLarkAppSecret(account, secretStore) {
141
+ const value = await resolveLarkAppSecret(account, secretStore);
142
+ if (!value) {
143
+ throw new Error(`missing keychain:${account}`);
144
+ }
145
+ return {
146
+ value,
147
+ detail: "present"
148
+ };
149
+ }
150
+ async function checkAsync(checks, name, run) {
151
+ try {
152
+ const result = await run();
153
+ checks.push({
154
+ name,
155
+ ok: true,
156
+ detail: typeof result === "string" ? result : undefined
157
+ });
158
+ return result;
159
+ }
160
+ catch (error) {
161
+ checks.push({
162
+ name,
163
+ ok: false,
164
+ detail: toErrorMessage(error)
165
+ });
166
+ return undefined;
167
+ }
168
+ }
169
+ async function getGrantedLarkScopes(openApiClient) {
170
+ const raw = await openApiClient.request("/application/v6/scopes", { method: "GET" });
171
+ const scopes = asRecord(asRecord(raw).data).scopes;
172
+ if (!Array.isArray(scopes)) {
173
+ throw new Error("invalid Lark scope response");
174
+ }
175
+ const granted = new Set();
176
+ for (const item of scopes) {
177
+ const scope = asRecord(item);
178
+ if (typeof scope.scope_name === "string" && scope.grant_status === 1) {
179
+ granted.add(scope.scope_name);
180
+ }
181
+ }
182
+ return granted;
183
+ }
184
+ function asRecord(value) {
185
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
186
+ }
187
+ //# sourceMappingURL=health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/observability/health.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import pino, { type Logger } from "pino";
2
+ import type { LarkSdkLogger } from "../lark/types.js";
3
+ export interface LoggerOptions {
4
+ level?: string;
5
+ logFile?: string;
6
+ pretty?: boolean;
7
+ }
8
+ export declare function createLogger(options?: LoggerOptions): Logger;
9
+ export declare function createLarkSdkLogger(logger: Pick<Logger, "trace" | "debug" | "info" | "warn" | "error">): LarkSdkLogger;
10
+ export declare const logger: pino.Logger;
@@ -0,0 +1,34 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import pino from "pino";
4
+ export function createLogger(options = {}) {
5
+ const level = options.level ?? process.env.TWINNY_LOG_LEVEL ?? "info";
6
+ if (options.logFile) {
7
+ fs.mkdirSync(path.dirname(options.logFile), { recursive: true });
8
+ return pino({ level }, pino.destination({ dest: options.logFile, sync: false }));
9
+ }
10
+ if (options.pretty ?? process.stdout.isTTY) {
11
+ return pino({
12
+ level,
13
+ transport: {
14
+ target: "pino-pretty",
15
+ options: { colorize: true, translateTime: "SYS:standard" }
16
+ }
17
+ });
18
+ }
19
+ return pino({ level });
20
+ }
21
+ export function createLarkSdkLogger(logger) {
22
+ return {
23
+ trace: (...args) => logger.trace({ args: normalizeExternalLoggerArgs(args) }, "lark sdk trace"),
24
+ debug: (...args) => logger.debug({ args: normalizeExternalLoggerArgs(args) }, "lark sdk debug"),
25
+ info: (...args) => logger.info({ args: normalizeExternalLoggerArgs(args) }, "lark sdk info"),
26
+ warn: (...args) => logger.warn({ args: normalizeExternalLoggerArgs(args) }, "lark sdk warn"),
27
+ error: (...args) => logger.error({ args: normalizeExternalLoggerArgs(args) }, "lark sdk error")
28
+ };
29
+ }
30
+ function normalizeExternalLoggerArgs(args) {
31
+ return args.length === 1 ? args[0] : args;
32
+ }
33
+ export const logger = createLogger();
34
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/observability/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAqB,MAAM,MAAM,CAAC;AASzC,MAAM,UAAU,YAAY,CAAC,UAAyB,EAAE;IACtD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,MAAM,CAAC;IACtE,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACnF,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC;YACV,KAAK;YACL,SAAS,EAAE;gBACT,MAAM,EAAE,aAAa;gBACrB,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,cAAc,EAAE;aAC3D;SACF,CAAC,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAmE;IACrG,OAAO;QACL,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,2BAA2B,CAAC,IAAI,CAAC,EAAE,EAAE,gBAAgB,CAAC;QAC/F,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,2BAA2B,CAAC,IAAI,CAAC,EAAE,EAAE,gBAAgB,CAAC;QAC/F,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,2BAA2B,CAAC,IAAI,CAAC,EAAE,EAAE,eAAe,CAAC;QAC5F,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,2BAA2B,CAAC,IAAI,CAAC,EAAE,EAAE,eAAe,CAAC;QAC5F,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,2BAA2B,CAAC,IAAI,CAAC,EAAE,EAAE,gBAAgB,CAAC;KAChG,CAAC;AACJ,CAAC;AAED,SAAS,2BAA2B,CAAC,IAAe;IAClD,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { type LarkCardJson } from "../lark/cards.js";
2
+ import type { LarkLogger } from "../lark/index.js";
3
+ export interface SystemNotificationSender {
4
+ sendInteractiveCardToOpenId(openId: string, card: LarkCardJson, options?: {
5
+ signal?: AbortSignal;
6
+ uuid?: string;
7
+ }): Promise<unknown>;
8
+ }
9
+ export interface TwinnySystemNotifierOptions {
10
+ ownerOpenId: string;
11
+ sender: SystemNotificationSender;
12
+ logger?: LarkLogger;
13
+ timeoutMs?: number;
14
+ }
15
+ export declare class TwinnySystemNotifier {
16
+ private readonly ownerOpenId;
17
+ private readonly sender;
18
+ private readonly logger?;
19
+ private readonly timeoutMs;
20
+ constructor(options: TwinnySystemNotifierOptions);
21
+ notifyInitialized(options?: {
22
+ bannerImageKey?: string;
23
+ }): Promise<void>;
24
+ private sendCard;
25
+ }
@@ -0,0 +1,33 @@
1
+ import { toErrorMessage } from "../errors.js";
2
+ import { renderTwinnyBannerCard } from "../lark/cards.js";
3
+ import { TWINNY_VERSION } from "../version.js";
4
+ const DEFAULT_NOTIFICATION_TIMEOUT_MS = 5_000;
5
+ export class TwinnySystemNotifier {
6
+ ownerOpenId;
7
+ sender;
8
+ logger;
9
+ timeoutMs;
10
+ constructor(options) {
11
+ this.ownerOpenId = options.ownerOpenId;
12
+ this.sender = options.sender;
13
+ this.logger = options.logger;
14
+ this.timeoutMs = options.timeoutMs ?? DEFAULT_NOTIFICATION_TIMEOUT_MS;
15
+ }
16
+ async notifyInitialized(options = {}) {
17
+ await this.sendCard("initialized", renderTwinnyBannerCard({ bannerImageKey: options.bannerImageKey, twinnyVersion: TWINNY_VERSION }));
18
+ }
19
+ async sendCard(kind, card) {
20
+ const controller = new AbortController();
21
+ const timeout = setTimeout(() => controller.abort(), this.timeoutMs);
22
+ try {
23
+ await this.sender.sendInteractiveCardToOpenId(this.ownerOpenId, card, { signal: controller.signal });
24
+ }
25
+ catch (error) {
26
+ this.logger?.warn?.({ kind, error: toErrorMessage(error) }, "failed to send Twinny system notification");
27
+ }
28
+ finally {
29
+ clearTimeout(timeout);
30
+ }
31
+ }
32
+ }
33
+ //# sourceMappingURL=system-notifications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-notifications.js","sourceRoot":"","sources":["../../src/observability/system-notifications.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAqB,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,MAAM,+BAA+B,GAAG,KAAK,CAAC;AAa9C,MAAM,OAAO,oBAAoB;IACd,WAAW,CAAS;IACpB,MAAM,CAA2B;IACjC,MAAM,CAAc;IACpB,SAAS,CAAS;IAEnC,YAAY,OAAoC;QAC9C,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,+BAA+B,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,UAAuC,EAAE;QAC/D,MAAM,IAAI,CAAC,QAAQ,CACjB,aAAa,EACb,sBAAsB,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC,CAClG,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,IAAkB;QACrD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACrE,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,2BAA2B,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;QACvG,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,EAAE,2CAA2C,CAAC,CAAC;QAC3G,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;CACF"}