@mobvibe/cli 0.1.7 → 0.1.9

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.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,32 @@
1
+ import type { GitFileStatus } from "@mobvibe/shared";
2
+ /**
3
+ * Check if a directory is a git repository.
4
+ */
5
+ export declare function isGitRepo(cwd: string): Promise<boolean>;
6
+ /**
7
+ * Get the current git branch name.
8
+ */
9
+ export declare function getGitBranch(cwd: string): Promise<string | undefined>;
10
+ /**
11
+ * Get git status for all files in the repository.
12
+ */
13
+ export declare function getGitStatus(cwd: string): Promise<Array<{
14
+ path: string;
15
+ status: GitFileStatus;
16
+ }>>;
17
+ /**
18
+ * Aggregate file statuses into directory statuses.
19
+ * A directory gets the "highest priority" status of its children.
20
+ */
21
+ export declare function aggregateDirStatus(files: Array<{
22
+ path: string;
23
+ status: GitFileStatus;
24
+ }>): Record<string, GitFileStatus>;
25
+ /**
26
+ * Get git diff for a specific file.
27
+ */
28
+ export declare function getFileDiff(cwd: string, filePath: string): Promise<{
29
+ addedLines: number[];
30
+ modifiedLines: number[];
31
+ deletedLines: number[];
32
+ }>;
@@ -0,0 +1,2 @@
1
+ import pino from "pino";
2
+ export declare const logger: pino.Logger<never, boolean>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,59 @@
1
+ import type { Database } from "bun:sqlite";
2
+ import type { CompactionConfig } from "../config.js";
3
+ import type { WalStore } from "./wal-store.js";
4
+ export type CompactionStats = {
5
+ sessionId: string;
6
+ ackedEventsDeleted: number;
7
+ oldRevisionsDeleted: number;
8
+ durationMs: number;
9
+ };
10
+ export type CompactionResult = {
11
+ stats: CompactionStats[];
12
+ totalDurationMs: number;
13
+ skipped: string[];
14
+ };
15
+ /**
16
+ * WAL Compactor - handles cleanup and optimization of the WAL database.
17
+ *
18
+ * Operations:
19
+ * 1. Delete acked events older than retention period
20
+ * 2. Delete events from old revisions (keeps latest N revisions)
21
+ * 3. Run SQLite VACUUM to reclaim space
22
+ */
23
+ export declare class WalCompactor {
24
+ private readonly config;
25
+ private db;
26
+ private activeSessionIds;
27
+ private stmtGetAllSessions;
28
+ private stmtGetSessionRevisions;
29
+ private stmtDeleteAckedEvents;
30
+ private stmtDeleteOldRevisionEvents;
31
+ private stmtCountEvents;
32
+ private stmtLogCompaction;
33
+ constructor(_walStore: WalStore, config: CompactionConfig, db: Database);
34
+ /**
35
+ * Mark a session as actively streaming (will be skipped during compaction).
36
+ */
37
+ markSessionActive(sessionId: string): void;
38
+ /**
39
+ * Mark a session as inactive (eligible for compaction).
40
+ */
41
+ markSessionInactive(sessionId: string): void;
42
+ /**
43
+ * Check if a session should be skipped during compaction.
44
+ */
45
+ private shouldSkipSession;
46
+ /**
47
+ * Compact all sessions.
48
+ */
49
+ compactAll(options?: {
50
+ dryRun?: boolean;
51
+ }): Promise<CompactionResult>;
52
+ /**
53
+ * Compact a single session.
54
+ */
55
+ compactSession(sessionId: string, options?: {
56
+ dryRun?: boolean;
57
+ }): Promise<CompactionStats>;
58
+ private logCompaction;
59
+ }
@@ -0,0 +1,6 @@
1
+ export type { CompactionResult, CompactionStats, } from "./compactor.js";
2
+ export { WalCompactor } from "./compactor.js";
3
+ export { runMigrations } from "./migrations.js";
4
+ export { SeqGenerator } from "./seq-generator.js";
5
+ export type { AppendEventParams, DiscoveredSession, EnsureSessionParams, QueryEventsParams, WalEvent, WalSession, } from "./wal-store.js";
6
+ export { WalStore } from "./wal-store.js";
@@ -0,0 +1,2 @@
1
+ import type { Database } from "bun:sqlite";
2
+ export declare function runMigrations(db: Database): void;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Sequence generator for monotonically increasing sequence numbers
3
+ * per session/revision combination.
4
+ */
5
+ export declare class SeqGenerator {
6
+ private sequences;
7
+ private buildKey;
8
+ /**
9
+ * Initialize the sequence for a session/revision from the last known value.
10
+ */
11
+ initialize(sessionId: string, revision: number, lastSeq: number): void;
12
+ /**
13
+ * Get the next sequence number for a session/revision.
14
+ */
15
+ next(sessionId: string, revision: number): number;
16
+ /**
17
+ * Get the current (last assigned) sequence number for a session/revision.
18
+ * Returns 0 if no sequence has been assigned.
19
+ */
20
+ current(sessionId: string, revision: number): number;
21
+ /**
22
+ * Reset the sequence for a session/revision (used when revision changes).
23
+ */
24
+ reset(sessionId: string, revision: number): void;
25
+ /**
26
+ * Clear all sequences for a session (used when session is closed).
27
+ */
28
+ clearSession(sessionId: string): void;
29
+ }
@@ -0,0 +1,150 @@
1
+ import type { SessionEventKind } from "@mobvibe/shared";
2
+ export type WalSession = {
3
+ sessionId: string;
4
+ machineId: string;
5
+ backendId: string;
6
+ currentRevision: number;
7
+ cwd?: string;
8
+ title?: string;
9
+ createdAt: string;
10
+ updatedAt: string;
11
+ };
12
+ export type WalEvent = {
13
+ id: number;
14
+ sessionId: string;
15
+ revision: number;
16
+ seq: number;
17
+ kind: SessionEventKind;
18
+ payload: unknown;
19
+ createdAt: string;
20
+ ackedAt?: string;
21
+ };
22
+ export type AppendEventParams = {
23
+ sessionId: string;
24
+ revision: number;
25
+ kind: SessionEventKind;
26
+ payload: unknown;
27
+ };
28
+ export type QueryEventsParams = {
29
+ sessionId: string;
30
+ revision: number;
31
+ afterSeq?: number;
32
+ limit?: number;
33
+ };
34
+ export type EnsureSessionParams = {
35
+ sessionId: string;
36
+ machineId: string;
37
+ backendId: string;
38
+ cwd?: string;
39
+ title?: string;
40
+ };
41
+ export type DiscoveredSession = {
42
+ sessionId: string;
43
+ backendId: string;
44
+ cwd?: string;
45
+ title?: string;
46
+ agentUpdatedAt?: string;
47
+ discoveredAt: string;
48
+ lastVerifiedAt?: string;
49
+ isStale: boolean;
50
+ };
51
+ export declare class WalStore {
52
+ private db;
53
+ private seqGenerator;
54
+ private stmtGetSession;
55
+ private stmtInsertSession;
56
+ private stmtUpdateSession;
57
+ private stmtInsertEvent;
58
+ private stmtQueryEvents;
59
+ private stmtQueryUnackedEvents;
60
+ private stmtAckEvents;
61
+ private stmtIncrementRevision;
62
+ private stmtGetMaxSeq;
63
+ private stmtUpsertDiscoveredSession;
64
+ private stmtGetDiscoveredSessions;
65
+ private stmtGetDiscoveredSessionsByBackend;
66
+ private stmtMarkDiscoveredSessionStale;
67
+ private stmtDeleteStaleDiscoveredSessions;
68
+ private stmtDeleteSessionEvents;
69
+ private stmtDeleteSession;
70
+ private stmtInsertArchivedSession;
71
+ private stmtIsArchived;
72
+ private stmtGetArchivedSessionIds;
73
+ constructor(dbPath: string);
74
+ /**
75
+ * Ensure a session exists in the WAL store.
76
+ * Creates if not exists, updates metadata if exists.
77
+ */
78
+ ensureSession(params: EnsureSessionParams): {
79
+ revision: number;
80
+ };
81
+ /**
82
+ * Get a session by ID.
83
+ */
84
+ getSession(sessionId: string): WalSession | null;
85
+ /**
86
+ * Append an event to the WAL.
87
+ */
88
+ appendEvent(params: AppendEventParams): WalEvent;
89
+ /**
90
+ * Query events for a session/revision after a given sequence.
91
+ */
92
+ queryEvents(params: QueryEventsParams): WalEvent[];
93
+ /**
94
+ * Get all unacked events for a session/revision.
95
+ */
96
+ getUnackedEvents(sessionId: string, revision: number): WalEvent[];
97
+ /**
98
+ * Mark events as acknowledged up to a given sequence.
99
+ */
100
+ ackEvents(sessionId: string, revision: number, upToSeq: number): void;
101
+ /**
102
+ * Increment the revision for a session (used when session is reloaded).
103
+ */
104
+ incrementRevision(sessionId: string): number;
105
+ /**
106
+ * Get the current sequence number for a session/revision.
107
+ */
108
+ getCurrentSeq(sessionId: string, revision: number): number;
109
+ /**
110
+ * Save discovered sessions (upsert).
111
+ * Marks sessions as non-stale and updates verification time.
112
+ */
113
+ saveDiscoveredSessions(sessions: DiscoveredSession[]): void;
114
+ /**
115
+ * Get all non-stale discovered sessions.
116
+ */
117
+ getDiscoveredSessions(backendId?: string): DiscoveredSession[];
118
+ /**
119
+ * Mark a discovered session as stale (cwd no longer exists).
120
+ */
121
+ markDiscoveredSessionStale(sessionId: string): void;
122
+ /**
123
+ * Delete stale discovered sessions older than a given date.
124
+ */
125
+ deleteStaleDiscoveredSessions(olderThan: Date): number;
126
+ /**
127
+ * Archive a session: delete WAL events, delete session record, mark as archived.
128
+ */
129
+ archiveSession(sessionId: string): void;
130
+ /**
131
+ * Archive multiple sessions. Returns the number archived.
132
+ */
133
+ bulkArchiveSessions(sessionIds: string[]): number;
134
+ /**
135
+ * Check if a session ID is archived.
136
+ */
137
+ isArchived(sessionId: string): boolean;
138
+ /**
139
+ * Get all archived session IDs.
140
+ */
141
+ getArchivedSessionIds(): string[];
142
+ /**
143
+ * Close the database connection.
144
+ */
145
+ close(): void;
146
+ private getMaxSeq;
147
+ private rowToSession;
148
+ private rowToEvent;
149
+ private rowToDiscoveredSession;
150
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mobvibe/cli",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "CLI daemon for remote-claude (mobvibe) - connects ACP agents to the gateway",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -16,7 +16,7 @@
16
16
  "cli"
17
17
  ],
18
18
  "engines": {
19
- "node": ">=22"
19
+ "bun": ">=1.0.0"
20
20
  },
21
21
  "publishConfig": {
22
22
  "access": "public"
@@ -36,13 +36,16 @@
36
36
  }
37
37
  },
38
38
  "scripts": {
39
- "dev": "tsx watch src/index.ts",
40
- "build": "tsup",
41
- "start": "node dist/index.js",
39
+ "dev": "bun run build.ts",
40
+ "build": "bun run build.ts",
41
+ "build:bin": "bun run build-bin.ts",
42
+ "start": "bun dist/index.js",
42
43
  "lint": "biome check --write .",
44
+ "lint:check": "biome check .",
43
45
  "format": "biome format --write .",
44
- "test": "vitest --passWithNoTests",
45
- "test:run": "vitest run --passWithNoTests",
46
+ "format:check": "biome format .",
47
+ "test": "bun test",
48
+ "test:run": "bun test",
46
49
  "prepublishOnly": "pnpm build"
47
50
  },
48
51
  "dependencies": {
@@ -52,15 +55,14 @@
52
55
  "open": "^10.1.0",
53
56
  "pino": "^9.6.0",
54
57
  "pino-pretty": "^13.1.1",
58
+ "qrcode": "^1.5.4",
55
59
  "socket.io-client": "^4.8.1"
56
60
  },
57
61
  "devDependencies": {
58
62
  "@biomejs/biome": "2.3.11",
59
63
  "@mobvibe/shared": "workspace:*",
60
- "@types/node": "^24.10.1",
61
- "tsup": "^8.5.0",
62
- "tsx": "^4.19.3",
63
- "typescript": "~5.9.3",
64
- "vitest": "^2.1.8"
64
+ "@types/bun": "latest",
65
+ "@types/qrcode": "^1.5.5",
66
+ "typescript": "~5.9.3"
65
67
  }
66
68
  }