@foxden-app/foxclaw 0.12.0 → 0.13.0

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 (124) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/antigravity/account_ui.d.ts +34 -0
  3. package/dist/antigravity/account_ui.js +354 -0
  4. package/dist/antigravity/adapter.js +1 -1
  5. package/dist/antigravity/auth.d.ts +4 -1
  6. package/dist/antigravity/auth.js +17 -5
  7. package/dist/antigravity/controller.d.ts +3 -108
  8. package/dist/antigravity/controller.js +2 -2129
  9. package/dist/antigravity/conversation_ui.d.ts +56 -0
  10. package/dist/antigravity/conversation_ui.js +509 -0
  11. package/dist/antigravity/ui_callbacks.d.ts +6 -0
  12. package/dist/antigravity/ui_callbacks.js +6 -0
  13. package/dist/bridge/unified_bridge.d.ts +114 -0
  14. package/dist/bridge/unified_bridge.js +1343 -0
  15. package/dist/channels/bridge_messaging_router.d.ts +8 -4
  16. package/dist/channels/bridge_messaging_router.js +15 -4
  17. package/dist/channels/telegram/telegram_messaging_port.d.ts +16 -0
  18. package/dist/channels/telegram/telegram_messaging_port.js +22 -2
  19. package/dist/channels/text_actions.d.ts +14 -0
  20. package/dist/channels/text_actions.js +48 -0
  21. package/dist/channels/weixin/weixin_channel_adapter.d.ts +3 -4
  22. package/dist/channels/weixin/weixin_channel_adapter.js +2 -2
  23. package/dist/channels/weixin/weixin_messaging_port.d.ts +16 -1
  24. package/dist/channels/weixin/weixin_messaging_port.js +34 -7
  25. package/dist/codex_app/activity.d.ts +62 -0
  26. package/dist/codex_app/activity.js +418 -0
  27. package/dist/codex_app/adapter.d.ts +2 -2
  28. package/dist/codex_app/adapter.js +55 -25
  29. package/dist/codex_app/backend_ui.d.ts +4 -0
  30. package/dist/codex_app/backend_ui.js +48 -0
  31. package/dist/codex_app/client.js +0 -12
  32. package/dist/controller/access.d.ts +1 -11
  33. package/dist/controller/access.js +1 -33
  34. package/dist/controller/activity.d.ts +1 -62
  35. package/dist/controller/activity.js +2 -418
  36. package/dist/controller/auth_errors.d.ts +11 -0
  37. package/dist/controller/auth_errors.js +124 -0
  38. package/dist/controller/auth_files.d.ts +13 -0
  39. package/dist/controller/auth_files.js +156 -0
  40. package/dist/controller/auth_presentation.d.ts +77 -0
  41. package/dist/controller/auth_presentation.js +697 -0
  42. package/dist/controller/auth_quota_service.d.ts +27 -0
  43. package/dist/controller/auth_quota_service.js +151 -0
  44. package/dist/controller/controller.d.ts +30 -56
  45. package/dist/controller/controller.js +181 -3497
  46. package/dist/controller/interactions.d.ts +74 -0
  47. package/dist/controller/interactions.js +560 -0
  48. package/dist/controller/local_usage_service.d.ts +19 -0
  49. package/dist/controller/local_usage_service.js +62 -0
  50. package/dist/controller/native_panel_service.d.ts +55 -0
  51. package/dist/controller/native_panel_service.js +214 -0
  52. package/dist/controller/native_panels.d.ts +61 -0
  53. package/dist/controller/native_panels.js +784 -0
  54. package/dist/controller/shared_helpers.d.ts +53 -0
  55. package/dist/controller/shared_helpers.js +399 -0
  56. package/dist/controller/state_types.d.ts +390 -0
  57. package/dist/controller/state_types.js +82 -0
  58. package/dist/controller/turn_rendering.d.ts +22 -0
  59. package/dist/controller/turn_rendering.js +288 -0
  60. package/dist/core/access.d.ts +11 -0
  61. package/dist/core/access.js +33 -0
  62. package/dist/core/attachment_files.d.ts +13 -0
  63. package/dist/core/attachment_files.js +180 -0
  64. package/dist/core/attachment_types.d.ts +22 -0
  65. package/dist/core/attachment_types.js +1 -0
  66. package/dist/core/attachments.d.ts +5 -3
  67. package/dist/core/attachments.js +2 -2
  68. package/dist/core/backend_registry.d.ts +22 -0
  69. package/dist/core/backend_registry.js +50 -0
  70. package/dist/core/backend_ui.d.ts +28 -0
  71. package/dist/core/backend_ui.js +1 -0
  72. package/dist/core/channel_events.d.ts +48 -0
  73. package/dist/core/channel_events.js +1 -0
  74. package/dist/core/channel_port.d.ts +52 -8
  75. package/dist/core/engine_spi.d.ts +19 -4
  76. package/dist/core/listener_scope.d.ts +11 -0
  77. package/dist/core/listener_scope.js +10 -0
  78. package/dist/core/message_text.d.ts +2 -0
  79. package/dist/core/message_text.js +28 -0
  80. package/dist/core/network_errors.d.ts +1 -0
  81. package/dist/core/network_errors.js +23 -0
  82. package/dist/core/orchestrator.d.ts +53 -24
  83. package/dist/core/orchestrator.js +855 -507
  84. package/dist/core/queued_engine_input.d.ts +12 -0
  85. package/dist/core/queued_engine_input.js +16 -0
  86. package/dist/core/runtime_supervisor.d.ts +19 -0
  87. package/dist/core/runtime_supervisor.js +45 -0
  88. package/dist/core/scope_operations.d.ts +7 -0
  89. package/dist/core/scope_operations.js +19 -0
  90. package/dist/core/stream_preview.js +21 -9
  91. package/dist/dsh/adapter.js +18 -5
  92. package/dist/dsh/backend.d.ts +7 -0
  93. package/dist/dsh/backend.js +21 -0
  94. package/dist/dsh/runtime.d.ts +0 -1
  95. package/dist/dsh/runtime.js +4 -13
  96. package/dist/dsh/ui.d.ts +8 -8
  97. package/dist/dsh/ui.js +1 -1
  98. package/dist/main.js +55 -43
  99. package/dist/opencode/adapter.js +28 -9
  100. package/dist/opencode/controller.js +1 -1
  101. package/dist/store/channel_inbox.d.ts +14 -0
  102. package/dist/store/channel_inbox.js +21 -0
  103. package/dist/store/database.d.ts +7 -3
  104. package/dist/store/database.js +7 -2
  105. package/dist/store/task_journal.d.ts +32 -0
  106. package/dist/store/task_journal.js +70 -0
  107. package/dist/telegram/api.d.ts +2 -2
  108. package/dist/telegram/api.js +10 -28
  109. package/dist/telegram/gateway.d.ts +13 -27
  110. package/dist/telegram/gateway.js +86 -43
  111. package/dist/telegram/media.d.ts +2 -34
  112. package/dist/telegram/media.js +1 -180
  113. package/dist/telegram/task_preview.d.ts +13 -0
  114. package/dist/telegram/task_preview.js +92 -0
  115. package/dist/telegram/task_result.d.ts +2 -0
  116. package/dist/telegram/task_result.js +12 -0
  117. package/dist/telegram/text.d.ts +1 -1
  118. package/dist/telegram/text.js +2 -27
  119. package/dist/types.d.ts +1 -1
  120. package/docs/release.md +13 -11
  121. package/docs/zh/architecture-review.md +106 -0
  122. package/docs/zh/release.md +13 -11
  123. package/docs/zh/telegram-experience.md +40 -0
  124. package/package.json +5 -4
@@ -0,0 +1,156 @@
1
+ import path from 'node:path';
2
+ import os from 'node:os';
3
+ import fs from 'node:fs/promises';
4
+ import { isFileMissingError } from './shared_helpers.js';
5
+ export function codexAuthDir(explicitAuthDir = null) {
6
+ return explicitAuthDir || process.env.CODEX_AUTH_DIR || path.join(os.homedir(), '.codex');
7
+ }
8
+ export async function listCodexAuthState(disabledNames = new Set(), candidateStates = new Map(), explicitAuthDir = null) {
9
+ const authDir = codexAuthDir(explicitAuthDir);
10
+ const authPath = path.join(authDir, 'auth.json');
11
+ const currentTargetPath = await resolveCurrentAuthTarget(authDir, authPath);
12
+ const candidates = [];
13
+ const entries = await fs.readdir(authDir, { withFileTypes: true }).catch((error) => {
14
+ if (isFileMissingError(error)) {
15
+ return [];
16
+ }
17
+ throw error;
18
+ });
19
+ for (const entry of entries) {
20
+ if (!isCodexAuthCandidateName(entry.name)) {
21
+ continue;
22
+ }
23
+ const candidatePath = path.join(authDir, entry.name);
24
+ const stat = await fs.stat(candidatePath).catch(() => null);
25
+ if (!stat?.isFile()) {
26
+ continue;
27
+ }
28
+ candidates.push({
29
+ name: entry.name,
30
+ path: candidatePath,
31
+ isCurrent: currentTargetPath === candidatePath,
32
+ disabled: disabledNames.has(entry.name),
33
+ state: candidateStates.get(entry.name) ?? 'active',
34
+ mtimeMs: stat.mtimeMs,
35
+ credentialKind: 'invalid',
36
+ credentialLastRefreshMs: null,
37
+ credentialExpiresAtMs: null,
38
+ quota: null,
39
+ });
40
+ }
41
+ candidates.sort((left, right) => left.name.localeCompare(right.name, undefined, { numeric: true }));
42
+ return {
43
+ authDir,
44
+ authPath,
45
+ currentTargetPath,
46
+ currentLabel: currentTargetPath ? await authPathDisplayLabel(currentTargetPath) : null,
47
+ candidates,
48
+ };
49
+ }
50
+ export function isCodexAuthCandidateName(name) {
51
+ if (name === 'auth.json' || name.startsWith('.auth.json.')) {
52
+ return false;
53
+ }
54
+ return name.startsWith('auth.json_') || name.startsWith('auth.json.') || name.startsWith('auth.json-');
55
+ }
56
+ export async function isCodexApiKeyAuthCandidate(candidatePath) {
57
+ try {
58
+ const parsed = JSON.parse(await fs.readFile(candidatePath, 'utf8'));
59
+ return typeof parsed.openai_api_key === 'string' && parsed.openai_api_key.trim().length > 0;
60
+ }
61
+ catch {
62
+ return false;
63
+ }
64
+ }
65
+ export function codexAuthCandidateNameFromAddName(raw) {
66
+ const normalized = raw.trim();
67
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(normalized)) {
68
+ return null;
69
+ }
70
+ const name = normalized.startsWith('auth.json_')
71
+ || normalized.startsWith('auth.json.')
72
+ || normalized.startsWith('auth.json-')
73
+ ? normalized
74
+ : `auth.json_${normalized}`;
75
+ return isCodexAuthCandidateName(name) ? name : null;
76
+ }
77
+ export async function resolveCurrentAuthTarget(authDir, authPath) {
78
+ const stat = await fs.lstat(authPath).catch(() => null);
79
+ if (!stat) {
80
+ return null;
81
+ }
82
+ if (stat.isSymbolicLink()) {
83
+ const target = await fs.readlink(authPath);
84
+ return path.resolve(authDir, target);
85
+ }
86
+ return authPath;
87
+ }
88
+ export async function resolveAuthFinalTargetPath(startPath) {
89
+ let currentPath = startPath;
90
+ const seen = new Set();
91
+ for (let depth = 0; depth < 20; depth += 1) {
92
+ const absolutePath = path.resolve(currentPath);
93
+ if (seen.has(absolutePath)) {
94
+ return currentPath;
95
+ }
96
+ seen.add(absolutePath);
97
+ const stat = await fs.lstat(currentPath).catch(() => null);
98
+ if (!stat?.isSymbolicLink()) {
99
+ return currentPath;
100
+ }
101
+ const target = await fs.readlink(currentPath);
102
+ currentPath = path.resolve(path.dirname(currentPath), target);
103
+ }
104
+ return currentPath;
105
+ }
106
+ export async function authPathDisplayLabel(authPath) {
107
+ return path.basename(await resolveAuthFinalTargetPath(authPath));
108
+ }
109
+ export async function pointCodexAuthAtTarget(authDir, authPath, targetPath) {
110
+ await fs.mkdir(authDir, { recursive: true });
111
+ const tempLink = path.join(authDir, `.auth.json.${process.pid}.${Date.now()}.tmp`);
112
+ try {
113
+ await fs.symlink(targetPath, tempLink);
114
+ await fs.rename(tempLink, authPath);
115
+ }
116
+ catch (error) {
117
+ await fs.unlink(tempLink).catch(() => { });
118
+ throw error;
119
+ }
120
+ }
121
+ export async function restoreCodexAuthTarget(authDir, authPath, targetPath, regularAuthContents) {
122
+ if (regularAuthContents !== null) {
123
+ await fs.mkdir(authDir, { recursive: true });
124
+ const temporary = path.join(authDir, `.auth.json.${process.pid}.${Date.now()}.restore`);
125
+ try {
126
+ await fs.writeFile(temporary, regularAuthContents, { mode: 0o600 });
127
+ await fs.rename(temporary, authPath);
128
+ }
129
+ catch (error) {
130
+ await fs.unlink(temporary).catch(() => undefined);
131
+ throw error;
132
+ }
133
+ return;
134
+ }
135
+ if (targetPath) {
136
+ await pointCodexAuthAtTarget(authDir, authPath, targetPath);
137
+ return;
138
+ }
139
+ await fs.unlink(authPath).catch((error) => {
140
+ if (!isFileMissingError(error)) {
141
+ throw error;
142
+ }
143
+ });
144
+ }
145
+ export async function switchCodexAuth(targetPath, explicitAuthDir = null) {
146
+ const state = await listCodexAuthState(new Set(), new Map(), explicitAuthDir);
147
+ const candidate = state.candidates.find(entry => entry.path === targetPath);
148
+ if (!candidate) {
149
+ throw new Error(`Auth candidate is no longer available: ${path.basename(targetPath)}`);
150
+ }
151
+ await pointCodexAuthAtTarget(state.authDir, state.authPath, candidate.path);
152
+ return {
153
+ fromLabel: state.currentLabel,
154
+ toLabel: await authPathDisplayLabel(candidate.path),
155
+ };
156
+ }
@@ -0,0 +1,77 @@
1
+ import type { AppLocale, CodexAccountInfo, CodexAccountRateLimits, CodexRateLimitSnapshot, CodexRateLimitWindow, RuntimeStatus } from '../types.js';
2
+ import type { CodexAuthQuotaSnapshotRecord } from '../store/database.js';
3
+ import { type ChatGptAuthMetadata } from '../auth/mirror.js';
4
+ import { CodexAuthListView, CodexAuthCandidate, PendingAuthChoiceList, CodexAuthListFilter, CodexAuthState, CodexAuthCandidateHealth, CodexAuthRefreshAllResult, CodexAuthClusterAuditOutcome, AuthProactiveRefreshStatus, AuthSyncRuntimeEvent, CodexAuthQuotaSnapshot } from './state_types.js';
5
+ export declare function parseCodexAuthListRequest(action: string, args: string[]): Partial<CodexAuthListView> | null;
6
+ export declare function createPendingAuthChoiceList(chatId: string, candidates: CodexAuthCandidate[], view?: Partial<CodexAuthListView>): PendingAuthChoiceList;
7
+ export declare function clampCodexAuthListOffset(view: PendingAuthChoiceList): void;
8
+ export declare function codexAuthListPage(candidates: CodexAuthCandidate[], view: CodexAuthListView | null): {
9
+ visible: Array<{
10
+ candidate: CodexAuthCandidate;
11
+ index: number;
12
+ }>;
13
+ filteredCount: number;
14
+ offset: number;
15
+ pageIndex: number;
16
+ pageCount: number;
17
+ filter: CodexAuthListFilter;
18
+ searchTerm: string | null;
19
+ };
20
+ export declare function filterCodexAuthCandidates(candidates: CodexAuthCandidate[], view: Pick<CodexAuthListView, 'filter' | 'searchTerm'>): Array<{
21
+ candidate: CodexAuthCandidate;
22
+ index: number;
23
+ }>;
24
+ export declare function renderAuthListMessage(locale: AppLocale, state: CodexAuthState, botLabel?: string | null, includeWeixinCopyPaste?: boolean, view?: CodexAuthListView | null): string;
25
+ export declare function authChoiceKeyboard(locale: AppLocale, record: PendingAuthChoiceList): Array<Array<{
26
+ text: string;
27
+ callback_data: string;
28
+ }>>;
29
+ export declare function formatCodexAuthCandidateDisplayName(name: string): string;
30
+ export declare function authFilterButton(locale: AppLocale, record: PendingAuthChoiceList, filter: CodexAuthListFilter): {
31
+ text: string;
32
+ callback_data: string;
33
+ };
34
+ export declare function codexAuthCandidateHealth(candidate: CodexAuthCandidate): CodexAuthCandidateHealth;
35
+ export declare function codexAuthCandidateNeedsAttention(candidate: CodexAuthCandidate): boolean;
36
+ export declare function formatCodexAuthCandidateStatus(locale: AppLocale, candidate: CodexAuthCandidate): string;
37
+ export declare function formatCodexAuthFilter(locale: AppLocale, filter: CodexAuthListFilter): string;
38
+ export declare function authRefreshAllConfirmKeyboard(locale: AppLocale, record: PendingAuthChoiceList): Array<Array<{
39
+ text: string;
40
+ callback_data: string;
41
+ }>>;
42
+ export declare function authRepairKeyboard(locale: AppLocale, record: PendingAuthChoiceList, index: number): Array<Array<{
43
+ text: string;
44
+ callback_data: string;
45
+ }>>;
46
+ export declare function formatAuthRefreshAllResult(locale: AppLocale, result: CodexAuthRefreshAllResult, mode?: 'manual' | 'proactive'): string;
47
+ export declare function formatAuthClusterAuditResult(locale: AppLocale, outcome: CodexAuthClusterAuditOutcome): string;
48
+ export declare function formatAuthSyncStatus(locale: AppLocale, status: RuntimeStatus['authSync'], proactiveRefresh?: AuthProactiveRefreshStatus | null): string;
49
+ export declare function formatAuthProactiveRefreshStatus(locale: AppLocale, status: AuthProactiveRefreshStatus): string;
50
+ export declare function formatAuthProactiveRefreshState(locale: AppLocale, state: AuthProactiveRefreshStatus['state']): string;
51
+ export declare function formatLimitedList(values: readonly string[], limit: number): string;
52
+ export declare function formatAuthSyncEvents(locale: AppLocale, status: RuntimeStatus['authSync'], filter: string | null): string;
53
+ export declare function formatAuthSyncTrace(locale: AppLocale, status: RuntimeStatus['authSync'], requestId: string): string;
54
+ export declare function filterAuthSyncEvents(events: AuthSyncRuntimeEvent[], filter: string | null): AuthSyncRuntimeEvent[];
55
+ export declare function formatAuthSyncEventLine(event: AuthSyncRuntimeEvent): string;
56
+ export declare function selectCodexRateLimitSnapshot(limits: CodexAccountRateLimits | null): CodexRateLimitSnapshot | null;
57
+ export declare function formatCodexAccountLabel(account: CodexAccountInfo): string;
58
+ export declare function formatPlanTypeLabel(value: string): string;
59
+ export declare function formatRateLimitWindowLabel(locale: AppLocale, window: CodexRateLimitWindow, fallback: 'primary' | 'secondary'): string;
60
+ export declare function formatCompactRateLimitWindowLabel(locale: AppLocale, minutes: number | null, fallback: 'primary' | 'secondary'): string;
61
+ export declare function formatCompactAge(locale: AppLocale, ageMs: number): string;
62
+ export declare function formatUtcDateTime(timestampMs: number): string;
63
+ export declare function formatUsagePercent(value: number): string;
64
+ export declare function formatRemainingUsagePercent(usedPercent: number): string;
65
+ export declare function authQuotaSnapshotFromRateLimit(snapshot: CodexRateLimitSnapshot, accountId?: string | null, quotaIdentityId?: string | null): CodexAuthQuotaSnapshot;
66
+ export declare function codexAuthQuotaSnapshotFromRecord(record: CodexAuthQuotaSnapshotRecord): CodexAuthQuotaSnapshot;
67
+ export declare function mergeCodexAuthQuotaSnapshots(current: CodexAuthQuotaSnapshot | null, incoming: CodexAuthQuotaSnapshot | null): CodexAuthQuotaSnapshot | null;
68
+ export declare function isFiniteCodexAuthQuotaSnapshotRecord(record: CodexAuthQuotaSnapshotRecord): boolean;
69
+ export declare function remainingUsagePercent(usedPercent: number): number | null;
70
+ export declare function formatAuthQuotaPrefix(locale: AppLocale, snapshot: CodexAuthQuotaSnapshot | null): string;
71
+ export declare function formatAuthQuotaButtonPrefix(snapshot: CodexAuthQuotaSnapshot | null): string;
72
+ export declare function formatAuthQuotaButtonValue(value: number | null): string;
73
+ export declare function isCodexAuthQuotaSnapshot(value: unknown): value is CodexAuthQuotaSnapshot;
74
+ export declare function normalizeCodexAuthQuotaSnapshot(snapshot: CodexAuthQuotaSnapshot): CodexAuthQuotaSnapshot;
75
+ export declare function chatGptAuthMetadataCompatible(left: Pick<ChatGptAuthMetadata, 'accountId' | 'quotaIdentityId'>, right: Pick<ChatGptAuthMetadata, 'accountId' | 'quotaIdentityId'>): boolean;
76
+ export declare function isNullableFiniteNumber(value: unknown): value is number | null;
77
+ export declare function isNullableString(value: unknown): value is string | null;