@link-assistant/agent 0.0.9 → 0.0.12

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.
Files changed (104) hide show
  1. package/EXAMPLES.md +36 -0
  2. package/MODELS.md +72 -24
  3. package/README.md +59 -2
  4. package/TOOLS.md +20 -0
  5. package/package.json +35 -2
  6. package/src/agent/agent.ts +68 -54
  7. package/src/auth/claude-oauth.ts +426 -0
  8. package/src/auth/index.ts +28 -26
  9. package/src/auth/plugins.ts +876 -0
  10. package/src/bun/index.ts +53 -43
  11. package/src/bus/global.ts +5 -5
  12. package/src/bus/index.ts +59 -53
  13. package/src/cli/bootstrap.js +12 -12
  14. package/src/cli/bootstrap.ts +6 -6
  15. package/src/cli/cmd/agent.ts +97 -92
  16. package/src/cli/cmd/auth.ts +469 -0
  17. package/src/cli/cmd/cmd.ts +2 -2
  18. package/src/cli/cmd/export.ts +41 -41
  19. package/src/cli/cmd/mcp.ts +144 -119
  20. package/src/cli/cmd/models.ts +30 -29
  21. package/src/cli/cmd/run.ts +269 -213
  22. package/src/cli/cmd/stats.ts +185 -146
  23. package/src/cli/error.ts +17 -13
  24. package/src/cli/ui.ts +39 -24
  25. package/src/command/index.ts +26 -26
  26. package/src/config/config.ts +528 -288
  27. package/src/config/markdown.ts +15 -15
  28. package/src/file/ripgrep.ts +201 -169
  29. package/src/file/time.ts +21 -18
  30. package/src/file/watcher.ts +51 -42
  31. package/src/file.ts +1 -1
  32. package/src/flag/flag.ts +26 -11
  33. package/src/format/formatter.ts +206 -162
  34. package/src/format/index.ts +61 -61
  35. package/src/global/index.ts +21 -21
  36. package/src/id/id.ts +47 -33
  37. package/src/index.js +346 -199
  38. package/src/json-standard/index.ts +67 -51
  39. package/src/mcp/index.ts +135 -128
  40. package/src/patch/index.ts +336 -267
  41. package/src/project/bootstrap.ts +15 -15
  42. package/src/project/instance.ts +43 -36
  43. package/src/project/project.ts +47 -47
  44. package/src/project/state.ts +37 -33
  45. package/src/provider/models-macro.ts +5 -5
  46. package/src/provider/models.ts +32 -32
  47. package/src/provider/opencode.js +19 -19
  48. package/src/provider/provider.ts +518 -277
  49. package/src/provider/transform.ts +143 -102
  50. package/src/server/project.ts +21 -21
  51. package/src/server/server.ts +111 -105
  52. package/src/session/agent.js +66 -60
  53. package/src/session/compaction.ts +136 -111
  54. package/src/session/index.ts +189 -156
  55. package/src/session/message-v2.ts +312 -268
  56. package/src/session/message.ts +73 -57
  57. package/src/session/processor.ts +180 -166
  58. package/src/session/prompt.ts +678 -533
  59. package/src/session/retry.ts +26 -23
  60. package/src/session/revert.ts +76 -62
  61. package/src/session/status.ts +26 -26
  62. package/src/session/summary.ts +97 -76
  63. package/src/session/system.ts +77 -63
  64. package/src/session/todo.ts +22 -16
  65. package/src/snapshot/index.ts +92 -76
  66. package/src/storage/storage.ts +157 -120
  67. package/src/tool/bash.ts +116 -106
  68. package/src/tool/batch.ts +73 -59
  69. package/src/tool/codesearch.ts +60 -53
  70. package/src/tool/edit.ts +319 -263
  71. package/src/tool/glob.ts +32 -28
  72. package/src/tool/grep.ts +72 -53
  73. package/src/tool/invalid.ts +7 -7
  74. package/src/tool/ls.ts +77 -64
  75. package/src/tool/multiedit.ts +30 -21
  76. package/src/tool/patch.ts +121 -94
  77. package/src/tool/read.ts +140 -122
  78. package/src/tool/registry.ts +38 -38
  79. package/src/tool/task.ts +93 -60
  80. package/src/tool/todo.ts +16 -16
  81. package/src/tool/tool.ts +45 -36
  82. package/src/tool/webfetch.ts +97 -74
  83. package/src/tool/websearch.ts +78 -64
  84. package/src/tool/write.ts +21 -15
  85. package/src/util/binary.ts +27 -19
  86. package/src/util/context.ts +8 -8
  87. package/src/util/defer.ts +7 -5
  88. package/src/util/error.ts +24 -19
  89. package/src/util/eventloop.ts +16 -10
  90. package/src/util/filesystem.ts +37 -33
  91. package/src/util/fn.ts +11 -8
  92. package/src/util/iife.ts +1 -1
  93. package/src/util/keybind.ts +44 -44
  94. package/src/util/lazy.ts +7 -7
  95. package/src/util/locale.ts +20 -16
  96. package/src/util/lock.ts +43 -38
  97. package/src/util/log.ts +95 -85
  98. package/src/util/queue.ts +8 -8
  99. package/src/util/rpc.ts +35 -23
  100. package/src/util/scrap.ts +4 -4
  101. package/src/util/signal.ts +5 -5
  102. package/src/util/timeout.ts +6 -6
  103. package/src/util/token.ts +2 -2
  104. package/src/util/wildcard.ts +38 -27
package/src/file/time.ts CHANGED
@@ -1,38 +1,41 @@
1
- import { Instance } from "../project/instance"
2
- import { Log } from "../util/log"
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: "file.time" })
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("read", { sessionID, file })
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) throw new Error(`You must read the file ${filepath} before overwriting it. Use the Read tool first`)
31
- const stats = await Bun.file(filepath).stat()
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
  }
@@ -1,75 +1,84 @@
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"
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 "@parcel/watcher/wrapper"
10
- import { lazy } from "../util/lazy"
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: "file.watcher" })
13
+ const log = Log.create({ service: 'file.watcher' });
14
14
 
15
15
  export const Event = {
16
16
  Updated: Bus.event(
17
- "file.watcher.updated",
17
+ 'file.watcher.updated',
18
18
  z.object({
19
19
  file: z.string(),
20
- event: z.union([z.literal("add"), z.literal("change"), z.literal("unlink")]),
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 === "linux" ? "-glibc" : ""}`,
28
- )
29
- return createWrapper(binding) as typeof import("@parcel/watcher")
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 !== "git") return {}
35
- log.info("init")
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 === "win32") return "windows"
39
- if (process.platform === "darwin") return "fs-events"
40
- if (process.platform === "linux") return "inotify"
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("watcher backend not supported", { platform: process.platform })
44
- return {}
47
+ log.error('watcher backend not supported', {
48
+ platform: process.platform,
49
+ });
50
+ return {};
45
51
  }
46
- log.info("watcher backend", { platform: process.platform, backend })
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("event", evt)
53
- if (evt.type === "create") Bus.publish(Event.Updated, { file: evt.path, event: "add" })
54
- if (evt.type === "update") Bus.publish(Event.Updated, { file: evt.path, event: "change" })
55
- if (evt.type === "delete") Bus.publish(Event.Updated, { file: evt.path, event: "unlink" })
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
@@ -1,6 +1,6 @@
1
1
  // Mock File for MVP
2
2
  export namespace File {
3
3
  export namespace Event {
4
- export const Edited = "file:edited"
4
+ export const Edited = 'file:edited';
5
5
  }
6
6
  }
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["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("OPENCODE_DISABLE_AUTOUPDATE")
7
- export const OPENCODE_DISABLE_PRUNE = truthy("OPENCODE_DISABLE_PRUNE")
8
- export const OPENCODE_ENABLE_EXPERIMENTAL_MODELS = truthy("OPENCODE_ENABLE_EXPERIMENTAL_MODELS")
9
- export const OPENCODE_DISABLE_AUTOCOMPACT = truthy("OPENCODE_DISABLE_AUTOCOMPACT")
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("OPENCODE_EXPERIMENTAL")
13
- export const OPENCODE_EXPERIMENTAL_WATCHER = OPENCODE_EXPERIMENTAL || truthy("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 === "true" || value === "1"
31
+ const value = process.env[key]?.toLowerCase();
32
+ return value === 'true' || value === '1';
18
33
  }
19
34
  }