lark-remote 0.1.3 → 0.1.5
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 +86 -0
- package/README.en.md +4 -1
- package/README.md +4 -1
- package/dist/bridge/index.d.ts +5 -1
- package/dist/bridge/index.js +25 -1
- package/dist/card/run-renderer.js +1 -1
- package/dist/card/run-state.js +7 -0
- package/dist/config/dir.d.ts +1 -0
- package/dist/config/dir.js +5 -1
- package/dist/config/index.d.ts +1 -0
- package/dist/config/index.js +2 -0
- package/dist/connector/index.js +20 -0
- package/dist/index.js +54 -2
- package/dist/router/index.d.ts +62 -1
- package/dist/router/index.js +466 -46
- package/dist/runner/codex/argv.d.ts +1 -1
- package/dist/runner/codex/argv.js +1 -1
- package/dist/runner/common/runner-utils.d.ts +12 -0
- package/dist/runner/common/runner-utils.js +21 -0
- package/dist/runner/common/spawning-runner.js +9 -1
- package/dist/session/claude/session-index.d.ts +93 -0
- package/dist/session/claude/session-index.js +374 -0
- package/dist/session/claude/sessions.d.ts +0 -18
- package/dist/session/claude/sessions.js +102 -319
- package/dist/session/codex/rollout-reader.js +3 -3
- package/dist/update/index.d.ts +10 -0
- package/dist/update/index.js +11 -0
- package/dist/update/install.d.ts +29 -0
- package/dist/update/install.js +93 -0
- package/dist/update/startup-hint.d.ts +5 -0
- package/dist/update/startup-hint.js +11 -0
- package/dist/update/version-check.d.ts +31 -0
- package/dist/update/version-check.js +149 -0
- package/dist/workspace/index.d.ts +19 -1
- package/dist/workspace/index.js +51 -5
- package/package.json +1 -14
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { execFile, execFileSync } from 'node:child_process';
|
|
2
|
+
import { getLogger } from '../logger/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Detect which package manager to use for global install.
|
|
5
|
+
*
|
|
6
|
+
* Priority:
|
|
7
|
+
* 1. Environment variable override (LARK_REMOTE_MANAGED_BY)
|
|
8
|
+
* 2. `which` availability: npm → bun → pnpm
|
|
9
|
+
*/
|
|
10
|
+
export function detectPackageManager() {
|
|
11
|
+
// 1. Env override (highest priority)
|
|
12
|
+
const env = process.env.LARK_REMOTE_MANAGED_BY;
|
|
13
|
+
if (env === 'npm' || env === 'bun' || env === 'pnpm')
|
|
14
|
+
return env;
|
|
15
|
+
// 2. which availability detection
|
|
16
|
+
const candidates = ['npm', 'bun', 'pnpm'];
|
|
17
|
+
for (const cmd of candidates) {
|
|
18
|
+
try {
|
|
19
|
+
execFileSync('which', [cmd], { stdio: 'pipe', timeout: 3000 });
|
|
20
|
+
return cmd;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// Not found, try next
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
/** Get the install command for a package manager. */
|
|
29
|
+
function getInstallCommand(pm) {
|
|
30
|
+
switch (pm) {
|
|
31
|
+
case 'npm':
|
|
32
|
+
return { cmd: 'npm', args: ['install', '-g', 'lark-remote@latest'] };
|
|
33
|
+
case 'bun':
|
|
34
|
+
return { cmd: 'bun', args: ['install', '-g', 'lark-remote@latest'] };
|
|
35
|
+
case 'pnpm':
|
|
36
|
+
return { cmd: 'pnpm', args: ['add', '-g', 'lark-remote@latest'] };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Run the global install command to upgrade lark-remote to the latest version.
|
|
41
|
+
*
|
|
42
|
+
* @param opts.packageManager - Override detected package manager
|
|
43
|
+
* @param opts.execFn - Override execFile for testing
|
|
44
|
+
*/
|
|
45
|
+
export function runInstallLatest(opts) {
|
|
46
|
+
// If packageManager is explicitly null, skip detection and fail immediately.
|
|
47
|
+
// If undefined (not provided), run detection.
|
|
48
|
+
let pm;
|
|
49
|
+
if (opts?.packageManager === null) {
|
|
50
|
+
pm = null;
|
|
51
|
+
}
|
|
52
|
+
else if (opts?.packageManager) {
|
|
53
|
+
pm = opts.packageManager;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
pm = detectPackageManager();
|
|
57
|
+
}
|
|
58
|
+
if (!pm) {
|
|
59
|
+
return Promise.resolve({
|
|
60
|
+
success: false,
|
|
61
|
+
error: '未检测到可用的包管理器(npm/bun/pnpm),请手动执行 npm install -g lark-remote@latest',
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
const { cmd, args } = getInstallCommand(pm);
|
|
65
|
+
const execFn = opts?.execFn ?? ((...args) => execFile(...args));
|
|
66
|
+
const logger = getLogger();
|
|
67
|
+
logger.info(`[update] running: ${cmd} ${args.join(' ')}`);
|
|
68
|
+
return new Promise((resolve) => {
|
|
69
|
+
execFn(cmd, args, { timeout: 120_000, encoding: 'utf8' }, // 2 min timeout for npm install
|
|
70
|
+
(err, _stdout, _stderr) => {
|
|
71
|
+
if (err) {
|
|
72
|
+
const msg = err.message || String(_stderr);
|
|
73
|
+
logger.error(`[update] install failed: ${msg}`);
|
|
74
|
+
// Detect common errors and give actionable advice
|
|
75
|
+
if (msg.includes('EACCES') || msg.includes('permission')) {
|
|
76
|
+
resolve({
|
|
77
|
+
success: false,
|
|
78
|
+
error: `权限不足,尝试 sudo ${cmd} ${args.join(' ')}`,
|
|
79
|
+
});
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
resolve({
|
|
83
|
+
success: false,
|
|
84
|
+
error: msg.split('\n')[0], // First line only
|
|
85
|
+
});
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
logger.info(`[update] install succeeded`);
|
|
89
|
+
resolve({ success: true });
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { isNewer } from './version-check.js';
|
|
2
|
+
/**
|
|
3
|
+
* Format an update hint string for the startup notification.
|
|
4
|
+
* Returns null if no newer version is available.
|
|
5
|
+
*/
|
|
6
|
+
export function formatUpdateHint(current, latest) {
|
|
7
|
+
if (!isNewer(current, latest))
|
|
8
|
+
return null;
|
|
9
|
+
return `📦 有新版本 ${latest} 可用(当前 ${current}),发送 /update 升级`;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=startup-hint.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Cache TTL for version check results (1 hour). */
|
|
2
|
+
export declare const CACHE_TTL_MS: number;
|
|
3
|
+
/** Cache file schema. */
|
|
4
|
+
export interface UpdateCache {
|
|
5
|
+
latestVersion: string;
|
|
6
|
+
checkedAt: string;
|
|
7
|
+
}
|
|
8
|
+
/** Result of a version check. */
|
|
9
|
+
export interface VersionCheckResult {
|
|
10
|
+
current: string;
|
|
11
|
+
latest: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Compare two semver strings (major.minor.patch).
|
|
15
|
+
* Returns true if latest > current, false if latest <= current,
|
|
16
|
+
* null if either version is not a valid semver string.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isNewer(current: string, latest: string): boolean | null;
|
|
19
|
+
/**
|
|
20
|
+
* Check the latest available version of lark-remote.
|
|
21
|
+
* Uses a local cache file with 1-hour TTL to avoid frequent network requests.
|
|
22
|
+
*
|
|
23
|
+
* @param opts.cachePath - Path to cache file (default: <configDir>/update-cache.json)
|
|
24
|
+
* @param opts.bypassCache - If true, always fetch from registry
|
|
25
|
+
* @param opts.registryUrl - Override registry URL (for testing)
|
|
26
|
+
*/
|
|
27
|
+
export declare function checkLatestVersion(opts?: {
|
|
28
|
+
cachePath?: string;
|
|
29
|
+
bypassCache?: boolean;
|
|
30
|
+
registryUrl?: string;
|
|
31
|
+
}): Promise<VersionCheckResult>;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import https from 'node:https';
|
|
2
|
+
import http from 'node:http';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import { getVersion } from '../config/dir.js';
|
|
5
|
+
import { getLogger } from '../logger/index.js';
|
|
6
|
+
import { atomicWrite } from '../persistence/atomic-write.js';
|
|
7
|
+
/** Cache TTL for version check results (1 hour). */
|
|
8
|
+
export const CACHE_TTL_MS = 60 * 60 * 1000;
|
|
9
|
+
/** Default npm registry endpoint for latest version query. */
|
|
10
|
+
const DEFAULT_REGISTRY_URL = 'https://registry.npmjs.org/lark-remote/latest';
|
|
11
|
+
/**
|
|
12
|
+
* Compare two semver strings (major.minor.patch).
|
|
13
|
+
* Returns true if latest > current, false if latest <= current,
|
|
14
|
+
* null if either version is not a valid semver string.
|
|
15
|
+
*/
|
|
16
|
+
export function isNewer(current, latest) {
|
|
17
|
+
const parse = (v) => {
|
|
18
|
+
// Split core and pre-release suffix; compare the core numerically and treat
|
|
19
|
+
// a release as newer than any pre-release of the same core version.
|
|
20
|
+
const [core, pre = ''] = v.trim().split('-', 2);
|
|
21
|
+
const parts = core.split('.');
|
|
22
|
+
if (parts.length !== 3)
|
|
23
|
+
return null;
|
|
24
|
+
const nums = parts.map((p) => (/^\d+$/.test(p) ? Number(p) : NaN));
|
|
25
|
+
if (nums.some((n) => !Number.isInteger(n) || n < 0))
|
|
26
|
+
return null;
|
|
27
|
+
return { nums: nums, pre };
|
|
28
|
+
};
|
|
29
|
+
const c = parse(current);
|
|
30
|
+
const l = parse(latest);
|
|
31
|
+
if (!c || !l)
|
|
32
|
+
return null;
|
|
33
|
+
for (let i = 0; i < 3; i++) {
|
|
34
|
+
if (l.nums[i] > c.nums[i])
|
|
35
|
+
return true;
|
|
36
|
+
if (l.nums[i] < c.nums[i])
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
// Equal core version: a release beats a pre-release of the same version.
|
|
40
|
+
if (c.pre !== l.pre)
|
|
41
|
+
return l.pre === '';
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Fetch the latest version from npm registry.
|
|
46
|
+
* Returns the version string.
|
|
47
|
+
*/
|
|
48
|
+
function fetchLatestVersion(registryUrl) {
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
const mod = registryUrl.startsWith('https') ? https : http;
|
|
51
|
+
const req = mod.get(registryUrl, { timeout: 10_000 }, (res) => {
|
|
52
|
+
if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
53
|
+
// Follow one redirect
|
|
54
|
+
fetchLatestVersion(res.headers.location).then(resolve, reject);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (res.statusCode !== 200) {
|
|
58
|
+
reject(new Error(`npm registry returned status ${res.statusCode}`));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
let data = '';
|
|
62
|
+
res.on('data', (chunk) => {
|
|
63
|
+
data += chunk.toString();
|
|
64
|
+
});
|
|
65
|
+
res.on('end', () => {
|
|
66
|
+
try {
|
|
67
|
+
const parsed = JSON.parse(data);
|
|
68
|
+
if (!parsed.version) {
|
|
69
|
+
reject(new Error('npm registry response missing version field'));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
resolve(parsed.version);
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
reject(new Error(`npm registry response parse error: ${err.message}`));
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
req.on('error', reject);
|
|
80
|
+
req.on('timeout', () => {
|
|
81
|
+
req.destroy();
|
|
82
|
+
reject(new Error('npm registry request timed out'));
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Read cached version check result. Returns null if cache is missing,
|
|
88
|
+
* expired, or corrupt.
|
|
89
|
+
*/
|
|
90
|
+
function readCache(cachePath) {
|
|
91
|
+
try {
|
|
92
|
+
if (!fs.existsSync(cachePath))
|
|
93
|
+
return null;
|
|
94
|
+
const raw = fs.readFileSync(cachePath, 'utf8');
|
|
95
|
+
const cached = JSON.parse(raw);
|
|
96
|
+
if (!cached.latestVersion || !cached.checkedAt)
|
|
97
|
+
return null;
|
|
98
|
+
return cached;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/** Write version check result to cache file. */
|
|
105
|
+
function writeCache(cachePath, latestVersion) {
|
|
106
|
+
try {
|
|
107
|
+
const cache = {
|
|
108
|
+
latestVersion,
|
|
109
|
+
checkedAt: new Date().toISOString(),
|
|
110
|
+
};
|
|
111
|
+
atomicWrite(cachePath, JSON.stringify(cache), 'utf8');
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
getLogger().warn(`[update] failed to write cache: ${err.message}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Check the latest available version of lark-remote.
|
|
119
|
+
* Uses a local cache file with 1-hour TTL to avoid frequent network requests.
|
|
120
|
+
*
|
|
121
|
+
* @param opts.cachePath - Path to cache file (default: <configDir>/update-cache.json)
|
|
122
|
+
* @param opts.bypassCache - If true, always fetch from registry
|
|
123
|
+
* @param opts.registryUrl - Override registry URL (for testing)
|
|
124
|
+
*/
|
|
125
|
+
export async function checkLatestVersion(opts) {
|
|
126
|
+
const current = getVersion();
|
|
127
|
+
const registryUrl = opts?.registryUrl ?? DEFAULT_REGISTRY_URL;
|
|
128
|
+
const cachePath = opts?.cachePath;
|
|
129
|
+
// Try cache first (unless bypassed)
|
|
130
|
+
if (cachePath && !opts?.bypassCache) {
|
|
131
|
+
const cached = readCache(cachePath);
|
|
132
|
+
if (cached) {
|
|
133
|
+
const age = Date.now() - new Date(cached.checkedAt).getTime();
|
|
134
|
+
if (age < CACHE_TTL_MS) {
|
|
135
|
+
getLogger().info(`[update] using cached latest version: ${cached.latestVersion}`);
|
|
136
|
+
return { current, latest: cached.latestVersion };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// Fetch from registry
|
|
141
|
+
getLogger().info(`[update] checking latest version from ${registryUrl}`);
|
|
142
|
+
const latest = await fetchLatestVersion(registryUrl);
|
|
143
|
+
// Update cache
|
|
144
|
+
if (cachePath) {
|
|
145
|
+
writeCache(cachePath, latest);
|
|
146
|
+
}
|
|
147
|
+
return { current, latest };
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=version-check.js.map
|
|
@@ -1,9 +1,18 @@
|
|
|
1
|
+
/** Public view of a workspace entry returned by list(). */
|
|
2
|
+
export interface WorkspaceEntry {
|
|
3
|
+
name: string;
|
|
4
|
+
path: string;
|
|
5
|
+
lastUsedAt: number;
|
|
6
|
+
}
|
|
1
7
|
/**
|
|
2
8
|
* Persistent named-alias store for workspace directories.
|
|
3
9
|
*
|
|
4
10
|
* Atomic write (§9.10): writes a temp file then `fs.rename` so a crash
|
|
5
11
|
* mid-write cannot leave a truncated JSON file. On load, a corrupt file
|
|
6
12
|
* is treated as empty (with a warning) so the bridge can still start.
|
|
13
|
+
*
|
|
14
|
+
* Data migration: old format `{ alias: "path" }` is normalized to
|
|
15
|
+
* `{ alias: { path, lastUsedAt: 0 } }` on first load and persisted.
|
|
7
16
|
*/
|
|
8
17
|
export declare class WorkspaceStore {
|
|
9
18
|
private filePath;
|
|
@@ -15,5 +24,14 @@ export declare class WorkspaceStore {
|
|
|
15
24
|
get(name: string): string | undefined;
|
|
16
25
|
has(name: string): boolean;
|
|
17
26
|
remove(name: string): void;
|
|
18
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Update lastUsedAt to now for the given alias and persist.
|
|
29
|
+
* No-op if the alias does not exist.
|
|
30
|
+
*/
|
|
31
|
+
touch(name: string): void;
|
|
32
|
+
/**
|
|
33
|
+
* List all workspace entries in insertion order.
|
|
34
|
+
* Sorting is the caller's responsibility (view concern).
|
|
35
|
+
*/
|
|
36
|
+
list(): WorkspaceEntry[];
|
|
19
37
|
}
|
package/dist/workspace/index.js
CHANGED
|
@@ -2,12 +2,16 @@ import path from 'node:path';
|
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import { atomicWriteJson } from '../persistence/atomic-write.js';
|
|
4
4
|
import { loadJsonFile } from '../persistence/load-json-file.js';
|
|
5
|
+
import { getLogger } from '../logger/index.js';
|
|
5
6
|
/**
|
|
6
7
|
* Persistent named-alias store for workspace directories.
|
|
7
8
|
*
|
|
8
9
|
* Atomic write (§9.10): writes a temp file then `fs.rename` so a crash
|
|
9
10
|
* mid-write cannot leave a truncated JSON file. On load, a corrupt file
|
|
10
11
|
* is treated as empty (with a warning) so the bridge can still start.
|
|
12
|
+
*
|
|
13
|
+
* Data migration: old format `{ alias: "path" }` is normalized to
|
|
14
|
+
* `{ alias: { path, lastUsedAt: 0 } }` on first load and persisted.
|
|
11
15
|
*/
|
|
12
16
|
export class WorkspaceStore {
|
|
13
17
|
filePath;
|
|
@@ -21,9 +25,32 @@ export class WorkspaceStore {
|
|
|
21
25
|
const parsed = loadJsonFile(this.filePath, undefined);
|
|
22
26
|
if (!parsed)
|
|
23
27
|
return;
|
|
28
|
+
let needsMigration = false;
|
|
24
29
|
for (const [k, v] of Object.entries(parsed)) {
|
|
25
|
-
if (typeof v === 'string')
|
|
26
|
-
|
|
30
|
+
if (typeof v === 'string') {
|
|
31
|
+
// Old format: string value → { path, lastUsedAt: 0 }
|
|
32
|
+
this.data.set(k, { path: v, lastUsedAt: 0 });
|
|
33
|
+
needsMigration = true;
|
|
34
|
+
}
|
|
35
|
+
else if (typeof v === 'object' &&
|
|
36
|
+
v !== null &&
|
|
37
|
+
typeof v.path === 'string') {
|
|
38
|
+
// New format: extract path and lastUsedAt (default 0 if missing)
|
|
39
|
+
const obj = v;
|
|
40
|
+
const lastUsedAt = typeof obj.lastUsedAt === 'number' ? obj.lastUsedAt : 0;
|
|
41
|
+
if (typeof obj.lastUsedAt !== 'number') {
|
|
42
|
+
if (obj.lastUsedAt !== undefined) {
|
|
43
|
+
getLogger().warn(`[workspace] "${k}" has invalid lastUsedAt (${JSON.stringify(obj.lastUsedAt)}), resetting to 0`);
|
|
44
|
+
}
|
|
45
|
+
needsMigration = true;
|
|
46
|
+
}
|
|
47
|
+
this.data.set(k, { path: obj.path, lastUsedAt });
|
|
48
|
+
}
|
|
49
|
+
// Non-string, non-object entries are silently skipped (existing behavior)
|
|
50
|
+
}
|
|
51
|
+
// Write back immediately if migration occurred
|
|
52
|
+
if (needsMigration) {
|
|
53
|
+
this.persist();
|
|
27
54
|
}
|
|
28
55
|
}
|
|
29
56
|
persist() {
|
|
@@ -33,11 +60,11 @@ export class WorkspaceStore {
|
|
|
33
60
|
atomicWriteJson(this.filePath, obj);
|
|
34
61
|
}
|
|
35
62
|
save(name, dirPath) {
|
|
36
|
-
this.data.set(name, dirPath);
|
|
63
|
+
this.data.set(name, { path: dirPath, lastUsedAt: 0 });
|
|
37
64
|
this.persist();
|
|
38
65
|
}
|
|
39
66
|
get(name) {
|
|
40
|
-
return this.data.get(name);
|
|
67
|
+
return this.data.get(name)?.path;
|
|
41
68
|
}
|
|
42
69
|
has(name) {
|
|
43
70
|
return this.data.has(name);
|
|
@@ -46,8 +73,27 @@ export class WorkspaceStore {
|
|
|
46
73
|
this.data.delete(name);
|
|
47
74
|
this.persist();
|
|
48
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Update lastUsedAt to now for the given alias and persist.
|
|
78
|
+
* No-op if the alias does not exist.
|
|
79
|
+
*/
|
|
80
|
+
touch(name) {
|
|
81
|
+
const entry = this.data.get(name);
|
|
82
|
+
if (!entry)
|
|
83
|
+
return;
|
|
84
|
+
entry.lastUsedAt = Date.now();
|
|
85
|
+
this.persist();
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* List all workspace entries in insertion order.
|
|
89
|
+
* Sorting is the caller's responsibility (view concern).
|
|
90
|
+
*/
|
|
49
91
|
list() {
|
|
50
|
-
return [...this.data.entries()]
|
|
92
|
+
return [...this.data.entries()].map(([name, data]) => ({
|
|
93
|
+
name,
|
|
94
|
+
path: data.path,
|
|
95
|
+
lastUsedAt: data.lastUsedAt,
|
|
96
|
+
}));
|
|
51
97
|
}
|
|
52
98
|
}
|
|
53
99
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lark-remote",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Feishu (Lark) private-chat bridge to local coding agents — Claude Code / Codex / opencode / pi / kimi, with live-streaming CardKit 2.0 cards",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
"CHANGELOG.md"
|
|
25
25
|
],
|
|
26
26
|
"scripts": {
|
|
27
|
-
"prepare": "husky",
|
|
28
27
|
"dev": "bun src/index.ts",
|
|
29
28
|
"build": "rm -rf dist && tsc && chmod +x dist/index.js dist/cli.js",
|
|
30
29
|
"typecheck": "tsc --noEmit",
|
|
@@ -108,21 +107,9 @@
|
|
|
108
107
|
"eslint": "^10.7.0",
|
|
109
108
|
"eslint-config-prettier": "^10.1.8",
|
|
110
109
|
"eslint-plugin-prettier": "^5.5.6",
|
|
111
|
-
"husky": "^9.1.7",
|
|
112
|
-
"lint-staged": "^17.3.0",
|
|
113
110
|
"prettier": "^3.9.5",
|
|
114
111
|
"typescript": "^6.0.0",
|
|
115
112
|
"typescript-eslint": "^8.63.0",
|
|
116
113
|
"vitest": "^4.1.10"
|
|
117
|
-
},
|
|
118
|
-
"lint-staged": {
|
|
119
|
-
"src/**/*.ts": [
|
|
120
|
-
"eslint --fix",
|
|
121
|
-
"prettier --write"
|
|
122
|
-
],
|
|
123
|
-
"tests/**/*.ts": [
|
|
124
|
-
"eslint --fix",
|
|
125
|
-
"prettier --write"
|
|
126
|
-
]
|
|
127
114
|
}
|
|
128
115
|
}
|