@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/bun/index.ts
CHANGED
|
@@ -1,74 +1,84 @@
|
|
|
1
|
-
import z from
|
|
2
|
-
import { Global } from
|
|
3
|
-
import { Log } from
|
|
4
|
-
import path from
|
|
5
|
-
import { NamedError } from
|
|
6
|
-
import { readableStreamToText } from
|
|
1
|
+
import z from 'zod';
|
|
2
|
+
import { Global } from '../global';
|
|
3
|
+
import { Log } from '../util/log';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { NamedError } from '../util/error';
|
|
6
|
+
import { readableStreamToText } from 'bun';
|
|
7
7
|
|
|
8
8
|
export namespace BunProc {
|
|
9
|
-
const log = Log.create({ service:
|
|
9
|
+
const log = Log.create({ service: 'bun' });
|
|
10
10
|
|
|
11
|
-
export async function run(
|
|
12
|
-
|
|
11
|
+
export async function run(
|
|
12
|
+
cmd: string[],
|
|
13
|
+
options?: Bun.SpawnOptions.OptionsObject<any, any, any>
|
|
14
|
+
) {
|
|
15
|
+
log.info('running', {
|
|
13
16
|
cmd: [which(), ...cmd],
|
|
14
17
|
...options,
|
|
15
|
-
})
|
|
18
|
+
});
|
|
16
19
|
const result = Bun.spawn([which(), ...cmd], {
|
|
17
20
|
...options,
|
|
18
|
-
stdout:
|
|
19
|
-
stderr:
|
|
21
|
+
stdout: 'pipe',
|
|
22
|
+
stderr: 'pipe',
|
|
20
23
|
env: {
|
|
21
24
|
...process.env,
|
|
22
25
|
...options?.env,
|
|
23
|
-
BUN_BE_BUN:
|
|
26
|
+
BUN_BE_BUN: '1',
|
|
24
27
|
},
|
|
25
|
-
})
|
|
26
|
-
const code = await result.exited
|
|
28
|
+
});
|
|
29
|
+
const code = await result.exited;
|
|
27
30
|
const stdout = result.stdout
|
|
28
|
-
? typeof result.stdout ===
|
|
31
|
+
? typeof result.stdout === 'number'
|
|
29
32
|
? result.stdout
|
|
30
33
|
: await readableStreamToText(result.stdout)
|
|
31
|
-
: undefined
|
|
34
|
+
: undefined;
|
|
32
35
|
const stderr = result.stderr
|
|
33
|
-
? typeof result.stderr ===
|
|
36
|
+
? typeof result.stderr === 'number'
|
|
34
37
|
? result.stderr
|
|
35
38
|
: await readableStreamToText(result.stderr)
|
|
36
|
-
: undefined
|
|
37
|
-
log.info(
|
|
39
|
+
: undefined;
|
|
40
|
+
log.info('done', {
|
|
38
41
|
code,
|
|
39
42
|
stdout,
|
|
40
43
|
stderr,
|
|
41
|
-
})
|
|
44
|
+
});
|
|
42
45
|
if (code !== 0) {
|
|
43
|
-
throw new Error(`Command failed with exit code ${result.exitCode}`)
|
|
46
|
+
throw new Error(`Command failed with exit code ${result.exitCode}`);
|
|
44
47
|
}
|
|
45
|
-
return result
|
|
48
|
+
return result;
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
export function which() {
|
|
49
|
-
return process.execPath
|
|
52
|
+
return process.execPath;
|
|
50
53
|
}
|
|
51
54
|
|
|
52
55
|
export const InstallFailedError = NamedError.create(
|
|
53
|
-
|
|
56
|
+
'BunInstallFailedError',
|
|
54
57
|
z.object({
|
|
55
58
|
pkg: z.string(),
|
|
56
59
|
version: z.string(),
|
|
57
|
-
})
|
|
58
|
-
)
|
|
60
|
+
})
|
|
61
|
+
);
|
|
59
62
|
|
|
60
|
-
export async function install(pkg: string, version =
|
|
61
|
-
const mod = path.join(Global.Path.cache,
|
|
62
|
-
const pkgjson = Bun.file(path.join(Global.Path.cache,
|
|
63
|
+
export async function install(pkg: string, version = 'latest') {
|
|
64
|
+
const mod = path.join(Global.Path.cache, 'node_modules', pkg);
|
|
65
|
+
const pkgjson = Bun.file(path.join(Global.Path.cache, 'package.json'));
|
|
63
66
|
const parsed = await pkgjson.json().catch(async () => {
|
|
64
|
-
const result = { dependencies: {} }
|
|
65
|
-
await Bun.write(pkgjson.name!, JSON.stringify(result, null, 2))
|
|
66
|
-
return result
|
|
67
|
-
})
|
|
68
|
-
if (parsed.dependencies[pkg] === version) return mod
|
|
67
|
+
const result = { dependencies: {} };
|
|
68
|
+
await Bun.write(pkgjson.name!, JSON.stringify(result, null, 2));
|
|
69
|
+
return result;
|
|
70
|
+
});
|
|
71
|
+
if (parsed.dependencies[pkg] === version) return mod;
|
|
69
72
|
|
|
70
73
|
// Build command arguments
|
|
71
|
-
const args = [
|
|
74
|
+
const args = [
|
|
75
|
+
'add',
|
|
76
|
+
'--force',
|
|
77
|
+
'--exact',
|
|
78
|
+
'--cwd',
|
|
79
|
+
Global.Path.cache,
|
|
80
|
+
pkg + '@' + version,
|
|
81
|
+
];
|
|
72
82
|
|
|
73
83
|
// Let Bun handle registry resolution:
|
|
74
84
|
// - If .npmrc files exist, Bun will use them automatically
|
|
@@ -77,7 +87,7 @@ export namespace BunProc {
|
|
|
77
87
|
log.info("installing package using Bun's default registry resolution", {
|
|
78
88
|
pkg,
|
|
79
89
|
version,
|
|
80
|
-
})
|
|
90
|
+
});
|
|
81
91
|
|
|
82
92
|
await BunProc.run(args, {
|
|
83
93
|
cwd: Global.Path.cache,
|
|
@@ -86,11 +96,11 @@ export namespace BunProc {
|
|
|
86
96
|
{ pkg, version },
|
|
87
97
|
{
|
|
88
98
|
cause: e,
|
|
89
|
-
}
|
|
90
|
-
)
|
|
91
|
-
})
|
|
92
|
-
parsed.dependencies[pkg] = version
|
|
93
|
-
await Bun.write(pkgjson.name!, JSON.stringify(parsed, null, 2))
|
|
94
|
-
return mod
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
});
|
|
102
|
+
parsed.dependencies[pkg] = version;
|
|
103
|
+
await Bun.write(pkgjson.name!, JSON.stringify(parsed, null, 2));
|
|
104
|
+
return mod;
|
|
95
105
|
}
|
|
96
106
|
}
|
package/src/bus/global.ts
CHANGED
package/src/bus/index.ts
CHANGED
|
@@ -1,38 +1,41 @@
|
|
|
1
|
-
import z from
|
|
2
|
-
import type { ZodType } from
|
|
3
|
-
import { Log } from
|
|
4
|
-
import { Instance } from
|
|
5
|
-
import { GlobalBus } from
|
|
1
|
+
import z from 'zod';
|
|
2
|
+
import type { ZodType } from 'zod';
|
|
3
|
+
import { Log } from '../util/log';
|
|
4
|
+
import { Instance } from '../project/instance';
|
|
5
|
+
import { GlobalBus } from './global';
|
|
6
6
|
|
|
7
7
|
export namespace Bus {
|
|
8
|
-
const log = Log.create({ service:
|
|
9
|
-
type Subscription = (event: any) => void
|
|
8
|
+
const log = Log.create({ service: 'bus' });
|
|
9
|
+
type Subscription = (event: any) => void;
|
|
10
10
|
|
|
11
11
|
const state = Instance.state(() => {
|
|
12
|
-
const subscriptions = new Map<any, Subscription[]>()
|
|
12
|
+
const subscriptions = new Map<any, Subscription[]>();
|
|
13
13
|
|
|
14
14
|
return {
|
|
15
15
|
subscriptions,
|
|
16
|
-
}
|
|
17
|
-
})
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
18
|
|
|
19
|
-
export type EventDefinition = ReturnType<typeof event
|
|
19
|
+
export type EventDefinition = ReturnType<typeof event>;
|
|
20
20
|
|
|
21
|
-
const registry = new Map<string, EventDefinition>()
|
|
21
|
+
const registry = new Map<string, EventDefinition>();
|
|
22
22
|
|
|
23
|
-
export function event<Type extends string, Properties extends ZodType>(
|
|
23
|
+
export function event<Type extends string, Properties extends ZodType>(
|
|
24
|
+
type: Type,
|
|
25
|
+
properties: Properties
|
|
26
|
+
) {
|
|
24
27
|
const result = {
|
|
25
28
|
type,
|
|
26
29
|
properties,
|
|
27
|
-
}
|
|
28
|
-
registry.set(type, result)
|
|
29
|
-
return result
|
|
30
|
+
};
|
|
31
|
+
registry.set(type, result);
|
|
32
|
+
return result;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
export function payloads() {
|
|
33
36
|
return z
|
|
34
37
|
.discriminatedUnion(
|
|
35
|
-
|
|
38
|
+
'type',
|
|
36
39
|
registry
|
|
37
40
|
.entries()
|
|
38
41
|
.map(([type, def]) => {
|
|
@@ -42,78 +45,81 @@ export namespace Bus {
|
|
|
42
45
|
properties: def.properties,
|
|
43
46
|
})
|
|
44
47
|
.meta({
|
|
45
|
-
ref:
|
|
46
|
-
})
|
|
48
|
+
ref: 'Event' + '.' + def.type,
|
|
49
|
+
});
|
|
47
50
|
})
|
|
48
|
-
.toArray() as any
|
|
51
|
+
.toArray() as any
|
|
49
52
|
)
|
|
50
53
|
.meta({
|
|
51
|
-
ref:
|
|
52
|
-
})
|
|
54
|
+
ref: 'Event',
|
|
55
|
+
});
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
export async function publish<Definition extends EventDefinition>(
|
|
56
59
|
def: Definition,
|
|
57
|
-
properties: z.output<Definition[
|
|
60
|
+
properties: z.output<Definition['properties']>
|
|
58
61
|
) {
|
|
59
62
|
const payload = {
|
|
60
63
|
type: def.type,
|
|
61
64
|
properties,
|
|
62
|
-
}
|
|
63
|
-
log.info(
|
|
65
|
+
};
|
|
66
|
+
log.info('publishing', {
|
|
64
67
|
type: def.type,
|
|
65
|
-
})
|
|
66
|
-
const pending = []
|
|
67
|
-
for (const key of [def.type,
|
|
68
|
-
const match = state().subscriptions.get(key)
|
|
68
|
+
});
|
|
69
|
+
const pending = [];
|
|
70
|
+
for (const key of [def.type, '*']) {
|
|
71
|
+
const match = state().subscriptions.get(key);
|
|
69
72
|
for (const sub of match ?? []) {
|
|
70
|
-
pending.push(sub(payload))
|
|
73
|
+
pending.push(sub(payload));
|
|
71
74
|
}
|
|
72
75
|
}
|
|
73
|
-
GlobalBus.emit(
|
|
76
|
+
GlobalBus.emit('event', {
|
|
74
77
|
directory: Instance.directory,
|
|
75
78
|
payload,
|
|
76
|
-
})
|
|
77
|
-
return Promise.all(pending)
|
|
79
|
+
});
|
|
80
|
+
return Promise.all(pending);
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
export function subscribe<Definition extends EventDefinition>(
|
|
81
84
|
def: Definition,
|
|
82
|
-
callback: (event: {
|
|
85
|
+
callback: (event: {
|
|
86
|
+
type: Definition['type'];
|
|
87
|
+
properties: z.infer<Definition['properties']>;
|
|
88
|
+
}) => void
|
|
83
89
|
) {
|
|
84
|
-
return raw(def.type, callback)
|
|
90
|
+
return raw(def.type, callback);
|
|
85
91
|
}
|
|
86
92
|
|
|
87
93
|
export function once<Definition extends EventDefinition>(
|
|
88
94
|
def: Definition,
|
|
89
95
|
callback: (event: {
|
|
90
|
-
type: Definition[
|
|
91
|
-
properties: z.infer<Definition[
|
|
92
|
-
}) =>
|
|
96
|
+
type: Definition['type'];
|
|
97
|
+
properties: z.infer<Definition['properties']>;
|
|
98
|
+
}) => 'done' | undefined
|
|
93
99
|
) {
|
|
94
100
|
const unsub = subscribe(def, (event) => {
|
|
95
|
-
if (callback(event)) unsub()
|
|
96
|
-
})
|
|
101
|
+
if (callback(event)) unsub();
|
|
102
|
+
});
|
|
97
103
|
}
|
|
98
104
|
|
|
99
105
|
export function subscribeAll(callback: (event: any) => void) {
|
|
100
|
-
return raw(
|
|
106
|
+
return raw('*', callback);
|
|
101
107
|
}
|
|
102
108
|
|
|
103
109
|
function raw(type: string, callback: (event: any) => void) {
|
|
104
|
-
log.info(
|
|
105
|
-
const subscriptions = state().subscriptions
|
|
106
|
-
let match = subscriptions.get(type) ?? []
|
|
107
|
-
match.push(callback)
|
|
108
|
-
subscriptions.set(type, match)
|
|
110
|
+
log.info('subscribing', { type });
|
|
111
|
+
const subscriptions = state().subscriptions;
|
|
112
|
+
let match = subscriptions.get(type) ?? [];
|
|
113
|
+
match.push(callback);
|
|
114
|
+
subscriptions.set(type, match);
|
|
109
115
|
|
|
110
116
|
return () => {
|
|
111
|
-
log.info(
|
|
112
|
-
const match = subscriptions.get(type)
|
|
113
|
-
if (!match) return
|
|
114
|
-
const index = match.indexOf(callback)
|
|
115
|
-
if (index === -1) return
|
|
116
|
-
match.splice(index, 1)
|
|
117
|
-
}
|
|
117
|
+
log.info('unsubscribing', { type });
|
|
118
|
+
const match = subscriptions.get(type);
|
|
119
|
+
if (!match) return;
|
|
120
|
+
const index = match.indexOf(callback);
|
|
121
|
+
if (index === -1) return;
|
|
122
|
+
match.splice(index, 1);
|
|
123
|
+
};
|
|
118
124
|
}
|
|
119
125
|
}
|
package/src/cli/bootstrap.js
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
// Permalink: https://github.com/sst/opencode/blob/main/packages/opencode/src/project/instance.ts
|
|
3
3
|
// Permalink: https://github.com/sst/opencode/blob/main/packages/opencode/src/project/bootstrap.ts
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// createOpencode is available from @opencode-ai/sdk but not used directly
|
|
6
6
|
|
|
7
7
|
class Instance {
|
|
8
|
-
static directory = process.cwd()
|
|
9
|
-
static worktree = process.cwd()
|
|
8
|
+
static directory = process.cwd();
|
|
9
|
+
static worktree = process.cwd();
|
|
10
10
|
|
|
11
11
|
static provide(options) {
|
|
12
|
-
this.directory = options.directory
|
|
13
|
-
this.worktree = options.directory
|
|
14
|
-
return options.fn()
|
|
12
|
+
this.directory = options.directory;
|
|
13
|
+
this.worktree = options.directory;
|
|
14
|
+
return options.fn();
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
static dispose() {
|
|
@@ -25,17 +25,17 @@ class InstanceBootstrap {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export
|
|
28
|
+
export function bootstrap(directory, cb) {
|
|
29
29
|
return Instance.provide({
|
|
30
30
|
directory,
|
|
31
31
|
init: InstanceBootstrap,
|
|
32
32
|
fn: async () => {
|
|
33
33
|
try {
|
|
34
|
-
const result = await cb()
|
|
35
|
-
return result
|
|
34
|
+
const result = await cb();
|
|
35
|
+
return result;
|
|
36
36
|
} finally {
|
|
37
|
-
await Instance.dispose()
|
|
37
|
+
await Instance.dispose();
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
|
-
})
|
|
41
|
-
}
|
|
40
|
+
});
|
|
41
|
+
}
|
package/src/cli/bootstrap.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { InstanceBootstrap } from
|
|
2
|
-
import { Instance } from
|
|
1
|
+
import { InstanceBootstrap } from '../project/bootstrap';
|
|
2
|
+
import { Instance } from '../project/instance';
|
|
3
3
|
|
|
4
4
|
export async function bootstrap<T>(directory: string, cb: () => Promise<T>) {
|
|
5
5
|
return Instance.provide({
|
|
@@ -7,11 +7,11 @@ export async function bootstrap<T>(directory: string, cb: () => Promise<T>) {
|
|
|
7
7
|
init: InstanceBootstrap,
|
|
8
8
|
fn: async () => {
|
|
9
9
|
try {
|
|
10
|
-
const result = await cb()
|
|
11
|
-
return result
|
|
10
|
+
const result = await cb();
|
|
11
|
+
return result;
|
|
12
12
|
} finally {
|
|
13
|
-
await Instance.dispose()
|
|
13
|
+
await Instance.dispose();
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
|
-
})
|
|
16
|
+
});
|
|
17
17
|
}
|