@foxden-app/foxclaw 0.5.15 → 0.5.17
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/CHANGELOG.md +18 -0
- package/dist/controller/controller.js +4 -1
- package/dist/main.js +4 -1
- package/dist/store/database.d.ts +4 -1
- package/dist/store/database.js +11 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
All notable FoxClaw changes are listed here. Each release note is bilingual so GitHub Releases and the npm package are useful to both Chinese and English readers.
|
|
4
4
|
|
|
5
|
+
## 0.5.17 - 2026-06-08
|
|
6
|
+
|
|
7
|
+
### 中文
|
|
8
|
+
- `foxclaw <subcommand> --help` / `-h` 现在只打印帮助,不再继续执行 `install-systemd`、`start`、`restart` 等带副作用的子命令,避免一次查帮助意外触发服务重启。
|
|
9
|
+
|
|
10
|
+
### English
|
|
11
|
+
- `foxclaw <subcommand> --help` / `-h` now prints usage and stops before running side-effecting subcommands such as `install-systemd`, `start`, or `restart`, preventing an accidental service restart while checking help.
|
|
12
|
+
|
|
13
|
+
## 0.5.16 - 2026-06-08
|
|
14
|
+
|
|
15
|
+
### 中文
|
|
16
|
+
- FoxClaw 重启后会把仍在运行的桥接自有 Codex turn 恢复为可继续操作的活动态,状态卡继续刷新,后续 Telegram 输入会继续 steer 或按聊天设置排队,不再退化成需要用户重新发消息的只读观察态。
|
|
17
|
+
- `/watch` 产生的观察态 turn 会在状态卡中持久化只读标记,重启恢复后仍保持只读,避免把旁观线程误恢复成可操作任务。
|
|
18
|
+
|
|
19
|
+
### English
|
|
20
|
+
- After a FoxClaw restart, bridge-owned live Codex turns are restored as actionable active turns: their status cards keep updating, and later Telegram messages keep steering or queueing according to the chat setting instead of degrading into read-only watch mode.
|
|
21
|
+
- `/watch`-created observed turns now persist their read-only marker, so restart recovery keeps watched threads read-only and does not accidentally promote them into actionable tasks.
|
|
22
|
+
|
|
5
23
|
## 0.5.15 - 2026-06-08
|
|
6
24
|
|
|
7
25
|
### 中文
|
|
@@ -2862,6 +2862,7 @@ export class BridgeSessionCore {
|
|
|
2862
2862
|
scopeId,
|
|
2863
2863
|
threadId,
|
|
2864
2864
|
messageId: previewMessageId,
|
|
2865
|
+
isObserved: active.isObserved,
|
|
2865
2866
|
});
|
|
2866
2867
|
}
|
|
2867
2868
|
this.updateStatus();
|
|
@@ -6946,7 +6947,7 @@ export class BridgeSessionCore {
|
|
|
6946
6947
|
return this.interruptOrphanWaitingUserInput(preview);
|
|
6947
6948
|
}
|
|
6948
6949
|
await this.stopWatchingScopeThread(preview.scopeId, preview.threadId);
|
|
6949
|
-
const active = this.createActiveTurnState(preview.scopeId, target.chatId, target.chatType, target.topicId, preview.threadId, preview.turnId, preview.messageId,
|
|
6950
|
+
const active = this.createActiveTurnState(preview.scopeId, target.chatId, target.chatType, target.topicId, preview.threadId, preview.turnId, preview.messageId, preview.isObserved);
|
|
6950
6951
|
this.setActiveTurn(preview.scopeId, preview.turnId, active);
|
|
6951
6952
|
const watcher = {
|
|
6952
6953
|
scopeId: preview.scopeId,
|
|
@@ -6973,6 +6974,7 @@ export class BridgeSessionCore {
|
|
|
6973
6974
|
scopeId: preview.scopeId,
|
|
6974
6975
|
threadId: preview.threadId,
|
|
6975
6976
|
turnId: preview.turnId,
|
|
6977
|
+
isObserved: preview.isObserved,
|
|
6976
6978
|
});
|
|
6977
6979
|
return true;
|
|
6978
6980
|
}
|
|
@@ -7153,6 +7155,7 @@ export class BridgeSessionCore {
|
|
|
7153
7155
|
scopeId: active.scopeId,
|
|
7154
7156
|
threadId: active.threadId,
|
|
7155
7157
|
messageId,
|
|
7158
|
+
isObserved: active.isObserved,
|
|
7156
7159
|
});
|
|
7157
7160
|
}
|
|
7158
7161
|
catch (error) {
|
package/dist/main.js
CHANGED
|
@@ -66,7 +66,7 @@ async function main() {
|
|
|
66
66
|
console.log(readPackageVersion());
|
|
67
67
|
return;
|
|
68
68
|
}
|
|
69
|
-
if (isHelpCommand(command)) {
|
|
69
|
+
if (isHelpCommand(command) || hasHelpFlag()) {
|
|
70
70
|
printUsage();
|
|
71
71
|
return;
|
|
72
72
|
}
|
|
@@ -149,6 +149,9 @@ function isVersionCommand(value) {
|
|
|
149
149
|
function isHelpCommand(value) {
|
|
150
150
|
return value === 'help' || value === '--help' || value === '-h';
|
|
151
151
|
}
|
|
152
|
+
function hasHelpFlag() {
|
|
153
|
+
return process.argv.slice(3).some(isHelpCommand);
|
|
154
|
+
}
|
|
152
155
|
function readPackageVersion() {
|
|
153
156
|
try {
|
|
154
157
|
const pkg = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'));
|
package/dist/store/database.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export interface ActiveTurnPreviewRecord {
|
|
|
4
4
|
scopeId: string;
|
|
5
5
|
threadId: string;
|
|
6
6
|
messageId: number;
|
|
7
|
+
isObserved: boolean;
|
|
7
8
|
createdAt: number;
|
|
8
9
|
updatedAt: number;
|
|
9
10
|
}
|
|
@@ -74,7 +75,9 @@ export declare class BridgeStore {
|
|
|
74
75
|
getPendingApprovalByServerRequestId(serverRequestId: string): PendingApprovalRecord | null;
|
|
75
76
|
markApprovalResolved(localId: string): void;
|
|
76
77
|
countPendingApprovals(): number;
|
|
77
|
-
saveActiveTurnPreview(record: Pick<ActiveTurnPreviewRecord, 'turnId' | 'scopeId' | 'threadId' | 'messageId'>
|
|
78
|
+
saveActiveTurnPreview(record: Pick<ActiveTurnPreviewRecord, 'turnId' | 'scopeId' | 'threadId' | 'messageId'> & {
|
|
79
|
+
isObserved?: boolean;
|
|
80
|
+
}): void;
|
|
78
81
|
listActiveTurnPreviews(): ActiveTurnPreviewRecord[];
|
|
79
82
|
removeActiveTurnPreview(turnId: string): void;
|
|
80
83
|
removeActiveTurnPreviewByMessage(scopeId: string, messageId: number): void;
|
package/dist/store/database.js
CHANGED
|
@@ -70,6 +70,7 @@ export class BridgeStore {
|
|
|
70
70
|
scope_id TEXT NOT NULL,
|
|
71
71
|
thread_id TEXT NOT NULL,
|
|
72
72
|
message_id INTEGER NOT NULL,
|
|
73
|
+
is_observed INTEGER NOT NULL DEFAULT 0,
|
|
73
74
|
created_at INTEGER NOT NULL,
|
|
74
75
|
updated_at INTEGER NOT NULL
|
|
75
76
|
);
|
|
@@ -209,6 +210,7 @@ export class BridgeStore {
|
|
|
209
210
|
this.ensureColumn('pending_approvals', 'payload_json', 'TEXT');
|
|
210
211
|
this.ensureColumn('pending_user_inputs', 'status', "TEXT NOT NULL DEFAULT 'pending'");
|
|
211
212
|
this.ensureColumn('pending_user_inputs', 'submitted_at', 'INTEGER');
|
|
213
|
+
this.ensureColumn('active_turn_previews', 'is_observed', 'INTEGER NOT NULL DEFAULT 0');
|
|
212
214
|
this.ensureColumn('codex_auth_candidates', 'state', "TEXT NOT NULL DEFAULT 'active'");
|
|
213
215
|
this.ensureColumn('codex_auth_candidate_runtime', 'state', "TEXT NOT NULL DEFAULT 'active'");
|
|
214
216
|
this.ensureColumn('codex_auth_quota_snapshots', 'plan_type', 'TEXT');
|
|
@@ -414,22 +416,23 @@ export class BridgeStore {
|
|
|
414
416
|
saveActiveTurnPreview(record) {
|
|
415
417
|
const now = Date.now();
|
|
416
418
|
this.db.prepare('DELETE FROM active_turn_previews WHERE turn_id = ? OR scope_id = ?').run(record.turnId, record.scopeId);
|
|
417
|
-
this.db.prepare(`
|
|
418
|
-
INSERT INTO active_turn_previews (turn_id, scope_id, thread_id, message_id, created_at, updated_at)
|
|
419
|
-
VALUES (?, ?, ?, ?, ?, ?)
|
|
420
|
-
`).run(record.turnId, record.scopeId, record.threadId, record.messageId, now, now);
|
|
419
|
+
this.db.prepare(`
|
|
420
|
+
INSERT INTO active_turn_previews (turn_id, scope_id, thread_id, message_id, is_observed, created_at, updated_at)
|
|
421
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
422
|
+
`).run(record.turnId, record.scopeId, record.threadId, record.messageId, record.isObserved ? 1 : 0, now, now);
|
|
421
423
|
}
|
|
422
424
|
listActiveTurnPreviews() {
|
|
423
|
-
const rows = this.db.prepare(`
|
|
424
|
-
SELECT turn_id, scope_id, thread_id, message_id, created_at, updated_at
|
|
425
|
-
FROM active_turn_previews
|
|
426
|
-
ORDER BY created_at ASC
|
|
425
|
+
const rows = this.db.prepare(`
|
|
426
|
+
SELECT turn_id, scope_id, thread_id, message_id, is_observed, created_at, updated_at
|
|
427
|
+
FROM active_turn_previews
|
|
428
|
+
ORDER BY created_at ASC
|
|
427
429
|
`).all();
|
|
428
430
|
return rows.map((row) => ({
|
|
429
431
|
turnId: String(row.turn_id),
|
|
430
432
|
scopeId: String(row.scope_id),
|
|
431
433
|
threadId: String(row.thread_id),
|
|
432
434
|
messageId: Number(row.message_id),
|
|
435
|
+
isObserved: Boolean(row.is_observed),
|
|
433
436
|
createdAt: Number(row.created_at),
|
|
434
437
|
updatedAt: Number(row.updated_at),
|
|
435
438
|
}));
|