saeeol 1.2.1 → 1.2.2

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 (113) hide show
  1. package/package.json +11 -11
  2. package/src/cli/cmd/tui/component/dialog/dialog-agent.tsx +32 -0
  3. package/src/cli/cmd/tui/component/dialog/dialog-command.tsx +190 -0
  4. package/src/cli/cmd/tui/component/dialog/dialog-console-org.tsx +103 -0
  5. package/src/cli/cmd/tui/component/dialog/dialog-go-upsell.tsx +159 -0
  6. package/src/cli/cmd/tui/component/dialog/dialog-mcp.tsx +86 -0
  7. package/src/cli/cmd/tui/component/dialog/dialog-model.tsx +238 -0
  8. package/src/cli/cmd/tui/component/dialog/dialog-provider.tsx +343 -0
  9. package/src/cli/cmd/tui/component/dialog/dialog-session-delete-failed.tsx +103 -0
  10. package/src/cli/cmd/tui/component/dialog/dialog-session-list.tsx +301 -0
  11. package/src/cli/cmd/tui/component/dialog/dialog-session-rename.tsx +35 -0
  12. package/src/cli/cmd/tui/component/dialog/dialog-skill.tsx +37 -0
  13. package/src/cli/cmd/tui/component/dialog/dialog-stash.tsx +87 -0
  14. package/src/cli/cmd/tui/component/dialog/dialog-status.tsx +190 -0
  15. package/src/cli/cmd/tui/component/dialog/dialog-tag.tsx +44 -0
  16. package/src/cli/cmd/tui/component/dialog/dialog-theme-list.tsx +50 -0
  17. package/src/cli/cmd/tui/component/dialog/dialog-variant.tsx +39 -0
  18. package/src/cli/cmd/tui/component/dialog/dialog-workspace-create.tsx +200 -0
  19. package/src/cli/cmd/tui/component/dialog/dialog-workspace-unavailable.tsx +81 -0
  20. package/src/cli/cmd/tui/component/dialog-agent.tsx +1 -32
  21. package/src/cli/cmd/tui/component/dialog-command.tsx +1 -190
  22. package/src/cli/cmd/tui/component/dialog-console-org.tsx +1 -103
  23. package/src/cli/cmd/tui/component/dialog-go-upsell.tsx +1 -159
  24. package/src/cli/cmd/tui/component/dialog-mcp.tsx +1 -86
  25. package/src/cli/cmd/tui/component/dialog-model.tsx +1 -238
  26. package/src/cli/cmd/tui/component/dialog-provider.tsx +1 -343
  27. package/src/cli/cmd/tui/component/dialog-session-delete-failed.tsx +1 -103
  28. package/src/cli/cmd/tui/component/dialog-session-list.tsx +1 -301
  29. package/src/cli/cmd/tui/component/dialog-session-rename.tsx +1 -35
  30. package/src/cli/cmd/tui/component/dialog-skill.tsx +1 -37
  31. package/src/cli/cmd/tui/component/dialog-stash.tsx +1 -87
  32. package/src/cli/cmd/tui/component/dialog-status.tsx +1 -190
  33. package/src/cli/cmd/tui/component/dialog-tag.tsx +1 -44
  34. package/src/cli/cmd/tui/component/dialog-theme-list.tsx +1 -50
  35. package/src/cli/cmd/tui/component/dialog-variant.tsx +1 -39
  36. package/src/cli/cmd/tui/component/dialog-workspace-create.tsx +1 -200
  37. package/src/cli/cmd/tui/component/dialog-workspace-unavailable.tsx +1 -81
  38. package/src/tool/apply_patch.ts +1 -334
  39. package/src/tool/bash.ts +1 -656
  40. package/src/tool/core/external-directory.ts +55 -0
  41. package/src/tool/core/invalid.ts +21 -0
  42. package/src/tool/core/recall.ts +164 -0
  43. package/src/tool/core/recall.txt +12 -0
  44. package/src/tool/core/schema.ts +16 -0
  45. package/src/tool/core/tool.ts +162 -0
  46. package/src/tool/core/truncate.ts +160 -0
  47. package/src/tool/core/truncation-dir.ts +4 -0
  48. package/src/tool/diagnostics.ts +1 -20
  49. package/src/tool/edit-replacers.ts +1 -288
  50. package/src/tool/edit-utils.ts +1 -86
  51. package/src/tool/edit.ts +1 -262
  52. package/src/tool/external-directory.ts +1 -55
  53. package/src/tool/file/apply_patch.ts +334 -0
  54. package/src/tool/file/apply_patch.txt +33 -0
  55. package/src/tool/file/bash.ts +656 -0
  56. package/src/tool/file/bash.txt +119 -0
  57. package/src/tool/file/edit-replacers.ts +288 -0
  58. package/src/tool/file/edit-utils.ts +86 -0
  59. package/src/tool/file/edit.ts +262 -0
  60. package/src/tool/file/edit.txt +10 -0
  61. package/src/tool/file/read.ts +389 -0
  62. package/src/tool/file/read.txt +14 -0
  63. package/src/tool/file/write.ts +114 -0
  64. package/src/tool/file/write.txt +8 -0
  65. package/src/tool/glob.ts +1 -115
  66. package/src/tool/grep.ts +1 -151
  67. package/src/tool/integration/diagnostics.ts +20 -0
  68. package/src/tool/integration/lsp.ts +113 -0
  69. package/src/tool/integration/lsp.txt +24 -0
  70. package/src/tool/integration/mcp-exa.ts +73 -0
  71. package/src/tool/integration/package.ts +168 -0
  72. package/src/tool/integration/registry.ts +375 -0
  73. package/src/tool/invalid.ts +1 -21
  74. package/src/tool/lsp.ts +1 -113
  75. package/src/tool/mcp-exa.ts +1 -73
  76. package/src/tool/package.ts +1 -168
  77. package/src/tool/plan.ts +1 -30
  78. package/src/tool/question.ts +1 -52
  79. package/src/tool/read.ts +1 -389
  80. package/src/tool/recall.ts +1 -164
  81. package/src/tool/registry.ts +1 -375
  82. package/src/tool/schema.ts +1 -16
  83. package/src/tool/search/glob.ts +115 -0
  84. package/src/tool/search/glob.txt +6 -0
  85. package/src/tool/search/grep.ts +151 -0
  86. package/src/tool/search/grep.txt +8 -0
  87. package/src/tool/search/warpgrep.ts +107 -0
  88. package/src/tool/search/warpgrep.txt +10 -0
  89. package/src/tool/search/webfetch.ts +202 -0
  90. package/src/tool/search/webfetch.txt +13 -0
  91. package/src/tool/search/websearch.ts +71 -0
  92. package/src/tool/search/websearch.txt +14 -0
  93. package/src/tool/skill.ts +1 -91
  94. package/src/tool/task.ts +1 -197
  95. package/src/tool/todo.ts +1 -62
  96. package/src/tool/tool.ts +1 -162
  97. package/src/tool/truncate.ts +1 -160
  98. package/src/tool/truncation-dir.ts +1 -4
  99. package/src/tool/warpgrep.ts +1 -107
  100. package/src/tool/webfetch.ts +1 -202
  101. package/src/tool/websearch.ts +1 -71
  102. package/src/tool/workflow/plan-enter.txt +14 -0
  103. package/src/tool/workflow/plan-exit.txt +13 -0
  104. package/src/tool/workflow/plan.ts +30 -0
  105. package/src/tool/workflow/question.ts +52 -0
  106. package/src/tool/workflow/question.txt +11 -0
  107. package/src/tool/workflow/skill.ts +91 -0
  108. package/src/tool/workflow/skill.txt +5 -0
  109. package/src/tool/workflow/task.ts +197 -0
  110. package/src/tool/workflow/task.txt +57 -0
  111. package/src/tool/workflow/todo.ts +62 -0
  112. package/src/tool/workflow/todowrite.txt +167 -0
  113. package/src/tool/write.ts +1 -114
@@ -1,73 +1 @@
1
- import { Duration, Effect, Schema } from "effect"
2
- import { HttpClient, HttpClientRequest } from "effect/unstable/http"
3
-
4
- const URL = process.env.EXA_API_KEY
5
- ? `https://mcp.exa.ai/mcp?exaApiKey=${encodeURIComponent(process.env.EXA_API_KEY)}`
6
- : "https://mcp.exa.ai/mcp"
7
-
8
- const McpResult = Schema.Struct({
9
- result: Schema.Struct({
10
- content: Schema.Array(
11
- Schema.Struct({
12
- type: Schema.String,
13
- text: Schema.String,
14
- }),
15
- ),
16
- }),
17
- })
18
-
19
- const decode = Schema.decodeUnknownEffect(Schema.fromJsonString(McpResult))
20
-
21
- const parseSse = Effect.fn("McpExa.parseSse")(function* (body: string) {
22
- for (const line of body.split("\n")) {
23
- if (!line.startsWith("data: ")) continue
24
- const data = yield* decode(line.substring(6))
25
- if (data.result.content[0]?.text) return data.result.content[0].text
26
- }
27
- return undefined
28
- })
29
-
30
- export const SearchArgs = Schema.Struct({
31
- query: Schema.String,
32
- type: Schema.String,
33
- numResults: Schema.Number,
34
- livecrawl: Schema.String,
35
- contextMaxCharacters: Schema.optional(Schema.Number),
36
- })
37
-
38
- const McpRequest = <F extends Schema.Struct.Fields>(args: Schema.Struct<F>) =>
39
- Schema.Struct({
40
- jsonrpc: Schema.Literal("2.0"),
41
- id: Schema.Literal(1),
42
- method: Schema.Literal("tools/call"),
43
- params: Schema.Struct({
44
- name: Schema.String,
45
- arguments: args,
46
- }),
47
- })
48
-
49
- export const call = <F extends Schema.Struct.Fields>(
50
- http: HttpClient.HttpClient,
51
- tool: string,
52
- args: Schema.Struct<F>,
53
- value: Schema.Struct.Type<F>,
54
- timeout: Duration.Input,
55
- ) =>
56
- Effect.gen(function* () {
57
- const request = yield* HttpClientRequest.post(URL).pipe(
58
- HttpClientRequest.accept("application/json, text/event-stream"),
59
- HttpClientRequest.schemaBodyJson(McpRequest(args))({
60
- jsonrpc: "2.0" as const,
61
- id: 1 as const,
62
- method: "tools/call" as const,
63
- params: { name: tool, arguments: value },
64
- }),
65
- )
66
- const response = yield* HttpClient.filterStatusOk(http)
67
- .execute(request)
68
- .pipe(
69
- Effect.timeoutOrElse({ duration: timeout, orElse: () => Effect.die(new Error(`${tool} request timed out`)) }),
70
- )
71
- const body = yield* response.text
72
- return yield* parseSse(body)
73
- })
1
+ export * from "./integration/mcp-exa"
@@ -1,168 +1 @@
1
- import { Effect, Schema } from "effect"
2
- import { Npm } from "@saeeol/core/npm"
3
- import * as Bus from "@/bus"
4
- import * as Tool from "./tool"
5
- import { ProviderInstallEvent } from "@/provider/provider-events"
6
-
7
- const Parameters = Schema.Struct({
8
- action: Schema.Literals(["install", "list"]).annotate({
9
- description: '"install" to install provider packages, "list" to show available providers',
10
- }),
11
- packages: Schema.optional(Schema.Array(Schema.String)).annotate({
12
- description:
13
- 'Package names to install. npm names like "@ai-sdk/anthropic" or short names like "anthropic".',
14
- }),
15
- })
16
-
17
- type Params = Schema.Schema.Type<typeof Parameters>
18
-
19
- const SHORT_NAME_MAP: Record<string, string> = {
20
- anthropic: "@ai-sdk/anthropic",
21
- openai: "@ai-sdk/openai",
22
- "openai-compatible": "@ai-sdk/openai-compatible",
23
- google: "@ai-sdk/google",
24
- "google-vertex": "@ai-sdk/google-vertex",
25
- bedrock: "@ai-sdk/amazon-bedrock",
26
- "amazon-bedrock": "@ai-sdk/amazon-bedrock",
27
- azure: "@ai-sdk/azure",
28
- openrouter: "@openrouter/ai-sdk-provider",
29
- groq: "@ai-sdk/groq",
30
- deepinfra: "@ai-sdk/deepinfra",
31
- gateway: "@ai-sdk/gateway",
32
- alibaba: "@ai-sdk/alibaba",
33
- cerebras: "@ai-sdk/cerebras",
34
- xai: "@ai-sdk/xai",
35
- mistral: "@ai-sdk/mistral",
36
- cohere: "@ai-sdk/cohere",
37
- togetherai: "@ai-sdk/togetherai",
38
- perplexity: "@ai-sdk/perplexity",
39
- vercel: "@ai-sdk/vercel",
40
- gitlab: "gitlab-ai-provider",
41
- venice: "venice-ai-sdk-provider",
42
- }
43
-
44
- const KNOWN_PROVIDERS = [
45
- { npm: "@saeeol/gateway", label: "Saeeol Gateway (bundled)" },
46
- { npm: "@ai-sdk/anthropic", label: "Anthropic (Claude)" },
47
- { npm: "@ai-sdk/openai", label: "OpenAI (GPT)" },
48
- { npm: "@ai-sdk/openai-compatible", label: "OpenAI Compatible" },
49
- { npm: "@ai-sdk/google", label: "Google (Gemini)" },
50
- { npm: "@ai-sdk/github-copilot", label: "GitHub Copilot" },
51
- { npm: "@ai-sdk/amazon-bedrock", label: "Amazon Bedrock" },
52
- { npm: "@ai-sdk/azure", label: "Azure OpenAI" },
53
- { npm: "@ai-sdk/google-vertex", label: "Google Vertex AI" },
54
- { npm: "@openrouter/ai-sdk-provider", label: "OpenRouter" },
55
- { npm: "@ai-sdk/groq", label: "Groq" },
56
- { npm: "@ai-sdk/deepinfra", label: "DeepInfra" },
57
- { npm: "@ai-sdk/gateway", label: "Vercel AI Gateway" },
58
- { npm: "@ai-sdk/alibaba", label: "Alibaba (Qwen)" },
59
- { npm: "@ai-sdk/cerebras", label: "Cerebras" },
60
- { npm: "@ai-sdk/xai", label: "xAI (Grok)" },
61
- { npm: "@ai-sdk/mistral", label: "Mistral" },
62
- { npm: "@ai-sdk/cohere", label: "Cohere" },
63
- { npm: "@ai-sdk/togetherai", label: "Together AI" },
64
- { npm: "@ai-sdk/perplexity", label: "Perplexity" },
65
- { npm: "@ai-sdk/vercel", label: "Vercel" },
66
- ]
67
-
68
- function resolve(pkg: string) {
69
- if (pkg.startsWith("@") || pkg.startsWith("file://")) return pkg
70
- return SHORT_NAME_MAP[pkg] ?? pkg
71
- }
72
-
73
- export const PackageTool = Tool.define(
74
- "package",
75
- Effect.gen(function* () {
76
- return {
77
- description: [
78
- "Manage saeeol provider SDK packages.",
79
- "",
80
- "Use this tool when the user asks to install additional AI providers,",
81
- "or when you detect that a required provider is not available.",
82
- "",
83
- 'Actions: "install" — install provider packages, "list" — show available providers',
84
- "",
85
- "Short names: anthropic, openai, google, bedrock, azure, openrouter, groq,",
86
- "deepinfra, cerebras, xai, mistral, cohere, togetherai, perplexity, vercel",
87
- ].join("\n"),
88
- parameters: Parameters,
89
- execute: (params: Params, ctx: Tool.Context) =>
90
- Effect.gen(function* () {
91
- if (params.action === "list") {
92
- const lines = [
93
- "Available provider SDKs:",
94
- "",
95
- ...KNOWN_PROVIDERS.map((p) => ` ${p.label}\n npm: ${p.npm}`),
96
- "",
97
- 'Install: { action: "install", packages: ["anthropic"] }',
98
- ]
99
- return { title: "Available Providers", output: lines.join("\n"), metadata: {} }
100
- }
101
-
102
- // action === "install"
103
- const packages = params.packages
104
- if (!packages || packages.length === 0) {
105
- return {
106
- title: "Package Install",
107
- output: "No packages specified. Provide package names in the 'packages' array.",
108
- metadata: {},
109
- }
110
- }
111
-
112
- const resolved = packages.map(resolve)
113
-
114
- yield* ctx.ask({
115
- permission: "package",
116
- patterns: resolved,
117
- always: resolved,
118
- metadata: {},
119
- })
120
-
121
- const results: string[] = []
122
- for (const pkg of resolved) {
123
- void Bus.publish(ProviderInstallEvent.Started, {
124
- providerID: pkg,
125
- pkg,
126
- })
127
- try {
128
- const entry = yield* Effect.promise(() => Npm.add(pkg))
129
- if (!entry.entrypoint) {
130
- void Bus.publish(ProviderInstallEvent.Failed, {
131
- providerID: pkg,
132
- pkg,
133
- error: "No import entrypoint found",
134
- })
135
- results.push(`X ${pkg}: no import entrypoint`)
136
- continue
137
- }
138
- void Bus.publish(ProviderInstallEvent.Completed, {
139
- providerID: pkg,
140
- pkg,
141
- })
142
- results.push(`OK ${pkg}`)
143
- } catch (err) {
144
- const msg = err instanceof Error ? err.message : String(err)
145
- void Bus.publish(ProviderInstallEvent.Failed, {
146
- providerID: pkg,
147
- pkg,
148
- error: msg,
149
- })
150
- results.push(`X ${pkg}: ${msg}`)
151
- }
152
- }
153
-
154
- return {
155
- title: "Package Install",
156
- output: [
157
- `${resolved.length} package(s) processed:`,
158
- "",
159
- ...results,
160
- "",
161
- "Installed providers are now available.",
162
- ].join("\n"),
163
- metadata: {},
164
- }
165
- }),
166
- }
167
- }),
168
- )
1
+ export * from "./integration/package"
package/src/tool/plan.ts CHANGED
@@ -1,30 +1 @@
1
- import path from "path"
2
- import { Effect, Schema } from "effect"
3
- import * as Tool from "./tool"
4
- import { Session } from "@/session/session"
5
- import { InstanceState } from "@/effect/instance-state"
6
- import EXIT_DESCRIPTION from "./plan-exit.txt"
7
-
8
- export const Parameters = Schema.Struct({})
9
- export const PlanExitTool = Tool.define(
10
- "plan_exit",
11
- Effect.gen(function* () {
12
- const session = yield* Session.Service
13
-
14
- return {
15
- description: EXIT_DESCRIPTION,
16
- parameters: Parameters,
17
- execute: (_params: {}, ctx: Tool.Context) =>
18
- Effect.gen(function* () {
19
- const instance = yield* InstanceState.context
20
- const info = yield* session.get(ctx.sessionID)
21
- const plan = path.relative(instance.worktree, Session.plan(info, instance))
22
- return {
23
- title: "Planning complete",
24
- output: `Plan is ready at ${plan}. Ending planning turn.`,
25
- metadata: { plan },
26
- }
27
- }).pipe(Effect.orDie),
28
- }
29
- }),
30
- )
1
+ export * from "./workflow/plan"
@@ -1,52 +1 @@
1
- import { Effect, Schema } from "effect"
2
- import { plural } from "@saeeol/boxes/plural"
3
- import * as Tool from "./tool"
4
- import { Question } from "../question"
5
- import DESCRIPTION from "./question.txt"
6
- import { SaeeolQuestionTool } from "@/saeeol/tool/question"
7
-
8
- export const Parameters = Schema.Struct({
9
- questions: Schema.mutable(Schema.Array(Question.Prompt)).annotate({ description: "Questions to ask" }),
10
- })
11
-
12
- type Metadata = {
13
- answers: ReadonlyArray<Question.Answer>
14
- dismissed?: boolean
15
- }
16
-
17
- export const QuestionTool = Tool.define<typeof Parameters, Metadata, Question.Service>(
18
- "question",
19
- Effect.gen(function* () {
20
- const question = yield* Question.Service
21
-
22
- return {
23
- description: DESCRIPTION,
24
- parameters: Parameters,
25
- execute: (params: Schema.Schema.Type<typeof Parameters>, ctx: Tool.Context<Metadata>) =>
26
- Effect.gen(function* () {
27
- // tool result via SaeeolQuestionTool helpers, so Effect.orDie below does not turn
28
- // it into a defect and kill the in-flight stream.
29
- const answers = yield* question
30
- .ask({
31
- sessionID: ctx.sessionID,
32
- questions: params.questions,
33
- tool: ctx.callID ? { messageID: ctx.messageID, callID: ctx.callID } : undefined,
34
- })
35
- .pipe(SaeeolQuestionTool.catchDismissed)
36
- if (SaeeolQuestionTool.isDismissed(answers)) return SaeeolQuestionTool.dismissedResult()
37
-
38
- const formatted = params.questions
39
- .map((q, i) => `"${q.question}"="${answers[i]?.length ? answers[i].join(", ") : "Unanswered"}"`)
40
- .join(", ")
41
-
42
- return {
43
- title: plural(params.questions.length, `Asked {} question`, `Asked {} questions`),
44
- output: `User has answered your questions: ${formatted}. You can now continue with the user's answers in mind.`,
45
- metadata: {
46
- answers,
47
- },
48
- }
49
- }).pipe(Effect.orDie),
50
- }
51
- }),
52
- )
1
+ export * from "./workflow/question"