@link-assistant/agent 0.0.8 → 0.0.11
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/EXAMPLES.md +80 -1
- package/MODELS.md +72 -24
- package/README.md +95 -2
- package/TOOLS.md +20 -0
- package/package.json +36 -2
- package/src/agent/agent.ts +68 -54
- package/src/auth/claude-oauth.ts +426 -0
- package/src/auth/index.ts +28 -26
- package/src/auth/plugins.ts +876 -0
- package/src/bun/index.ts +53 -43
- package/src/bus/global.ts +5 -5
- package/src/bus/index.ts +59 -53
- package/src/cli/bootstrap.js +12 -12
- package/src/cli/bootstrap.ts +6 -6
- package/src/cli/cmd/agent.ts +97 -92
- package/src/cli/cmd/auth.ts +468 -0
- package/src/cli/cmd/cmd.ts +2 -2
- package/src/cli/cmd/export.ts +41 -41
- package/src/cli/cmd/mcp.ts +210 -53
- package/src/cli/cmd/models.ts +30 -29
- package/src/cli/cmd/run.ts +269 -213
- package/src/cli/cmd/stats.ts +185 -146
- package/src/cli/error.ts +17 -13
- package/src/cli/ui.ts +78 -0
- package/src/command/index.ts +26 -26
- package/src/config/config.ts +528 -288
- package/src/config/markdown.ts +15 -15
- package/src/file/ripgrep.ts +201 -169
- package/src/file/time.ts +21 -18
- package/src/file/watcher.ts +51 -42
- package/src/file.ts +1 -1
- package/src/flag/flag.ts +26 -11
- package/src/format/formatter.ts +206 -162
- package/src/format/index.ts +61 -61
- package/src/global/index.ts +21 -21
- package/src/id/id.ts +47 -33
- package/src/index.js +554 -332
- package/src/json-standard/index.ts +173 -0
- package/src/mcp/index.ts +135 -128
- package/src/patch/index.ts +336 -267
- package/src/project/bootstrap.ts +15 -15
- package/src/project/instance.ts +43 -36
- package/src/project/project.ts +47 -47
- package/src/project/state.ts +37 -33
- package/src/provider/models-macro.ts +5 -5
- package/src/provider/models.ts +32 -32
- package/src/provider/opencode.js +19 -19
- package/src/provider/provider.ts +518 -277
- package/src/provider/transform.ts +143 -102
- package/src/server/project.ts +21 -21
- package/src/server/server.ts +111 -105
- package/src/session/agent.js +66 -60
- package/src/session/compaction.ts +136 -111
- package/src/session/index.ts +189 -156
- package/src/session/message-v2.ts +312 -268
- package/src/session/message.ts +73 -57
- package/src/session/processor.ts +180 -166
- package/src/session/prompt.ts +678 -533
- package/src/session/retry.ts +26 -23
- package/src/session/revert.ts +76 -62
- package/src/session/status.ts +26 -26
- package/src/session/summary.ts +97 -76
- package/src/session/system.ts +77 -63
- package/src/session/todo.ts +22 -16
- package/src/snapshot/index.ts +92 -76
- package/src/storage/storage.ts +157 -120
- package/src/tool/bash.ts +116 -106
- package/src/tool/batch.ts +73 -59
- package/src/tool/codesearch.ts +60 -53
- package/src/tool/edit.ts +319 -263
- package/src/tool/glob.ts +32 -28
- package/src/tool/grep.ts +72 -53
- package/src/tool/invalid.ts +7 -7
- package/src/tool/ls.ts +77 -64
- package/src/tool/multiedit.ts +30 -21
- package/src/tool/patch.ts +121 -94
- package/src/tool/read.ts +140 -122
- package/src/tool/registry.ts +38 -38
- package/src/tool/task.ts +93 -60
- package/src/tool/todo.ts +16 -16
- package/src/tool/tool.ts +45 -36
- package/src/tool/webfetch.ts +97 -74
- package/src/tool/websearch.ts +78 -64
- package/src/tool/write.ts +21 -15
- package/src/util/binary.ts +27 -19
- package/src/util/context.ts +8 -8
- package/src/util/defer.ts +7 -5
- package/src/util/error.ts +24 -19
- package/src/util/eventloop.ts +16 -10
- package/src/util/filesystem.ts +37 -33
- package/src/util/fn.ts +11 -8
- package/src/util/iife.ts +1 -1
- package/src/util/keybind.ts +44 -44
- package/src/util/lazy.ts +7 -7
- package/src/util/locale.ts +20 -16
- package/src/util/lock.ts +43 -38
- package/src/util/log.ts +95 -85
- package/src/util/queue.ts +8 -8
- package/src/util/rpc.ts +35 -23
- package/src/util/scrap.ts +4 -4
- package/src/util/signal.ts +5 -5
- package/src/util/timeout.ts +6 -6
- package/src/util/token.ts +2 -2
- package/src/util/wildcard.ts +38 -27
package/src/file/time.ts
CHANGED
|
@@ -1,38 +1,41 @@
|
|
|
1
|
-
import { Instance } from
|
|
2
|
-
import { Log } from
|
|
1
|
+
import { Instance } from '../project/instance';
|
|
2
|
+
import { Log } from '../util/log';
|
|
3
3
|
|
|
4
4
|
export namespace FileTime {
|
|
5
|
-
const log = Log.create({ service:
|
|
5
|
+
const log = Log.create({ service: 'file.time' });
|
|
6
6
|
export const state = Instance.state(() => {
|
|
7
7
|
const read: {
|
|
8
8
|
[sessionID: string]: {
|
|
9
|
-
[path: string]: Date | undefined
|
|
10
|
-
}
|
|
11
|
-
} = {}
|
|
9
|
+
[path: string]: Date | undefined;
|
|
10
|
+
};
|
|
11
|
+
} = {};
|
|
12
12
|
return {
|
|
13
13
|
read,
|
|
14
|
-
}
|
|
15
|
-
})
|
|
14
|
+
};
|
|
15
|
+
});
|
|
16
16
|
|
|
17
17
|
export function read(sessionID: string, file: string) {
|
|
18
|
-
log.info(
|
|
19
|
-
const { read } = state()
|
|
20
|
-
read[sessionID] = read[sessionID] || {}
|
|
21
|
-
read[sessionID][file] = new Date()
|
|
18
|
+
log.info('read', { sessionID, file });
|
|
19
|
+
const { read } = state();
|
|
20
|
+
read[sessionID] = read[sessionID] || {};
|
|
21
|
+
read[sessionID][file] = new Date();
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export function get(sessionID: string, file: string) {
|
|
25
|
-
return state().read[sessionID]?.[file]
|
|
25
|
+
return state().read[sessionID]?.[file];
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export async function assert(sessionID: string, filepath: string) {
|
|
29
|
-
const time = get(sessionID, filepath)
|
|
30
|
-
if (!time)
|
|
31
|
-
|
|
29
|
+
const time = get(sessionID, filepath);
|
|
30
|
+
if (!time)
|
|
31
|
+
throw new Error(
|
|
32
|
+
`You must read the file ${filepath} before overwriting it. Use the Read tool first`
|
|
33
|
+
);
|
|
34
|
+
const stats = await Bun.file(filepath).stat();
|
|
32
35
|
if (stats.mtime.getTime() > time.getTime()) {
|
|
33
36
|
throw new Error(
|
|
34
|
-
`File ${filepath} has been modified since it was last read.\nLast modification: ${stats.mtime.toISOString()}\nLast read: ${time.toISOString()}\n\nPlease read the file again before modifying it
|
|
35
|
-
)
|
|
37
|
+
`File ${filepath} has been modified since it was last read.\nLast modification: ${stats.mtime.toISOString()}\nLast read: ${time.toISOString()}\n\nPlease read the file again before modifying it.`
|
|
38
|
+
);
|
|
36
39
|
}
|
|
37
40
|
}
|
|
38
41
|
}
|
package/src/file/watcher.ts
CHANGED
|
@@ -1,75 +1,84 @@
|
|
|
1
|
-
import z from
|
|
2
|
-
import { Bus } from
|
|
3
|
-
import { Flag } from
|
|
4
|
-
import { Instance } from
|
|
5
|
-
import { Log } from
|
|
6
|
-
import { FileIgnore } from
|
|
7
|
-
import { Config } from
|
|
1
|
+
import z from 'zod';
|
|
2
|
+
import { Bus } from '../bus';
|
|
3
|
+
import { Flag } from '../flag/flag';
|
|
4
|
+
import { Instance } from '../project/instance';
|
|
5
|
+
import { Log } from '../util/log';
|
|
6
|
+
import { FileIgnore } from './ignore';
|
|
7
|
+
import { Config } from '../config/config';
|
|
8
8
|
// @ts-ignore
|
|
9
|
-
import { createWrapper } from
|
|
10
|
-
import { lazy } from
|
|
9
|
+
import { createWrapper } from '@parcel/watcher/wrapper';
|
|
10
|
+
import { lazy } from '../util/lazy';
|
|
11
11
|
|
|
12
12
|
export namespace FileWatcher {
|
|
13
|
-
const log = Log.create({ service:
|
|
13
|
+
const log = Log.create({ service: 'file.watcher' });
|
|
14
14
|
|
|
15
15
|
export const Event = {
|
|
16
16
|
Updated: Bus.event(
|
|
17
|
-
|
|
17
|
+
'file.watcher.updated',
|
|
18
18
|
z.object({
|
|
19
19
|
file: z.string(),
|
|
20
|
-
event: z.union([
|
|
21
|
-
|
|
20
|
+
event: z.union([
|
|
21
|
+
z.literal('add'),
|
|
22
|
+
z.literal('change'),
|
|
23
|
+
z.literal('unlink'),
|
|
24
|
+
]),
|
|
25
|
+
})
|
|
22
26
|
),
|
|
23
|
-
}
|
|
27
|
+
};
|
|
24
28
|
|
|
25
29
|
const watcher = lazy(() => {
|
|
26
30
|
const binding = require(
|
|
27
|
-
`@parcel/watcher-${process.platform}-${process.arch}${process.platform ===
|
|
28
|
-
)
|
|
29
|
-
return createWrapper(binding) as typeof import(
|
|
30
|
-
})
|
|
31
|
+
`@parcel/watcher-${process.platform}-${process.arch}${process.platform === 'linux' ? '-glibc' : ''}`
|
|
32
|
+
);
|
|
33
|
+
return createWrapper(binding) as typeof import('@parcel/watcher');
|
|
34
|
+
});
|
|
31
35
|
|
|
32
36
|
const state = Instance.state(
|
|
33
37
|
async () => {
|
|
34
|
-
if (Instance.project.vcs !==
|
|
35
|
-
log.info(
|
|
36
|
-
const cfg = await Config.get()
|
|
38
|
+
if (Instance.project.vcs !== 'git') return {};
|
|
39
|
+
log.info('init');
|
|
40
|
+
const cfg = await Config.get();
|
|
37
41
|
const backend = (() => {
|
|
38
|
-
if (process.platform ===
|
|
39
|
-
if (process.platform ===
|
|
40
|
-
if (process.platform ===
|
|
41
|
-
})()
|
|
42
|
+
if (process.platform === 'win32') return 'windows';
|
|
43
|
+
if (process.platform === 'darwin') return 'fs-events';
|
|
44
|
+
if (process.platform === 'linux') return 'inotify';
|
|
45
|
+
})();
|
|
42
46
|
if (!backend) {
|
|
43
|
-
log.error(
|
|
44
|
-
|
|
47
|
+
log.error('watcher backend not supported', {
|
|
48
|
+
platform: process.platform,
|
|
49
|
+
});
|
|
50
|
+
return {};
|
|
45
51
|
}
|
|
46
|
-
log.info(
|
|
52
|
+
log.info('watcher backend', { platform: process.platform, backend });
|
|
47
53
|
const sub = await watcher().subscribe(
|
|
48
54
|
Instance.directory,
|
|
49
55
|
(err, evts) => {
|
|
50
|
-
if (err) return
|
|
56
|
+
if (err) return;
|
|
51
57
|
for (const evt of evts) {
|
|
52
|
-
log.info(
|
|
53
|
-
if (evt.type ===
|
|
54
|
-
|
|
55
|
-
if (evt.type ===
|
|
58
|
+
log.info('event', evt);
|
|
59
|
+
if (evt.type === 'create')
|
|
60
|
+
Bus.publish(Event.Updated, { file: evt.path, event: 'add' });
|
|
61
|
+
if (evt.type === 'update')
|
|
62
|
+
Bus.publish(Event.Updated, { file: evt.path, event: 'change' });
|
|
63
|
+
if (evt.type === 'delete')
|
|
64
|
+
Bus.publish(Event.Updated, { file: evt.path, event: 'unlink' });
|
|
56
65
|
}
|
|
57
66
|
},
|
|
58
67
|
{
|
|
59
68
|
ignore: [...FileIgnore.PATTERNS, ...(cfg.watcher?.ignore ?? [])],
|
|
60
69
|
backend,
|
|
61
|
-
}
|
|
62
|
-
)
|
|
63
|
-
return { sub }
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
return { sub };
|
|
64
73
|
},
|
|
65
74
|
async (state) => {
|
|
66
|
-
if (!state.sub) return
|
|
67
|
-
await state.sub?.unsubscribe()
|
|
68
|
-
}
|
|
69
|
-
)
|
|
75
|
+
if (!state.sub) return;
|
|
76
|
+
await state.sub?.unsubscribe();
|
|
77
|
+
}
|
|
78
|
+
);
|
|
70
79
|
|
|
71
80
|
export function init() {
|
|
72
|
-
if (!Flag.OPENCODE_EXPERIMENTAL_WATCHER) return
|
|
73
|
-
state()
|
|
81
|
+
if (!Flag.OPENCODE_EXPERIMENTAL_WATCHER) return;
|
|
82
|
+
state();
|
|
74
83
|
}
|
|
75
84
|
}
|
package/src/file.ts
CHANGED
package/src/flag/flag.ts
CHANGED
|
@@ -1,19 +1,34 @@
|
|
|
1
1
|
export namespace Flag {
|
|
2
2
|
// OPENCODE_AUTO_SHARE removed - no sharing support
|
|
3
|
-
export const OPENCODE_CONFIG = process.env[
|
|
4
|
-
export const OPENCODE_CONFIG_DIR = process.env[
|
|
5
|
-
export const OPENCODE_CONFIG_CONTENT = process.env[
|
|
6
|
-
export const OPENCODE_DISABLE_AUTOUPDATE = truthy(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export const
|
|
3
|
+
export const OPENCODE_CONFIG = process.env['OPENCODE_CONFIG'];
|
|
4
|
+
export const OPENCODE_CONFIG_DIR = process.env['OPENCODE_CONFIG_DIR'];
|
|
5
|
+
export const OPENCODE_CONFIG_CONTENT = process.env['OPENCODE_CONFIG_CONTENT'];
|
|
6
|
+
export const OPENCODE_DISABLE_AUTOUPDATE = truthy(
|
|
7
|
+
'OPENCODE_DISABLE_AUTOUPDATE'
|
|
8
|
+
);
|
|
9
|
+
export const OPENCODE_DISABLE_PRUNE = truthy('OPENCODE_DISABLE_PRUNE');
|
|
10
|
+
export const OPENCODE_ENABLE_EXPERIMENTAL_MODELS = truthy(
|
|
11
|
+
'OPENCODE_ENABLE_EXPERIMENTAL_MODELS'
|
|
12
|
+
);
|
|
13
|
+
export const OPENCODE_DISABLE_AUTOCOMPACT = truthy(
|
|
14
|
+
'OPENCODE_DISABLE_AUTOCOMPACT'
|
|
15
|
+
);
|
|
10
16
|
|
|
11
17
|
// Experimental
|
|
12
|
-
export const OPENCODE_EXPERIMENTAL = truthy(
|
|
13
|
-
export const OPENCODE_EXPERIMENTAL_WATCHER =
|
|
18
|
+
export const OPENCODE_EXPERIMENTAL = truthy('OPENCODE_EXPERIMENTAL');
|
|
19
|
+
export const OPENCODE_EXPERIMENTAL_WATCHER =
|
|
20
|
+
OPENCODE_EXPERIMENTAL || truthy('OPENCODE_EXPERIMENTAL_WATCHER');
|
|
21
|
+
|
|
22
|
+
// Verbose mode - enables detailed logging of API requests
|
|
23
|
+
export let OPENCODE_VERBOSE = truthy('OPENCODE_VERBOSE');
|
|
24
|
+
|
|
25
|
+
// Allow setting verbose mode programmatically (e.g., from CLI --verbose flag)
|
|
26
|
+
export function setVerbose(value: boolean) {
|
|
27
|
+
OPENCODE_VERBOSE = value;
|
|
28
|
+
}
|
|
14
29
|
|
|
15
30
|
function truthy(key: string) {
|
|
16
|
-
const value = process.env[key]?.toLowerCase()
|
|
17
|
-
return value ===
|
|
31
|
+
const value = process.env[key]?.toLowerCase();
|
|
32
|
+
return value === 'true' || value === '1';
|
|
18
33
|
}
|
|
19
34
|
}
|