Dashboard › opencode › Session 1YRc42brQB3D
1YRc42brQB3DFIZ44Perform an independent, read-only adversarial correctness review of the exact frozen Lore V2 port in /home/byk/Code/opencode-lore-v2. Review target: jj change wlpqmtos, commit 52e6687e1eae545273185978c57838d8782e4e92, parent 429114122aa1170fd171aa3f0a2bb97e5a6bd6aa, jj diff --git SHA-256 e58f101082669135fc7f3f11d466c22f696de14270c63747d021efecc8e0bf95. Packed OpenCode tarball SHA-256 911a71125926f8320dc0b0ce719e1506ea40bf6cb57e7ef1e8209cd970615bac; built dist/server.js SHA-256 bbf89f31f76a000d9746733c8ad11a283d5c27fc9368b77ef682ddcf9debb2d2. Do not modify any file, run jj mutations, or use production data/services. Inspect every changed file and exact diff. Focus on legacy compatibility, V2 plugin API correctness, request routing equivalence, streaming Request preservation, exact upstream URL/path handling, original auth preservation, session/parent/provider/project attribution, host-resolved path trust, multi-location isolation, gateway lease reference counting, acquisition/setup/cleanup failure order, idempotence, owned-vs-reused gateway shutdown, package exports/build/tarball behavior, and tests that may pass without proving the real precondition. Confirm hashes before and after review. Use file:line evidence. Classify every material point PASS, CONCERN, or MUST-FIX. End with exactly MERGE or DO-NOT-MERGE. If tooling blocks review, name the exact command/error and end DO-NOT-MERGE. Return a substantive report, never an empty result.
<skill_content name="jj-guide"> # Skill: jj-guide # jj Guide for AI Agents Jujutsu (jj) is a Git-compatible VCS with mutable commits, automatic snapshotting, no staging area, and first-class conflicts. This skill teaches you how to use it safely from a non-interactive agent environment. If `.jj/` exists in the repo root, this is a jj repo. **Use `jj` commands, not `git`.** In a colocated repo (`.jj/` *and* `.git/`), git tools can read the state, but mutations should go through `jj` so the operation log stays consistent. ## Critical Rules - **NEVER** use interactive flags (`-i`, `--interactive`). TUI prompts hang in agent environments. This applies to `jj split -i`, `jj squash -i`, `jj commit -i`, `jj resolve`, `jj diffedit`, etc. - **ALWAYS** pass `-m "msg"` when describing/committing. Without `-m`, an editor opens and hangs. - **VERIFY** mutations with `jj st` and `jj log` after `squash`, `abandon`, `rebase`, `restore`, `commit`. ...
I’ll verify the frozen revision and artifact hashes first, then inspect the full parent-to-target diff, every changed file, relevant call sites, generated/package output, and tests. I’ll use only read-only commands with jj --ignore-working-copy and isolated validation that cannot touch production data or services.
<path>/home/byk/Code/opencode-lore-v2</path> <type>directory</type> <entries> .craft.yml .git .github/ .gitignore .jj/ .lore.md .oxfmtrc.json .oxlintrc.json AGENTS.md CHANGELOG.md codecov.yml LICENSE node_modules/ package.json packages/ patches/ pnpm-lock.yaml pnpm-workspace.yaml quality/ README.md scripts/ stryker.config.mjs supabase/ tsconfig.base.json tsconfig.json vitest.config.ts vitest.evals.config.ts vitest.mutation.config.ts (28 entries) </entries>
<path>/home/byk/Code/opencode-lore-v2/AGENTS.md</path> <type>file</type> <content> 1: <!-- This section is maintained by the coding agent via lore (https://github.com/BYK/loreai) --> 2: ## Long-term Knowledge 3: 4: For long-term knowledge entries managed by [lore](https://github.com/BYK/loreai) (gotchas, patterns, decisions, architecture), see [`.lore.md`](.lore.md) in the project root. 5: <!-- End lore-managed section --> 6: 7: ## Review 8: 9: See [`quality/REVIEW.md`](quality/REVIEW.md) for the review heuristics and workflow — regression-test discipline, adversarial-order state setup, fan-out registry coverage, recurring bug-class batteries, and the two-reviewer rule. Every non-trivial PR requires an adversarial correctness review before merge. 10: 11: # Project Overview 12: 13: Lore is a **three-tier memory architecture** for AI coding agents. ...
<path>/home/byk/Code/opencode-lore-v2/quality/REVIEW.md</path> <type>file</type> <content> 1: # Review Heuristics — Lore 2: 3: This document codifies the review bar for pull requests. It exists because 4: adversarial review has repeatedly caught correctness bugs that a green test 5: suite missed — skip/early-return branches, lifecycle sequences, and fan-out 6: registry gaps. Institutionalizing these patterns so they compound. 7: 8: The review workflow (§6) is referenced from AGENTS.md. 9: 10: --- 11: 12: ## 1. Regression-test discipline 13: 14: Every adversarial-review finding that surfaces a defect **must** land a 15: deterministic regression test in the same PR. The test: 16: - fails on the base branch (proving it reproduces the bug), 17: - passes on the fix (proving the fix works), 18: - drives the *real* precondition, not an artificially-constructed state (e.g. ...
No files found
No files found
/home/byk/Code/opencode-lore-v2 wlpqmtosolpkopymsmpyonmmvoqpzlyx 52e6687e1eae545273185978c57838d8782e4e92 429114122aa1170fd171aa3f0a2bb97e5a6bd6aa e58f101082669135fc7f3f11d466c22f696de14270c63747d021efecc8e0bf95 - bbf89f31f76a000d9746733c8ad11a283d5c27fc9368b77ef682ddcf9debb2d2 packages/opencode/dist/server.js sha256sum: packages/opencode/opencode-ai-opencode-0.22.6.tgz: No such file or directory
/home/byk/Code/opencode/packages/app/vendor/opencode-ai-client-1.17.13-v2.tgz
/tmp/opencode/loreai-opencode-0.40.0.tgz /tmp/opencode/loreai-gateway-0.40.0.tgz /tmp/opencode/loreai-core-0.40.0.tgz
911a71125926f8320dc0b0ce719e1506ea40bf6cb57e7ef1e8209cd970615bac /tmp/opencode/loreai-opencode-0.40.0.tgz M packages/core/src/fetch-interceptor.ts M packages/core/src/index.ts A packages/core/test/fetch-interceptor-request.test.ts M packages/opencode/package.json A packages/opencode/script/build.ts M packages/opencode/src/index.ts M packages/opencode/src/internal.ts A packages/opencode/src/server-core.ts A packages/opencode/src/server-runtime.ts A packages/opencode/src/server.ts M packages/opencode/test/internal.test.ts A packages/opencode/test/package.test.ts A packages/opencode/test/server-runtime.test.ts A packages/opencode/test/server.test.ts M pnpm-lock.yaml packages/core/src/fetch-interceptor.ts | 250 +-- packages/core/src/index.ts | 3 + ...ges/core/test/fetch-interceptor-request.test.ts | 163 ++ packages/opencode/package.json | 17 +- packages/opencode/script/build.ts | 25 ...
diff --git a/packages/core/src/fetch-interceptor.ts b/packages/core/src/fetch-interceptor.ts
index 602362b0f6..f10263cde3 100644
--- a/packages/core/src/fetch-interceptor.ts
+++ b/packages/core/src/fetch-interceptor.ts
@@ -195,6 +195,12 @@
upstreamPath: string;
};
+export type DynamicRequestHeaders = Readonly<Record<string, string>>;
+
+export type DynamicRequestHeadersSource =
+ | DynamicRequestHeaders
+ | (() => DynamicRequestHeaders);
+
/**
* Rewrite an intercepted URL to the gateway, handling both standard /v1/...
* paths and non-standard paths (e.g. /codex/responses). Used by the
@@ -284,17 +290,7 @@
// Never intercept requests already going to the gateway
if (url.startsWith(gatewayBase)) return false;
// Never intercept local requests (could be local LLM or gateway itself)
- const host = parsed.hostname;
- if (
- host === "localhost" ||
- host === "127.0.0.1" ||
- host === "0.0.0.0" ||
- // URL.hostname KEEPS brackets on IPv6 ...
diff --git a/packages/opencode/package.json b/packages/opencode/package.json
index 2dc3111e7d..612407f54f 100644
--- a/packages/opencode/package.json
+++ b/packages/opencode/package.json
@@ -11,14 +11,25 @@
"types": "./src/index.ts",
"bun": "./src/index.ts",
"default": "./src/index.ts"
+ },
+ "./server": {
+ "types": "./src/server.ts",
+ "bun": "./dist/server.js",
+ "default": "./dist/server.js"
}
},
"scripts": {
"typecheck": "tsc --noEmit",
- "build": "echo '@loreai/opencode ships raw TS — no build step needed'"
+ "build": "tsx script/build.ts"
},
"peerDependencies": {
- "@opencode-ai/plugin": ">=1.1.0"
+ "@opencode-ai/plugin": ">=1.1.0",
+ "@opencode/plugin": ">=0.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@opencode/plugin": {
+ "optional": true
+ }
},
"dependencies": {
"@loreai/core": "workspace:*",
@@ -27,10 +38,12 @@
"devDependencies": {
"@opencode-ai/plugin": "^1.1.39",
...
diff --git a/packages/opencode/test/internal.test.ts b/packages/opencode/test/internal.test.ts
index 570ae5a6be..d18e2049ed 100644
--- a/packages/opencode/test/internal.test.ts
+++ b/packages/opencode/test/internal.test.ts
@@ -3,11 +3,21 @@
import { log } from "@loreai/core";
import {
gatewayAccessHeadersForRemote,
+ parseUpstreamExtraHeaders,
shouldForwardUpstreamExtraHeader,
surfaceGatewayUnavailable,
} from "../src/internal";
describe("remote gateway access headers", () => {
+ test("parses empty values and CRLF without changing legacy semantics", () => {
+ expect(
+ parseUpstreamExtraHeaders("x-empty:\r\nx-team: platform\r\ninvalid"),
+ ).toEqual([
+ ["x-empty", ""],
+ ["x-team", "platform"],
+ ]);
+ });
+
const token = "opencode-remote-gateway-token-at-least-32";
test("injects the access token only for the matching LORE_REMOTE_URL", () => {
diff --git a/packages/opencode/test/package.test.ts ...
...output truncated...
Full output saved to: /home/byk/.local/share/opencode/tool-output/tool_086d9a529001mPJ3OxODe1p7FP
@@ -5481,7 +6166,20 @@
'@aws-sdk/middleware-eventstream': 3.972.16
'@aws-sdk/middleware-websocket': 3.972.26
'@aws-sdk/token-providers': 3.1048.0
- '@aws-sdk/types': 3.973.11
+ '@aws-sdk/types': 3.973.13
+ '@smithy/core': 3.24.6
+ '@smithy/fetch-http-handler': 5.4.6
+ '@smithy/node-http-handler': 4.7.7
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/client-cognito-identity@3.1057.0':
+ dependencies:
+ '@aws-crypto/sha256-browser': 5.2.0
+ '@aws-crypto/sha256-js': 5.2.0
+ '@aws-sdk/core': 3.974.18
+ '@aws-sdk/credential-provider-node': 3.972.52
+ '@aws-sdk/types': 3.973.13
'@smithy/core': 3.24.6
'@smithy/fetch-http-handler': 5.4.6
'@smithy/node-http-handler': 4.7.7
@@ -5490,7 +6188,7 @@
'@aws-sdk/core@3.974.18':
dependencies:
- ...
<path>/home/byk/.local/share/opencode/tool-output/tool_086d9a529001mPJ3OxODe1p7FP</path> <type>file</type> <content> 1: diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml 2: index c9b41a1b23..b2983d8ba4 100644 3: --- a/pnpm-lock.yaml 4: +++ b/pnpm-lock.yaml 5: @@ -185,7 +185,7 @@ 6: version: link:../core 7: '@sentry/bun': 8: specifier: ^10.52.0 9: - version: 10.56.0 10: + version: 10.56.0(@opentelemetry/exporter-trace-otlp-http@0.214.0(@opentelemetry/api@1.9.1)) 11: '@types/bun': 12: specifier: ^1.2.0 13: version: 1.3.9 14: @@ -229,6 +229,9 @@ 15: '@opencode-ai/sdk': 16: specifier: ^1.1.39 17: version: 1.2.15 18: + '@opencode/plugin': 19: + specifier: 0.0.0-beta-19378 20: + version: ...
<path>/home/byk/.local/share/opencode/tool-output/tool_086d9a529001mPJ3OxODe1p7FP</path>
<type>file</type>
<content>
1001: + npm-package-arg@13.0.2:
1002: + resolution: {integrity: sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA==}
1003: + engines: {node: ^20.17.0 || >=22.9.0}
1004: +
1005: + npm-packlist@10.0.4:
1006: + resolution: {integrity: sha512-uMW73iajD8hiH4ZBxEV3HC+eTnppIqwakjOYuvgddnalIw2lJguKviK1pcUJDlIWm1wSJkchpDZDSVVsZEYRng==}
1007: + engines: {node: ^20.17.0 || >=22.9.0}
1008: +
1009: + npm-pick-manifest@11.0.3:
1010: + resolution: {integrity: sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==}
1011: + engines: {node: ^20.17.0 || >=22.9.0}
1012: +
1013: + npm-registry-fetch@19.1.1:
1014: + resolution: {integrity: sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw==}
1015: + engines: {node: ^20.17.0 || ...
<path>/home/byk/.local/share/opencode/tool-output/tool_086d9a529001mPJ3OxODe1p7FP</path> <type>file</type> <content> 2001: + '@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.0)': 2002: + dependencies: 2003: + '@opentelemetry/api': 1.9.0 2004: + '@opentelemetry/semantic-conventions': 1.41.1 2005: + 2006: '@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1)': 2007: dependencies: 2008: '@opentelemetry/api': 1.9.1 2009: '@opentelemetry/semantic-conventions': 1.41.1 2010: 2011: + '@opentelemetry/exporter-trace-otlp-http@0.214.0(@opentelemetry/api@1.9.0)': 2012: + dependencies: 2013: + '@opentelemetry/api': 1.9.0 2014: + '@opentelemetry/core': 2.8.0(@opentelemetry/api@1.9.0) 2015: + '@opentelemetry/otlp-exporter-base': 0.214.0(@opentelemetry/api@1.9.0) 2016: + '@opentelemetry/otlp-transformer': 0.214.0(@opentelemetry/api@1.9.0) 2017: + '@opentelemetry/resources': 2.6.1(@opentelemetry/api@1.9.0) 2018: + ...
No files found
File not found: /home/byk/Code/opencode-lore-v2/node_modules/@opencode
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules</path> <type>directory</type> <entries> .bin/ @loreai/ @opencode-ai/ @opencode/ @types/ (5 entries) </entries>
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules/@opencode/plugin</path> <type>directory</type> <entries> dist/ package.json (2 entries) </entries>
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules/@opencode/plugin/dist</path> <type>directory</type> <entries> app.d.ts app.js effect/ host.d.ts host.js options.d.ts options.js promise/ rpc.d.ts rpc.js source.bun.d.ts source.bun.js source.d.ts source.js source.node.d.ts source.node.js storage.d.ts storage.js tui/ worktree.d.ts worktree.js (21 entries) </entries>
No files found
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules/@opencode/plugin/package.json</path>
<type>file</type>
<content>
1: {
2: "$schema": "https://json.schemastore.org/package.json",
3: "name": "@opencode/plugin",
4: "version": "0.0.0-beta-19378",
5: "type": "module",
6: "license": "MIT",
7: "scripts": {
8: "test": "bun test --only-failures",
9: "typecheck": "tsgo --noEmit",
10: "build": "tsc -p tsconfig.build.json"
11: },
12: "exports": {
13: ".": {
14: "import": "./dist/promise/index.js",
15: "types": "./dist/promise/index.d.ts"
16: },
17: "./effect": {
18: "import": "./dist/effect/index.js",
19: "types": "./dist/effect/index.d.ts"
20: },
21: "./host": {
22: "import": "./dist/host.js",
23: "types": "./dist/host.d.ts"
24: },
25: "./tui": {
26: "import": "./dist/tui/index.js",
27: "types": "./dist/tui/index.d.ts"
28: },
29: "./*": {
30: "import": ...
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules/@opencode/plugin/dist/promise</path> <type>directory</type> <entries> adapter.d.ts adapter.js agent.d.ts agent.js aisdk.d.ts aisdk.js catalog.d.ts catalog.js command.d.ts command.js event.d.ts event.js index.d.ts index.js integration.d.ts integration.js mcp.d.ts mcp.js permission.d.ts permission.js plugin.d.ts plugin.js reference.d.ts reference.js registration.d.ts registration.js rpc.d.ts rpc.js session.d.ts session.js shell.d.ts shell.js skill.d.ts skill.js storage.d.ts storage.js tool.d.ts tool.js types.d.ts types.js vcs.d.ts vcs.js websearch.d.ts websearch.js worktree.d.ts worktree.js (46 entries) </entries>
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules/@opencode/plugin/dist/promise/index.d.ts</path>
<type>file</type>
<content>
1: export type { PluginOptions } from "../options.js";
2: export type { StorageEntry, StorageScanOptions, StorageScanResult } from "../storage.js";
3: export * as Plugin from "./plugin.js";
4: export { Agent } from "@opencode/schema/agent";
5: export { Command } from "@opencode/schema/command";
6: export { Connection } from "@opencode/schema/connection";
7: export { Credential } from "@opencode/schema/credential";
8: export { Integration } from "@opencode/schema/integration";
9: export { Location } from "@opencode/schema/location";
10: export { Mcp } from "@opencode/schema/mcp";
11: export { Model } from "@opencode/schema/model";
12: export { PersistentPty } from "@opencode/schema/persistent-pty";
13: export { Provider } from "@opencode/schema/provider";
14: export { Reference } from "@opencode/schema/reference";
15: export { Rpc } from ...
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules/@opencode/plugin/dist/promise/plugin.d.ts</path>
<type>file</type>
<content>
1: import type { OpenCodeClient } from "@opencode/client";
2: import type { GenerateApi, PluginApi } from "@opencode/client/promise/api";
3: import type { Location } from "@opencode/schema/location";
4: import type { PluginOptions } from "../options.js";
5: import type { App } from "../app.js";
6: import type { AgentDomain } from "./agent.js";
7: import type { AISDKDomain } from "./aisdk.js";
8: import type { CatalogDomain } from "./catalog.js";
9: import type { CommandDomain } from "./command.js";
10: import type { EventDomain } from "./event.js";
11: import type { IntegrationDomain } from "./integration.js";
12: import type { MCPDomain } from "./mcp.js";
13: import type { PermissionDomain } from "./permission.js";
14: import type { ReferenceDomain } from "./reference.js";
15: import type { RpcDomain } from "./rpc.js";
16: import type { ...
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules/@opencode/plugin/dist/promise/session.d.ts</path>
<type>file</type>
<content>
1: import type { SessionApi } from "@opencode/client/promise/api";
2: import type { GenerationOptionsFields, Message, SystemPart } from "@opencode/ai";
3: import type { Agent } from "@opencode/schema/agent";
4: import type { Model } from "@opencode/schema/model";
5: import type { PromptInput } from "@opencode/schema/prompt-input";
6: import type { Session } from "@opencode/schema/session";
7: import type { SessionInbox } from "@opencode/schema/session-inbox";
8: import type { SessionError } from "@opencode/schema/session-error";
9: import type { SessionMessage } from "@opencode/schema/session-message";
10: import type { JsonSchema, Types } from "effect";
11: import type { ModelHooks } from "./registration.js";
12: export interface SessionPrompt {
13: readonly sessionID: Session.ID;
14: readonly messageID: SessionMessage.ID;
15: ...
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules/@opencode/plugin/dist/promise/agent.d.ts</path>
<type>file</type>
<content>
1: import type { AgentApi } from "@opencode/client/promise/api";
2: import type { Agent } from "@opencode/schema/agent";
3: import type { Transform } from "./registration.js";
4: import type { DeepMutable } from "./types.js";
5: export interface AgentEditor {
6: list(): readonly DeepMutable<Agent.Info>[];
7: get(id: string): DeepMutable<Agent.Info> | undefined;
8: default(id: string | undefined): void;
9: update(id: string, update: (agent: DeepMutable<Agent.Info>) => void): void;
10: remove(id: string): void;
11: }
12: export interface AgentDomain extends AgentApi {
13: readonly transform: Transform<AgentEditor>;
14: readonly reload: () => Promise<void>;
15: }
(End of file - total 15 lines)
</content>
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules/@opencode/plugin/dist/promise/registration.d.ts</path>
<type>file</type>
<content>
1: export interface Registration {
2: readonly dispose: () => Promise<void>;
3: }
4: export interface ModelHookOptions {
5: /** Limits the hook to one provider. Unscoped hooks apply to every provider. */
6: readonly providerID?: string;
7: }
8: export type Hooks<Spec> = <Name extends keyof Spec>(name: Name, callback: (input: Spec[Name]) => Promise<void> | void) => Promise<Registration>;
9: export type ModelHooks<Spec> = <Name extends keyof Spec>(name: Name, callback: (input: Spec[Name]) => Promise<void> | void, options?: Spec[Name] extends {
10: readonly model: unknown;
11: } ? ModelHookOptions : never) => Promise<Registration>;
12: export type Transform<Input> = (callback: (input: Input) => void) => Promise<Registration>;
(End of file - total 12 lines)
</content>
No files found
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules/@opencode</path> <type>directory</type> <entries> plugin/ (1 entries) </entries>
/home/byk/Code/opencode-lore-v2/node_modules/.pnpm/@opencode+plugin@0.0.0-beta-19378_@opentelemetry+api-logs@0.214.0_@opentelemetry+resour_adca8235564d91579da6ab6087184da7/node_modules/@opencode/plugin /home/byk/Code/opencode-lore-v2/node_modules/.pnpm/@opencode+plugin@0.0.0-beta-19378_@opentelemetry+api-logs@0.214.0_@opentelemetry+resour_adca8235564d91579da6ab6087184da7/node_modules/@opencode/plugin/node_modules/@opencode/schema/dist/location.d.ts
<path>/home/byk/Code/opencode-lore-v2/node_modules/.pnpm/@opencode+plugin@0.0.0-beta-19378_@opentelemetry+api-logs@0.214.0_@opentelemetry+resour_adca8235564d91579da6ab6087184da7/node_modules/@opencode/schema/dist/location.d.ts</path>
<type>file</type>
<content>
1: export * as Location from "./location.js";
2: import { Schema } from "effect";
3: export interface Ref extends Schema.Schema.Type<typeof Ref> {
4: }
5: export declare const Ref: Schema.Struct<{
6: readonly directory: Schema.brand<Schema.String, "AbsolutePath">;
7: readonly workspaceID: Schema.decodeTo<Schema.optional<Schema.toType<Schema.brand<Schema.String, "Workspace.ID"> & {
8: ascending: (id?: string) => string & import("effect/Brand").Brand<"Workspace.ID">;
9: create: () => string & import("effect/Brand").Brand<"Workspace.ID">;
10: }>>, Schema.optionalKey<Schema.brand<Schema.String, "Workspace.ID"> & {
11: ascending: (id?: string) => string & ...
Found 17 matches
/home/byk/Code/opencode/packages/core/test/session-runner.test.ts:
Line 786: yield* agent.transform((editor) =>
Line 807: yield* agent.transform((editor) => {
Line 835: yield* agent.transform((editor) =>
/home/byk/Code/opencode/packages/core/test/agent.test.ts:
Line 28: yield* agent.transform((editor) =>
Line 46: yield* agent.transform((editor) =>
Line 65: yield* agent.transform((editor) => editor.update(id, () => {})).pipe(Scope.provide(scope))
Line 78: yield* agent.transform((editor) =>
Line 94: yield* agent.transform((editor) => editor.update(id, () => {}))
Line 97: yield* agent.transform((editor) => editor.remove(id))
/home/byk/Code/opencode/packages/core/test/config/fixtures/plugin/directory-plugin.ts:
Line 6: await ctx.agent.transform((agents) => {
/home/byk/Code/opencode/packages/core/test/plugin/promise.test.ts:
Line 24: await ctx.agent.transform((draft) => ...
Found 28 matches
/home/byk/Code/opencode/packages/core/test/catalog.test.ts:
Line 177: model.request.body.baseURL = "https://override.example.com"
Line 228: model.request.headers.model = "model"
Line 229: model.request.headers.shared = "model"
Line 230: model.request.body.model = true
Line 231: model.request.body.request = true
Line 232: model.request.body.shared = "model"
Line 237: expect(model.request.headers).toEqual({ provider: "provider", shared: "model", model: "model" })
Line 238: expect(model.request.body).toEqual({ provider: true, model: true, request: true, shared: "model" })
/home/byk/Code/opencode/packages/core/test/config/provider.test.ts:
Line 258: expect(model.request.headers).toEqual({ first: "first", shared: "last", last: "last" })
Line 259: ...
/home/byk/Code/opencode/packages/plugin/src/v2/promise/skill.ts /home/byk/Code/opencode/packages/plugin/src/v2/promise/registration.ts /home/byk/Code/opencode/packages/plugin/src/v2/promise/reference.ts /home/byk/Code/opencode/packages/plugin/src/v2/promise/plugin.ts /home/byk/Code/opencode/packages/plugin/src/v2/promise/integration.ts /home/byk/Code/opencode/packages/plugin/src/v2/promise/index.ts /home/byk/Code/opencode/packages/plugin/src/v2/promise/context.ts /home/byk/Code/opencode/packages/plugin/src/v2/promise/command.ts /home/byk/Code/opencode/packages/plugin/src/v2/promise/catalog.ts /home/byk/Code/opencode/packages/plugin/src/v2/promise/aisdk.ts /home/byk/Code/opencode/packages/plugin/src/v2/promise/agent.ts /home/byk/Code/opencode/packages/plugin/src/v2/options.ts /home/byk/Code/opencode/packages/plugin/src/v2/effect/skill.ts /home/byk/Code/opencode/packages/plugin/src/v2/effect/registration.ts /home/byk/Code/opencode/packages/plugin/src/v2/effect/reference.ts /home/byk/Code...
<path>/home/byk/Code/opencode-lore-v2/packages/core/src/fetch-interceptor.ts</path>
<type>file</type>
<content>
1: /**
2: * Fetch-level interception for transparent LLM API proxy routing.
3: *
4: * Instead of overwriting provider baseURLs early (which loses original auth
5: * and URL context), this interceptor wraps `globalThis.fetch` to redirect
6: * outgoing LLM API calls through the Lore gateway at the HTTP level.
7: *
8: * The SDK builds requests normally (correct auth, correct URL for each
9: * provider), and the interceptor transparently reroutes them through the
10: * gateway while preserving all original headers.
11: */
12: import * as log from "./log";
13:
14: /** Configuration for the fetch interceptor. */
15: export type FetchInterceptorConfig = {
16: /** Base URL of the Lore gateway (e.g., "http://127.0.0.1:3207"). */
17: gatewayBase: string;
18: /**
19: * Dynamic headers to inject on every intercepted request. ...
/home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-request.test.ts /home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-paths.test.ts /home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-install.test.ts /home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-global.test.ts /home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-body.test.ts
<path>/home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-install.test.ts</path>
<type>file</type>
<content>
1: /**
2: * End-to-end tests for installFetchInterceptor.
3: *
4: * These exercise the actual interception flow — URL rewriting, header
5: * injection, X-Lore-Upstream-URL derivation, and the body-shape fallback —
6: * by installing the interceptor over a stubbed originalFetch and asserting
7: * what URL/headers/body the gateway would receive.
8: */
9: import { describe, test, expect, beforeEach, afterEach, vi } from "vitest";
10: import {
11: installFetchInterceptor,
12: interceptUrlForProtocol,
13: } from "../src/fetch-interceptor";
14:
15: const GATEWAY = "http://127.0.0.1:3207";
16:
17: type Captured = { url: string; init: RequestInit | undefined };
18:
19: describe("installFetchInterceptor — end-to-end routing", () => {
20: let cleanup: () => void;
21: let captured: Captured | null;
22: let realFetch: typeof globalThis.fetch;
23: let ...
<path>/home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-body.test.ts</path>
<type>file</type>
<content>
1: /**
2: * Tests for the fetch interceptor's body-shape protocol detection.
3: *
4: * When a URL doesn't match any known LLM API path pattern but the path
5: * looks LLM-like (contains /messages, /chat/completions, or /responses),
6: * the interceptor inspects the request body JSON to detect the protocol
7: * by its unique per-protocol identifiers.
8: */
9: import { describe, test, expect } from "vitest";
10: import {
11: shouldIntercept,
12: detectProtocolFromBody,
13: } from "../src/fetch-interceptor";
14:
15: const GATEWAY = "http://127.0.0.1:3207";
16:
17: describe("detectProtocolFromBody", () => {
18: describe("openai-responses — distinctive markers", () => {
19: test("detects via `input` array", () => {
20: expect(
21: detectProtocolFromBody(JSON.stringify({ model: "gpt-4", input: [] })),
22: ...
<path>/home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-paths.test.ts</path>
<type>file</type>
<content>
1: /**
2: * Tests for the fetch interceptor's LLM API path pattern matching (B3).
3: *
4: * The interceptor transparently reroutes LLM API calls through the Lore
5: * gateway. It needs to recognize the standard LLM API paths plus common
6: * aggregator variants (OpenRouter, etc.) so that X-Lore-* context headers
7: * (project path, git remote, session ID) are injected for all of them.
8: *
9: * These tests are the regression coverage for the broadened pattern list
10: * introduced to address the persistent "lore-config" bug for users whose
11: * providers used a non-standard path prefix.
12: */
13: import { describe, test, expect } from "vitest";
14: import { shouldIntercept } from "../src/fetch-interceptor";
15:
16: const GATEWAY = "http://127.0.0.1:3207";
17:
18: describe("shouldIntercept — LLM API path patterns", () => {
19: describe("Anthropic ...
<path>/home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-global.test.ts</path> <type>file</type> <content> 1: /** 2: * Regression battery for the SHARED original-fetch handle (#1027, #1107). 3: * 4: * The fetch interceptor stores the pre-install `globalThis.fetch` in a 5: * process-global keyed by `Symbol.for(...)`. It backs the cross-copy 6: * double-install guard so that EVERY copy of @loreai/core in the process 7: * agrees a single interceptor is installed — even when core is 8: * bundled/instantiated more than once (e.g. the OpenCode plugin's copy plus a 9: * copy inlined into the in-process gateway bundle). 10: * 11: * Without a shared handle, each module copy keeps a private module-scoped slot: 12: * one copy installs the interceptor (patching `globalThis.fetch`) while a 13: * second copy's guard still sees `null` and installs AGAIN, stacking 14: * interceptors (copy B captures copy A's interceptor as its "original") — an 15: * infinite request ...
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/src/index.ts</path>
<type>file</type>
<content>
1: import type { Hooks, Plugin, PluginInput } from "@opencode-ai/plugin";
2: import {
3: log,
4: getGitRemote,
5: discoverWorkspaceRoot,
6: installFetchInterceptor,
7: } from "@loreai/core";
8: // Helpers live in a separate module so they are NOT re-exported from this
9: // plugin entry. OpenCode's legacy plugin loader invokes every function
10: // exported from the entry module as a plugin; leaking these helpers pushed
11: // `undefined` into the host hooks array and crashed it on event dispatch
12: // (`undefined is not an object (evaluating 'A.event')`). See ./internal.ts.
13: import {
14: applyLoreProviderConfig,
15: gatewayAccessHeadersForRemote,
16: parseUpstreamExtraHeaders,
17: probeGateway,
18: shouldForwardUpstreamExtraHeader,
19: surfaceGatewayUnavailable,
20: } from "./internal";
21:
22: /**
23: * Lore plugin for OpenCode — transparent LLM proxy ...
<path>/home/byk/Code/opencode/packages/core/src/plugin</path> <type>directory</type> <entries> agent.ts command.ts command/ host.ts internal.ts layer-map.example.ts models-dev.ts promise.ts provider.ts provider/ skill.ts skill/ variant.ts (13 entries) </entries>
Found 5 matches
/home/byk/Code/opencode/packages/opencode/src/acp/service.ts:
Line 27: type SetSessionModelRequest,
Line 68: readonly setSessionModel: (input: SetSessionModelRequest) => Effect.Effect<SetSessionModelResponse, Error>
Line 467: const setSessionModel = Effect.fn("ACP.setSessionModel")(function* (params: SetSessionModelRequest) {
/home/byk/Code/opencode/packages/opencode/src/acp/agent.ts:
Line 16: type SetSessionModelRequest,
Line 75: unstable_setSessionModel(params: SetSessionModelRequest) {
No files found
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules/@opencode/plugin/dist/promise/session.js</path> <type>file</type> <content> (End of file - total 0 lines) </content>
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules/@opencode/plugin/dist/host.d.ts</path>
<type>file</type>
<content>
1: export * as Host from "./host.js";
2: export interface Target {
3: readonly directory: string;
4: readonly name?: string;
5: }
6: export interface Entrypoints {
7: readonly server?: string;
8: readonly tui?: string;
9: readonly rpc?: string;
10: }
11: export declare function resolve(target: Target): Entrypoints;
12: export declare function load(entrypoint: string): Promise<unknown>;
(End of file - total 12 lines)
</content>
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules/@opencode/plugin/dist/host.js</path>
<type>file</type>
<content>
1: export * as Host from "./host.js";
2: import path from "node:path";
3: import { importModule, resolveModule } from "@opencode/util/runtime-import";
4: export function resolve(target) {
5: const entry = (subpaths) => {
6: for (const subpath of subpaths) {
7: const specifier = target.name
8: ? [target.name, subpath].filter(Boolean).join("/")
9: : path.resolve(target.directory, subpath || "index");
10: try {
11: return resolveModule(specifier, target.directory);
12: }
13: catch (error) {
14: if (!(error instanceof Error) ||
15: !("code" in error) ||
16: ![
17: "ENOENT",
18: "ENOTDIR",
19: "MODULE_NOT_FOUND",
20: ...
package/LICENSE
package/dist/server.js
package/package.json
package/dist/server.js.map
package/README.md
package/src/index.ts
package/src/internal.ts
package/src/server-core.ts
package/src/server-runtime.ts
package/src/server.ts
{
"name": "@loreai/opencode",
"version": "0.40.0",
"type": "module",
"license": "FSL-1.1-Apache-2.0",
"description": "Three-tier memory architecture for OpenCode — distillation, not summarization",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": {
"types": "./src/index.ts",
"bun": "./src/index.ts",
"default": "./src/index.ts"
},
"./server": {
"types": "./src/server.ts",
"bun": "./dist/server.js",
"default": "./dist/server.js"
}
},
"peerDependencies": {
"@opencode-ai/plugin": ">=1.1.0",
"@opencode/plugin": ">=0.0.0"
},
"peerDependenciesMeta": {
"@opencode/plugin": {
"optional": true
}
},
"dependencies": {
"@loreai/core": "0.40.0",
...
Found 12 matches
/home/byk/Code/opencode-lore-v2/packages/opencode/dist/server.js:
Line 158: silenceStderr: () => silenceStderr,
Line 162: import {
Line 173: } from "node:fs";
Line 174: import { join as join2 } from "node:path";
Line 177: import { existsSync, renameSync } from "node:fs";
Line 178: import { join } from "node:path";
Line 179: import { homedir } from "node:os";
Line 221: function silenceStderr(silenced = true) {
Line 627: import { execSync } from "node:child_process";
Line 694: import * as http from "node:http";
Line 695: import * as https from "node:https";
Line 754: var gatewayPackage = "@loreai/gateway";
<path>/home/byk/Code/opencode-lore-v2/packages/core/src/log.ts</path>
<type>file</type>
<content>
1: /**
2: * Lightweight logger that suppresses informational messages by default.
3: *
4: * In TUI mode, all stderr output renders as red "error" text — confusing
5: * for routine status messages like "incremental distillation" or "pruned
6: * temporal messages". Only actual errors should be visible by default.
7: *
8: * Set LORE_DEBUG=1 to see informational messages (useful when debugging
9: * the plugin itself).
10: *
11: * ## Sink registration
12: *
13: * An optional {@link LogSink} can be registered via {@link registerSink}.
14: * When registered, every log call (regardless of `isDebug`) also forwards
15: * to the sink. This is used by the gateway to bridge logs → Sentry without
16: * adding a Sentry dependency to `@loreai/core`.
17: *
18: * ## File logging
19: *
20: * All log calls (info, warn, error) are written to a persistent log file
21: * at ...
<path>/home/byk/Code/opencode-lore-v2/packages/core/src/log.ts</path>
<type>file</type>
<content>
400: if (!logPathResolved) {
401: logPath = resolveLogPath();
402: logPathResolved = true;
403: }
404: return logPath;
405: }
406:
407: /** Rotate the log file if it exceeds the size cap. */
408: function maybeRotate(): void {
409: if (!logPath) return;
410: let fd: number | undefined;
411: try {
412: // Tighten the active file before it becomes the rotated backup.
413: fd = openLogFileForAppend(logPath);
414: const stat = fstatSync(fd);
415: if (stat.size > LOG_MAX_BYTES) {
416: closeSync(fd);
417: fd = undefined;
418: const backup = `${logPath}.1`;
419: removeExistingRotationBackup(backup);
420: renameSync(logPath, backup);
421: // Another process may have raced the rename. Validate what now occupies
422: // the backup name before leaving it as persistent sensitive data. ...
<path>/home/byk/Code/opencode/packages/plugin/package.json</path>
<type>file</type>
<content>
1: {
2: "$schema": "https://json.schemastore.org/package.json",
3: "name": "@opencode-ai/plugin",
4: "version": "1.18.16",
5: "type": "module",
6: "license": "MIT",
7: "scripts": {
8: "typecheck": "tsgo --noEmit",
9: "build": "tsc"
10: },
11: "exports": {
12: ".": "./src/index.ts",
13: "./tool": "./src/tool.ts",
14: "./tui": "./src/tui.ts",
15: "./v2/effect": "./src/v2/effect/index.ts",
16: "./v2/effect/integration": "./src/v2/effect/integration.ts",
17: "./v2/effect/plugin": "./src/v2/effect/plugin.ts",
18: "./v2/promise": "./src/v2/promise/index.ts"
19: },
20: "files": [
21: "dist"
22: ],
23: "dependencies": {
24: "@ai-sdk/provider": "3.0.8",
25: "@opencode-ai/sdk": "workspace:*",
26: "effect": "catalog:",
27: "zod": "catalog:"
28: },
29: "peerDependencies": {
30: "@opentui/core": ">=0.4.5",
31: ...
<path>/home/byk/Code/opencode/packages/core/src/plugin/internal.ts</path>
<type>file</type>
<content>
1: export * as PluginInternal from "./internal"
2:
3: import { makeLocationNode } from "../effect/app-node"
4: import { httpClient } from "../effect/app-node-platform"
5: import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
6: import { Effect, Layer, Scope } from "effect"
7: import { AgentV2 } from "../agent"
8: import { Catalog } from "../catalog"
9: import { CommandV2 } from "../command"
10: import { Config } from "../config"
11: import { ConfigAgentPlugin } from "../config/plugin/agent"
12: import { ConfigCommandPlugin } from "../config/plugin/command"
13: import { ConfigExternalPlugin } from "../config/plugin/external"
14: import { ConfigProviderPlugin } from "../config/plugin/provider"
15: import { ConfigReferencePlugin } from "../config/plugin/reference"
16: import { ConfigSkillPlugin } from "../config/plugin/skill"
17: import { EventV2 } from "../event"
18: ...
No files found
a55dc8c84a5594da99b2c9dc2ae02198414441f2 2026-09-07 feat(services): organize hosted services and add public files 1382cebe10eda8e5230099e19a0cb76ee2406548 2026-09-07 feat(core): support explicit provider compaction (#47323) 0732cdd8e16fcb0dfaff1d4805483c75f7b79262 2026-09-07 feat(core): persist provider compaction context (#47322) ffac1c5b11729befce8289ec6ce743ca648ac10c 2026-09-03 fix(core): classify GitHub Copilot requests on every route (#47160) 8fc93e6ee4056f04e2d0b102a4abe299f4c18760 2026-09-02 fix(core): preserve session context during compaction (#46751) e76e90b71e0b60a456d436a456754f3519b88001 2026-09-01 refactor(core): decouple plugins from config loading (#46639) 0cdd711abfc4423af1947bc357e69db0115a69f9 2026-08-24 docs: expand plugin guides e68144cb677c1a0137b50a62d7764cfa9adcd76c 2026-08-21 refactor(core): fold single-consumer request modules into model-request (#43958) d19f58c5df0a5362fa1c469c748ac558f79277dd 2026-08-21 fix(core): use small model for titles ...
a5312e169b13c0f08b93c4b6e0c3076c94785aca 2026-09-07 refactor(packages): migrate to the opencode npm scope (#47852)
a55dc8c84a5594da99b2c9dc2ae02198414441f2^:packages/core/src/plugin/provider/azure.ts:179: "http.request",
a55dc8c84a5594da99b2c9dc2ae02198414441f2^:packages/core/src/plugin/provider/github-copilot.ts:255: "model.request",
a55dc8c84a5594da99b2c9dc2ae02198414441f2^:packages/core/src/plugin/provider/github-copilot.ts:270: "http.request",
a55dc8c84a5594da99b2c9dc2ae02198414441f2^:packages/core/src/plugin/provider/openai.ts:295: "model.request",
a55dc8c84a5594da99b2c9dc2ae02198414441f2^:packages/core/src/session/model-request.ts:224: const event = yield* hooks.trigger("session", "model.request", {
a55dc8c84a5594da99b2c9dc2ae02198414441f2^:packages/core/src/session/model-request.ts:249: const before = yield* hooks.trigger("session", "http.request", {
a55dc8c84a5594da99b2c9dc2ae02198414441f2^:packages/core/src/session/model-request.ts:365: (yield* hooks.has("session", "http.request", resolved.ref.providerID)) ...
File not found: /home/byk/Code/opencode/packages/core/src/session/model-request.ts
2cee8cb146d6110fd81c25734238330f2a29cca9 2026-08-12 fix(app): prevent stale WebUI asset loads ad2ad08ec4681c54f4f3a15611f33d7f4095d51d 2026-08-11 feat(server): add Fossilize standalone builds 4f29d6374770440de3ef75fa443aa762244361b2 2026-08-11 feat(app): resizable/collapsible vertical tab rail + review-panel toggle 3278d490ef2721365307a75e876de48715440406 2026-08-11 feat(app): add optional vertical tab rail ced9b253615f74ce7937bad3c49575d9d67da97d 2026-08-11 fix(app): show worktree selector on prod and label session tabs by worktree 735e8a29f10834580f022d317bc15eeb7b03f9cd 2026-08-11 fix(app): suppress reconnect toast flood and mobile bottom-row cutoff 420e42358e7d242f95a8054a5897c2fdefc9b435 2026-08-11 fix(app): faster message loading, subtle sync indicator, stable composer caret c012ae19d34e49e0e69fca66ec4d3762bea518b0 2026-08-11 fix(app): loading indicators and faster return-from-idle recovery 13778f35b916e14895176f300fd64b5884fb7c79 2026-08-11 fix(core): skip file finder init for ...
2ac698d65aa4690a694307e9cbdf44537ea9a4fb 2026-09-07 feat(ai): add Moonshot provider (#47851) c1c6ab593d58477119093b1997c858c2932fa619 2026-09-07 chore: update nix node_modules hashes d1d1c6f890cee88677d81028da6ed5fcc55ee4ce 2026-09-07 feat(release): publish package binaries through Cloudflare 0ab661a9ccdffa939a04bb9734a002919a64dadf 2026-09-07 chore: update nix node_modules hashes a55dc8c84a5594da99b2c9dc2ae02198414441f2 2026-09-07 feat(services): organize hosted services and add public files be41bc4e7de76637f4c7a94d6110637270bfff37 2026-09-07 fix(app): keep tab progress visible on hover (#47835) 567f8b974347f64869d1a43cb0653dd08bef3361 2026-09-07 feat(updates): serve updates under opencode.ai/update (#47858) 6263a35b3fba65736b5c358efd9dbb1b3e14df52 2026-09-07 fix(cli): install only opencode for stable AUR releases (#47857) 74ca560c750b0656374e8d7c1cd11085b7d90ce7 2026-09-07 feat(cli): publish stable releases to opencode-bin on AUR (#47856) a68d6f904d29c9fe91d3fce2086888a9d86b692a ...
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode/plugin",
"version": "1.18.15",
"type": "module",
"license": "MIT",
"scripts": {
"test": "bun test --only-failures",
"typecheck": "tsgo --noEmit",
"build": "tsc -p tsconfig.build.json"
},
"exports": {
".": "./src/promise/index.ts",
"./effect": "./src/effect/index.ts",
"./host": "./src/host.ts",
"./tui": "./src/tui/index.ts",
"./*": "./src/*.ts"
},
"imports": {
"#plugin-source": {
"bun": "./src/source.bun.ts",
"node": "./src/source.node.ts",
"default": "./src/source.node.ts"
}
},
"files": [
"dist"
],
"dependencies": {
"@ai-sdk/provider": "3.0.8",
"@opencode/ai": "workspace:*",
"@opencode/client": "workspace:*",
"@opencode/protocol": "workspace:*",
"@opencode/schema": "workspace:*",
"@opencode/util": "workspace:*",
"@standard-schema/spec": "catalog:",
"effect": "catalog:",
"zod": ...
1 export * as SessionModelRequest from "./model-request.js"
2
3 import { HttpOptions, LanguageModel, LLM, LLMRequest, Message, SystemPart } from "@opencode/ai"
4 import type { StreamOptions } from "@opencode/ai/route"
5 import type { SessionRequestKind } from "@opencode/plugin/effect/session"
6 import type { Agent } from "@opencode/schema/agent"
7 import type { Model } from "@opencode/schema/model"
8 import type { Content } from "@opencode/schema/tool"
9 import { Cause, Config, Context, Effect, Layer, Result, Stream } from "effect"
10 import { HttpClientRequest, HttpClientResponse } from "effect/unstable/http"
11 import { makeLocationNode } from "@opencode/util/effect/app-node"
12 import { App } from "../app.js"
13 import { Permission } from "../permission.js"
14 import { PluginHooks } from "../plugin/hooks.js"
15 import { QuestionTool } from "../tool/plugin/question.js"
16 import { Tool } from "../tool.js"
...
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/src/internal.ts</path> <type>file</type> <content> 1: /** 2: * Internal helpers for the Lore OpenCode plugin. 3: * 4: * These functions are intentionally kept OUT of the plugin entry module 5: * (`./index.ts`). OpenCode's legacy plugin loader treats EVERY function 6: * exported from a plugin module as a plugin instance and invokes it (see 7: * `getServerPlugin`/`getLegacyPlugins` in opencode's plugin loader). Exporting 8: * these helpers from the entry module caused them to be invoked as plugins and 9: * their return values pushed into the host's hooks array: 10: * `applyLoreProviderConfig` returns `undefined`, so the host crashed on the 11: * first hook dispatch with `undefined is not an object (evaluating 'A.event')` 12: * (the `?.` guards the `.event` property, not the `undefined` hook element). ...
<path>/home/byk/Code/opencode-lore-v2/packages/core/src/git.ts</path>
<type>file</type>
<content>
1: /**
2: * git.ts — Git repository identification utilities.
3: *
4: * Extracts and normalizes git remote URLs to identify projects by their
5: * repository identity rather than filesystem path. This enables:
6: * - Worktree awareness: main checkout and worktrees share one project
7: * - Clone deduplication: same repo cloned to different paths is one project
8: * - Fork safety: prefers `origin` over `upstream` so unrelated repos sharing a
9: * common template's upstream are NOT collapsed into one project
10: *
11: * Remote URL normalization strips protocol, auth, and `.git` suffix to produce
12: * a stable canonical identifier (e.g. "github.com/user/repo") regardless of
13: * how the remote was configured (SSH, HTTPS, git://).
14: */
15:
16: import { execSync } from "node:child_process";
17: import { isHostedMode } from "./hosted";
18:
19: // ...
Found 100 matches (more matches available)
/home/byk/Code/opencode-lore-v2/packages/gateway/src/worker-health.ts:
Line 808: * distillation and blocking compaction are intentionally exempt — starving
/home/byk/Code/opencode-lore-v2/packages/gateway/src/ui.ts:
Line 261: * `title` and `value` are escaped. `detailLeftHtml`/`detailRightHtml` accept
Line 265: title: string;
Line 283: <div class="cost-bar-label"><span class="bar-title">${esc(opts.title)}</span><span class="bar-value">${esc(opts.value)}</span></div>
Line 330: if (costs.workers.compaction.cost > 0)
Line 331: overheadParts.push(`compact: ${formatUSD(costs.workers.compaction.cost)}`);
Line 340: title: "Your Spend",
Line 354: title: "Cache Hit Rate",
Line 367: title: "Actual vs Without Lore",
Line 395: `Avoided compactions: ${formatUSD(costs.counterfactual.avoidedCompactionCost)} (×${costs.counterfactual.avoidedCompactions})`,
Line 531: .cost-bar-label ...
Found 5 matches /home/byk/Code/opencode-lore-v2/packages/gateway/src/translate/types.ts: Line 801: "x-lore-agent", /home/byk/Code/opencode-lore-v2/packages/gateway/src/compaction.ts: Line 374: export const LORE_AGENT_HEADER = "x-lore-agent"; Line 378: * When `x-lore-agent` matches, the request is always a normal turn. Line 384: * When `x-lore-agent` matches, the request is always passthrough. Line 434: * 1. Explicit `x-lore-agent` header (OpenCode plugin) — authoritative signal.
<path>/home/byk/Code/opencode-lore-v2/packages/gateway/src/compaction.ts</path>
<type>file</type>
<content>
340: }
341: }
342:
343: return { detected: false };
344: }
345:
346: export function isCompactionRequest(req: GatewayRequest): boolean {
347: return detectCompactionRequest(req).detected;
348: }
349:
350: // ---------------------------------------------------------------------------
351: // extractPreviousSummary
352: // ---------------------------------------------------------------------------
353:
354: /** Regex to extract content from `<previous-summary>` block (dotAll). */
355: const PREVIOUS_SUMMARY_RE = /<previous-summary>\n(.*?)\n<\/previous-summary>/s;
356:
357: /**
358: * Extract the content of a `<previous-summary>` block from the last user
359: * message, or `undefined` if no such block exists. ...
1 export * as SessionTitle from "./title.js"
2
3 import { isDeepStrictEqual } from "node:util"
4 import { LLMClient, LLMEvent, Message, SystemPart } from "@opencode/ai"
5 import type { Agent } from "@opencode/schema/agent"
6 import { Context, DateTime, Effect, Layer, Stream } from "effect"
7 import { Database } from "../database/database.js"
8 import { Bus } from "../bus.js"
9 import { makeLocationNode } from "@opencode/util/effect/app-node"
10 import { isExactRootFallback } from "@opencode/util/session-title-fallback"
11 import { llmClient } from "../effect/app-node-platform.js"
12 import { SessionContext } from "./context.js"
13 import { SessionEvent } from "./event.js"
14 import { SessionHistory } from "./history.js"
15 import type { SessionRunnerModel } from "./runner/model.js"
16 import { SessionSchema } from "./schema.js"
17 import { SessionUsage } from "./usage.js"
18 import { SessionStore } from ...
1 export * as SessionContext from "./context.js"
2
3 import { Model } from "@opencode/schema/model"
4 import { Context, Effect, Layer } from "effect"
5 import { Agent } from "../agent.js"
6 import { Catalog } from "../catalog.js"
7 import { CodeModeInstructions } from "../codemode/instructions.js"
8 import { Database } from "../database/database.js"
9 import { makeLocationNode } from "@opencode/util/effect/app-node"
10 import { InstructionDiscovery } from "../instruction-discovery.js"
11 import { Instructions } from "../instructions/index.js"
12 import { InstructionBuiltIns } from "../instructions/builtins.js"
13 import { Location } from "../location.js"
14 import { McpInstructions } from "../mcp/instructions.js"
15 import { McpTool } from "../tool/mcp.js"
16 import { ReferenceInstructions } from "../reference/instructions.js"
17 import { SkillInstructions } from "../skill/instructions.js"
18 import { ...
Found 47 matches /home/byk/Code/opencode-lore-v2/.github/workflows/docs-deploy.yml: Line 31: # publish lives in the `production` environment, so the job must opt into Line 103: run: pnpm --filter '@loreai/website' publish:standard-site /home/byk/Code/opencode-lore-v2/.github/workflows/ci.yml: Line 9: # packages:write is needed for publish-nightly to push to GHCR Line 52: - '.github/workflows/publish.yml' Line 155: - run: pnpm run build Line 431: run: pnpm run build Line 434: # with `workspaces: true` discovers all four and publishes them in Line 437: # We use `pnpm pack` (not `npm pack`) because pnpm automatically rewrites Line 439: # `npm pack` leaves the literal "workspace:*" in the tarball's Line 444: # names are published in parallel so existing users keep working. Line 451: (cd "$pkg" && pnpm pack --pack-destination ../../dist-tarballs) Line 824: # Nightly: build all ...
<path>/home/byk/Code/opencode-lore-v2/.github/workflows/ci.yml</path>
<type>file</type>
<content>
400: with:
401: name: lore-linux-x64
402: path: packages/gateway/dist-bin/lore-linux-x64
403:
404: # Prepare platform-independent staging dir for cross-platform builds.
405: # The linux-x64 build above already ran esbuild and populated
406: # .sea-staging/, but we run --prepare-only explicitly to make the
407: # intent clear and ensure the staging dir is complete for darwin-arm64.
408: - name: Prepare staging for cross-platform builds
409: if: github.ref == 'refs/heads/main' && github.event_name == 'push'
410: run: |
411: pnpm --filter @loreai/gateway run build:binary:sea \
412: --platforms darwin-arm64 --prepare-only
413: env:
414: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
415: FOSSILIZE_CACHE_DIR: ${{ github.workspace }}/.node-cache
416:
417: - ...
node:internal/modules/cjs/loader:1503
throw err;
^
Error: Cannot find module 'semver'
Require stack:
- /home/byk/Code/opencode-lore-v2/[eval]
at Module._resolveFilename (node:internal/modules/cjs/loader:1500:15)
at wrapResolveFilename (node:internal/modules/cjs/loader:1071:27)
at defaultResolveImplForCJSLoading (node:internal/modules/cjs/loader:1095:10)
at resolveForCJSWithHooks (node:internal/modules/cjs/loader:1116:12)
at Module._load (node:internal/modules/cjs/loader:1285:25)
at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)
at Module.require (node:internal/modules/cjs/loader:1600:12)
at require (node:internal/modules/helpers:153:16)
at [eval]:1:14
at runScriptInThisContext (node:internal/vm:219:10) {
code: 'MODULE_NOT_FOUND',
requireStack: [ '/home/byk/Code/opencode-lore-v2/[eval]' ]
}
Node.js v24.16.0
No files found
Found 2 matches /home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/start.ts: Line 868: export async function startGateway( Line 877: async function startGatewayLocked(
<path>/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/start.ts</path>
<type>file</type>
<content>
800: `Gateway did not establish authenticated ownership within ${timeout}ms; background pid ${pid}'s spawned process generation is no longer running. Check the log: ${daemonLogPath()}`,
801: );
802: } else {
803: io.logError(
804: `Gateway startup failed with unknown child state: background pid ${pid} did not establish authenticated ownership and could not be confirmed stopped. Check the log and process before retrying: ${daemonLogPath()}`,
805: );
806: }
807: return 1;
808: }
809:
810: /** Spawn the detached child gateway with stdio redirected to the log file. ...
Found 15 matches
/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/start.ts:
Line 105: processBoundary?: boolean;
Line 116: shutdown: () => Promise<void>;
Line 984: shutdown: async () => {},
Line 1012: shutdown: async () => {},
Line 1214: const processShutdown = opts.processBoundary
Line 1270: shutdown: async () => {},
Line 1312: processBoundary: true,
/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/shutdown.ts:
Line 56: shutdown: () => Promise<void>,
Line 82: console.error("[lore] Error during shutdown:", e);
Line 126: shutdown: () => Promise<void>,
Line 293: shutdown: () => Promise<void>,
Line 310: shutdown: () => Promise<void>,
/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/run.ts:
Line 405: let shutdown: () => Promise<void>;
Line 488: processBoundary: true,
/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/invariant-check.ts:
...
<path>/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/start.ts</path>
<type>file</type>
<content>
1180: }
1181: try {
1182: shutdownLock.assertOwned();
1183: closeDb();
1184: } catch (error) {
1185: // SQLite recovery handles a failed best-effort checkpoint. Keep
1186: // the established current-main behavior: warn but do not wedge
1187: // shutdown or retain an otherwise-stale process record for it.
1188: notify(
1189: `Database close warning: ${error instanceof Error ? error.message : String(error)}`,
1190: );
1191: }
1192:
1193: if (shutdownError) throw shutdownError;
1194:
1195: // Discovery is removed only after listener and worker teardown.
1196: shutdownLock.assertOwned();
1197: io.removePort(actualPort, controlToken);
1198: const current = ...
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/config/plugin/source.ts:165: ? yield* Effect.sync(() => Host.resolve({ directory: operation.target }))
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/module.ts:68: setup: Schema.declare<Parameters<typeof PluginPromise.fromPromise>[0]["setup"]>(
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/module.ts:97: : yield* Effect.sync(() => Host.resolve(installed ?? { directory: operation.target }))
1 export * as PluginModule from "./module.js"
2
3 import type { Plugin } from "@opencode/plugin/effect/plugin"
4 import { Host } from "@opencode/plugin/host"
5 import { createPluginSources } from "@opencode/plugin/source"
6 import { Npm } from "@opencode/util/npm"
7 import { Deferred, Effect, FiberSet, PubSub, Schema, Stream } from "effect"
8 import path from "path"
9 import { stat } from "node:fs/promises"
10 import { fileURLToPath, pathToFileURL } from "url"
11 import type { ConfigPluginSource } from "../config/plugin/source.js"
12 import type { Generation } from "../plugin.js"
13 import { PluginPromise } from "./promise.js"
14 import { Watcher } from "../filesystem/watcher.js"
15
16 export const make = Effect.fn("PluginModule.make")(function* () {
17 const watcher = yield* Watcher.Service
18 const scope = yield* Effect.scope
19 const runPromise = yield* FiberSet.makeRuntimePromise()
20 ...
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules/@opencode/plugin/dist/promise/adapter.js</path>
<type>file</type>
<content>
1: import { Tool } from "@opencode/schema/tool";
2: import { Effect, Schema, SchemaAST, Stream } from "effect";
3: import { HttpApiEndpoint, HttpApiSchema } from "effect/unstable/httpapi";
4: import { define } from "../effect/plugin.js";
5: const compiledEndpoints = new WeakMap();
6: const JsonInput = Schema.fromJsonString(Schema.Unknown);
7: class ReturnedRpcError extends Error {
8: type;
9: data;
10: constructor(type, message, data) {
11: super(message);
12: this.type = type;
13: this.data = data;
14: }
15: }
16: const makeStreams = Effect.fn("Plugin.Event.makeStreams")(function* () {
17: const context = yield* Effect.context();
18: const subscriptions = new Set();
19: // Async iterators own separate scopes, so close them when the plugin unloads.
20: yield* Effect.addFinalizer(() => ...
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/plugin/src/effect/registration.ts:3:export interface Registration {
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/plugin/src/effect/registration.ts:4: readonly dispose: Effect.Effect<void>
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/plugin/src/promise/adapter.ts:12:type HostRegistration = { readonly dispose: Effect.Effect<void> }
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/plugin/src/promise/adapter.ts:13:type Registration = { readonly dispose: () => Promise<void> }
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/plugin/src/promise/adapter.ts:153: dispose: () => run(registration.dispose),
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/plugin/src/promise/adapter.ts:244: dispose: () => Effect.runPromiseWith(context)(registration.dispose),
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/plugin/src/promise/registration.ts:1:export interface Registration ...
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/hooks.ts:9:import { Context, Effect, Layer, Scope } from "effect"
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/hooks.ts:53: ) => Effect.Effect<State.Registration, never, Scope.Scope>
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/hooks.ts:71: const scope = yield* Scope.Scope
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/hooks.ts:83: yield* Scope.addFinalizer(scope, dispose)
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/provider/azure.ts:16:const cognitiveScope = "https://cognitiveservices.azure.com/.default"
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/provider/azure.ts:17:const foundryScope = "https://ai.azure.com/.default"
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/provider/azure.ts:106: const current = yield* ...
1 export * as PluginHooks from "./hooks.js"
2
3 import type { AISDKHooks } from "@opencode/plugin/effect/aisdk"
4 import type { SessionHooks } from "@opencode/plugin/effect/session"
5 import type { ShellHooks } from "@opencode/plugin/effect/shell"
6 import type { ToolFailures, ToolHooks } from "@opencode/plugin/effect/tool"
7 import type { ModelHookOptions } from "@opencode/plugin/effect/registration"
8 import type { PermissionHooks } from "@opencode/plugin/effect/permission"
9 import { Context, Effect, Layer, Scope } from "effect"
10 import { makeLocationNode } from "@opencode/util/effect/app-node"
11 import { State } from "../state.js"
12
13 export interface Domains {
14 readonly aisdk: AISDKHooks
15 readonly session: SessionHooks
16 readonly permission: PermissionHooks
17 readonly shell: ShellHooks
18 readonly tool: ToolHooks
19 }
20
21 type NoFailures<Spec> = { readonly [Name ...
1 export * as State from "./state.js"
2
3 import { Cause, Context, Effect, Exit, Fiber, Scope } from "effect"
4
5 /**
6 * A synchronous, replayable edit to the current domain state.
7 *
8 * Domain editors expose readable and writable state while preserving concise
9 * plugin/config code. Transforms synchronously rebuild derived state.
10 */
11 type TransformCallback<Editor> = (editor: Editor) => void
12 export type MakeEditor<State, Editor> = (state: State) => Editor
13
14 export interface Registration {
15 readonly dispose: Effect.Effect<void>
16 }
17
18 /**
19 * Registers a scoped transform. Reads rebuild by applying every registered transform in order.
20 * Closing the owning Scope removes the transform and invalidates the current value.
21 */
22 export type Transform<Editor> = (
23 transform: TransformCallback<Editor>,
24 ) => Effect.Effect<Registration, never, ...
1 export * as Agent from "./agent.js"
2
3 import { Schema } from "effect"
4 import { ephemeral, inventory } from "./event.js"
5 import { optional } from "./schema.js"
6 import { Model } from "./model.js"
7 import { Permission } from "./permission.js"
8 import { Provider } from "./provider.js"
9 import { PositiveInt, statics } from "./schema.js"
10
11 const Updated = ephemeral({ type: "agent.updated", schema: {} })
12
13 export const ID = Schema.String.pipe(Schema.brand("Agent.ID"))
14 export type ID = typeof ID.Type
15
16 export const Name = Schema.String.pipe(Schema.brand("Agent.Name"))
17 export type Name = typeof Name.Type
18
19 export const Color = Schema.String.annotate({ identifier: "Agent.Color" })
20 export type Color = typeof Color.Type
21
22 export interface Info extends Schema.Schema.Type<typeof Info> {}
23 export const Info = Schema.Struct({
24 id: ID,
25 ...
1 export * as ConfigAgentPlugin from "./agent.js"
2
3 import { define } from "@opencode/plugin/effect/plugin"
4 import { Document, Info, type Entry } from "@opencode/schema/config"
5 import { ConfigAgent } from "@opencode/schema/config/agent"
6 import path from "path"
7 import { Effect, Option, PubSub, Schema, Stream } from "effect"
8 import { Agent } from "../../agent.js"
9 import { Config } from "../../config.js"
10 import { ConfigMarkdown } from "../markdown.js"
11 import { FSUtil } from "@opencode/util/fs-util"
12 import { ConfigAgentV1 } from "../../v1/config/agent.js"
13 import { ConfigMigrateV1 } from "../../v1/config/migrate.js"
14 import { Global } from "@opencode/util/global"
15 import { Permission } from "../../permission.js"
16 import type { FileAccess } from "../../file-access.js"
17 import type { ReadTool } from "../../tool/plugin/read.js"
18 import type { EditTool } from ...
429114122aa1170fd171aa3f0a2bb97e5a6bd6aa:packages/opencode/src/index.ts:351: "lore-distill": {
429114122aa1170fd171aa3f0a2bb97e5a6bd6aa:packages/opencode/src/index.ts:356: "lore-curator": {
429114122aa1170fd171aa3f0a2bb97e5a6bd6aa:packages/opencode/src/index.ts:361: "lore-query-expand": {
1 import type { SessionApi } from "@opencode/client/promise/api"
2 import type { GenerationOptionsFields, Message, SystemPart } from "@opencode/ai"
3 import type { Agent } from "@opencode/schema/agent"
4 import type { Model } from "@opencode/schema/model"
5 import type { PromptInput } from "@opencode/schema/prompt-input"
6 import type { Session } from "@opencode/schema/session"
7 import type { SessionInbox } from "@opencode/schema/session-inbox"
8 import type { SessionError } from "@opencode/schema/session-error"
9 import type { SessionMessage } from "@opencode/schema/session-message"
10 import type { JsonSchema, Types } from "effect"
11 import type { ModelHooks } from "./registration.js"
12
13 export interface SessionPrompt {
14 readonly sessionID: Session.ID
15 readonly messageID: SessionMessage.ID
16 prompt: Types.DeepMutable<PromptInput.Prompt>
17 metadata?: Record<string, unknown>
18 ...
fatal: path 'packages/client/src/promise/api/session.ts' does not exist in '2ac698d65aa4690a694307e9cbdf44537ea9a4fb'
packages/client/src/promise/api.ts packages/client/src/promise/generated/.httpapi-codegen.json
1 import type { OpenCode } from "./client.js"
2
3 type Client = ReturnType<typeof OpenCode.make>
4
5 export type { RpcApi, RpcCallOptions, RpcClient, RpcEventPayload } from "./rpc.js"
6
7 export type AgentApi = Client["agent"]
8 export type CommandApi = Client["command"]
9 export type ConfigApi = Client["config"]
10 export type EventApi = Client["event"]
11 export type GenerateApi = Client["generate"]
12 export type IntegrationApi = Client["integration"]
13 export type McpApi = Client["mcp"]
14 export type ModelApi = Client["model"]
15 export type PluginApi = Client["plugin"]
16 export type PermissionApi = Client["permission"]
17 export type ProviderApi = Client["provider"]
18 export type ReferenceApi = Client["reference"]
19 export type WebSearchApi = Client["websearch"]
20 export type SessionApi = Client["session"]
21 export type SkillApi = Client["skill"]
22 export type VcsApi = ...
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/protocol/src/groups/session.ts:232: HttpApiEndpoint.get("session.get", "/api/session/:sessionID", {
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/protocol/src/groups/session.ts:238: identifier: "v2.session.get",
1 import { SessionMessage } from "@opencode/schema/session-message"
2 import { SessionTransfer } from "@opencode/schema/session-transfer"
3 import { SessionInbox } from "@opencode/schema/session-inbox"
4 import { PromptInput } from "@opencode/schema/prompt-input"
5 import { Session } from "@opencode/schema/session"
6 import { SessionStats } from "@opencode/schema/session-stats"
7 import { InstructionEntry } from "@opencode/schema/instruction-entry"
8 import { Project } from "@opencode/schema/project"
9 import { AbsolutePath, NonNegativeInt, PositiveInt, RelativePath, statics } from "@opencode/schema/schema"
10 import { Event } from "@opencode/schema/event"
11 import { Workspace } from "@opencode/schema/workspace"
12 import { Context, Effect, Encoding, Result, Schema, SchemaGetter, Struct } from "effect"
13 import { HttpApiEndpoint, HttpApiGroup, HttpApiMiddleware, HttpApiSchema, OpenApi } from "effect/unstable/httpapi"
...
1 export * as Location from "./location.js"
2
3 import { Schema } from "effect"
4 import { AbsolutePath, optional } from "./schema.js"
5 import { ProjectID } from "./project-id.js"
6 import { WorkspaceID } from "./workspace-id.js"
7
8 export interface Ref extends Schema.Schema.Type<typeof Ref> {}
9 export const Ref = Schema.Struct({
10 directory: AbsolutePath,
11 workspaceID: optional(WorkspaceID),
12 }).annotate({ identifier: "Location.Ref" })
13
14 export class Info extends Schema.Class<Info>("Location.Info")({
15 directory: AbsolutePath,
16 workspaceID: optional(WorkspaceID),
17 project: Schema.Struct({
18 id: ProjectID,
19 directory: AbsolutePath,
20 canonical: AbsolutePath,
21 }),
22 }) {}
23
24 export function response<S extends Schema.Top>(data: S) {
25 return Schema.Struct({ location: Info, data })
26 }
1 export * as Session from ...
Working copy changes: M packages/core/src/fetch-interceptor.ts M packages/core/src/index.ts A packages/core/test/fetch-interceptor-request.test.ts M packages/opencode/package.json A packages/opencode/script/build.ts M packages/opencode/src/index.ts M packages/opencode/src/internal.ts A packages/opencode/src/server-core.ts A packages/opencode/src/server-runtime.ts A packages/opencode/src/server.ts M packages/opencode/test/internal.test.ts A packages/opencode/test/package.test.ts A packages/opencode/test/server-runtime.test.ts A packages/opencode/test/server.test.ts M pnpm-lock.yaml Working copy (@) : wlpqmtos 52e6687e lore-v2-plugin | feat(opencode): add V2 server plugin Parent commit (@-): uutomtup 42911412 main | fix(gateway): preserve large recall continuations (#1730) wlpqmtosolpkopymsmpyonmmvoqpzlyx 52e6687e1eae545273185978c57838d8782e4e92 feat(opencode): add V2 server plugin uutomtupslqmmvuzknuurlrokzlrruuv 429114122aa1170fd171aa3f0a2bb97e5a6bd6aa fix(gateway): preserve large ...
<path>/home/byk/Code/opencode-lore-v2/package.json</path>
<type>file</type>
<content>
1: {
2: "name": "lore-monorepo",
3: "private": true,
4: "type": "module",
5: "license": "FSL-1.1-Apache-2.0",
6: "description": "Monorepo root for Lore — three-tier memory architecture",
7: "main": "./packages/opencode/src/index.ts",
8: "exports": {
9: ".": "./packages/opencode/src/index.ts"
10: },
11: "packageManager": "pnpm@10.28.0",
12: "volta": {
13: "node": "24.16.0",
14: "pnpm": "10.28.0"
15: },
16: "pnpm": {
17: "onlyBuiltDependencies": [
18: "esbuild",
19: "onnxruntime-node",
20: "sharp"
21: ],
22: "overrides": {
23: "basic-ftp": "5.3.1",
24: "ip-address": "10.2.0",
25: "fast-xml-parser": "5.7.3",
26: "@huggingface/hub": "2.11.0",
27: "onnxruntime-node": "1.27.0",
28: "yaml": ">=2.8.3",
29: "esbuild": ">=0.28.1",
30: "@opentelemetry/core": ">=2.8.0",
31: "protobufjs": ...
<path>/home/byk/Code/opencode-lore-v2/packages/core/src/fetch-interceptor.ts</path>
<type>file</type>
<content>
1: /**
2: * Fetch-level interception for transparent LLM API proxy routing.
3: *
4: * Instead of overwriting provider baseURLs early (which loses original auth
5: * and URL context), this interceptor wraps `globalThis.fetch` to redirect
6: * outgoing LLM API calls through the Lore gateway at the HTTP level.
7: *
8: * The SDK builds requests normally (correct auth, correct URL for each
9: * provider), and the interceptor transparently reroutes them through the
10: * gateway while preserving all original headers.
11: */
12: import * as log from "./log";
13:
14: /** Configuration for the fetch interceptor. */
15: export type FetchInterceptorConfig = {
16: /** Base URL of the Lore gateway (e.g., "http://127.0.0.1:3207"). */
17: gatewayBase: string;
18: /**
19: * Dynamic headers to inject on every intercepted request. ...
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/src/server.ts</path>
<type>file</type>
<content>
1: import { rewriteRequest } from "@loreai/core";
2: import type { Plugin } from "@opencode/plugin";
3: import { acquireServerRuntime, buildServerHeaders } from "./server-runtime";
4:
5: const workers = [
6: ["lore-distill", "Lore memory distillation worker"],
7: ["lore-curator", "Lore knowledge curator worker"],
8: ["lore-query-expand", "Lore query expansion worker"],
9: ] as const;
10:
11: export default {
12: id: "lore",
13: setup: async (ctx) => {
14: const runtime = await acquireServerRuntime(ctx.location.project.directory);
15: if (!runtime) return;
16:
17: const registrations: Array<{ dispose: () => Promise<void> }> = [];
18: try {
19: registrations.push(
20: await ctx.agent.transform((editor) => {
21: for (const [id, description] of workers) {
22: editor.update(id, (agent) => {
23: ...
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/src/server-runtime.ts</path>
<type>file</type>
<content>
1: import { getGitRemote, log } from "@loreai/core";
2: import {
3: gatewayAccessHeadersForRemote,
4: parseUpstreamExtraHeaders,
5: probeGateway,
6: shouldForwardUpstreamExtraHeader,
7: } from "./internal";
8:
9: const gatewayPackage = "@loreai/gateway";
10: const knownGatewayPorts = [3207, 5673];
11:
12: export interface LoreServerRuntime {
13: gatewayBase: string;
14: projectPath: string;
15: gitRemote: string;
16: gatewayHeaders: Record<string, string>;
17: release: () => Promise<void>;
18: }
19:
20: export interface ServerRuntimeDependencies {
21: resolveGateway?: () => Promise<{
22: gatewayBase: string;
23: gatewayHeaders: Record<string, string>;
24: shutdown?: () => Promise<void>;
25: }>;
26: gitRemote?: (path: string) => string | null;
27: }
28:
29: interface GatewayHandle {
30: port: number;
31: owned: boolean;
32: ...
1 import type { AgentApi } from "@opencode/client/promise/api"
2 import type { Agent } from "@opencode/schema/agent"
3 import type { Transform } from "./registration.js"
4 import type { DeepMutable } from "./types.js"
5
6 export interface AgentEditor {
7 list(): readonly DeepMutable<Agent.Info>[]
8 get(id: string): DeepMutable<Agent.Info> | undefined
9 default(id: string | undefined): void
10 update(id: string, update: (agent: DeepMutable<Agent.Info>) => void): void
11 remove(id: string): void
12 }
13
14 export interface AgentDomain extends AgentApi {
15 readonly transform: Transform<AgentEditor>
16 readonly reload: () => Promise<void>
17 }
1 export interface Registration {
2 readonly dispose: () => Promise<void>
3 }
4
5 export interface ModelHookOptions {
6 /** Limits the hook to one provider. Unscoped hooks apply to every provider. ...
Found 40 matches
/home/byk/Code/opencode-lore-v2/packages/opencode/test/index.test.ts:
Line 50: cleanup: () => rmSync(tmpDir, { recursive: true, force: true }),
Line 56: const { hooks, cleanup } = await initPlugin();
Line 63: cleanup();
Line 68: const { hooks, cleanup } = await initPlugin();
Line 105: cleanup();
Line 110: const { hooks, cleanup } = await initPlugin();
Line 124: cleanup();
Line 254: const { hooks, cleanup } = await initPlugin();
Line 258: cleanup();
Line 263: const { hooks, cleanup } = await initPlugin();
Line 273: cleanup();
/home/byk/Code/opencode-lore-v2/packages/opencode/test/session-state.test.ts:
Line 105: // best-effort cleanup
/home/byk/Code/opencode-lore-v2/packages/opencode/test/gateway-smoke.test.ts:
Line 8: * the plugin's startInProcess delegates to). Tests use ephemeral ports so
Line 19: // Track shutdown handles to clean up after tests. ...
packages/core/src/fetch-interceptor.ts | 250 +-- packages/core/src/index.ts | 3 + .../core/test/fetch-interceptor-request.test.ts | 163 ++ packages/opencode/package.json | 17 +- packages/opencode/script/build.ts | 25 + packages/opencode/src/index.ts | 22 +- packages/opencode/src/internal.ts | 13 + packages/opencode/src/server-core.ts | 4 + packages/opencode/src/server-runtime.ts | 222 +++ packages/opencode/src/server.ts | 79 + packages/opencode/test/internal.test.ts | 10 + packages/opencode/test/package.test.ts | 62 + packages/opencode/test/server-runtime.test.ts | 159 ++ packages/opencode/test/server.test.ts | 316 ++++ pnpm-lock.yaml | 1775 +++++++++++++++++++- 15 files changed, 2914 insertions(+), 206 ...
<path>/home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-request.test.ts</path>
<type>file</type>
<content>
1: import { describe, expect, test, vi } from "vitest";
2: import { rewriteRequest } from "../src/fetch-interceptor";
3:
4: const GATEWAY = "https://gateway.example.com";
5: const dynamicHeaders = {
6: "x-lore-project": "/home/me/project",
7: "x-lore-session-id": "session-123",
8: };
9:
10: describe("rewriteRequest", () => {
11: test("routes a V2-style Request without losing method, body, auth, path, or query", async () => {
12: const body = JSON.stringify({
13: model: "gpt-5",
14: messages: [{ role: "user", content: "Hello" }],
15: });
16: const observed = vi.fn();
17: const request = new Request(
18: "https://openrouter.ai/api/v1/chat/completions?stream=true&trace=abc",
19: {
20: method: "POST",
21: headers: {
22: authorization: "Bearer sk-test",
23: "content-type": ...
Found 28 matches
/home/byk/Code/opencode-lore-v2/packages/gateway/src/config.ts:
Line 567: const raw = headers["x-lore-upstream-url"];
Line 712: const raw = headers["x-lore-upstream-path"];
Line 732: * Returns `origin(effectiveUpstreamBase) + upstreamPath` (the client's original
Line 737: * - `upstreamPath` is present — the interceptor preserved the endpoint;
Line 751: upstreamPath: string | undefined;
Line 769: upstreamPath,
Line 773: if (!headerUpstream || !upstreamPath) return reconstructedUrl;
Line 782: return new URL(effectiveUpstreamBase).origin + upstreamPath;
Line 1017: * the same way an incoming `x-lore-upstream-url` header is — the normalization
Line 1033: const norm = extractUpstreamUrlHeader({ "x-lore-upstream-url": route.url });
Line 1040: * Derive the provider id from a request's `x-lore-upstream-url` header by
Line 1066: * incoming `x-lore-upstream-url` header is and matching against PROVIDER_ROUTES. ...
<path>/home/byk/Code/opencode-lore-v2/packages/gateway/src/config.ts</path>
<type>file</type>
<content>
540: config: Pick<GatewayConfig, "remoteGateway" | "hostedMode"> &
541: Partial<Pick<GatewayConfig, "callerUpstreamAllowlist">>,
542: upstreamUrl: string,
543: ): boolean {
544: if (!config.remoteGateway && !config.hostedMode) return true;
545: try {
546: const parsed = new URL(upstreamUrl);
547: if (parsed.protocol !== "https:") return false;
548: return (config.callerUpstreamAllowlist ?? []).includes(parsed.origin);
549: } catch {
550: return false;
551: }
552: }
553:
554: /**
555: * Extract and validate the `X-Lore-Upstream-URL` header from a request.
556: *
557: * Used by local/custom providers (vllm, llama.cpp, ollama, etc.) to tell the
558: * gateway where to forward the request when `resolveUpstreamRoute()` returns
559: * null. ...
<path>/home/byk/Code/opencode-lore-v2/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
6170: const sessionID = generateSessionID();
6171: return { sessionID, isNew: true, tier: 3 };
6172: }
6173:
6174: // ---------------------------------------------------------------------------
6175: // Upstream forwarding
6176: // ---------------------------------------------------------------------------
6177:
6178: type EffectiveUpstreamProtocol = UpstreamSnapshot["protocol"];
6179:
6180: type ResolvedRequestUpstreamRoute = {
6181: /** Explicit, sanitized X-Lore-Provider value (not inferred signals). */
6182: providerHeader?: string;
6183: /** Provider identity actually selected, including Copilot inference. */
6184: providerID?: string;
6185: headerUpstream?: string;
6186: headerUpstreamPath?: string;
6187: providerRoute: ReturnType<typeof resolveProviderRoute>;
6188: modelRoute: ReturnType<typeof resolveUpstreamRoute>;
6189: effectiveProtocol: ...
<path>/home/byk/Code/opencode-lore-v2/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
6319: modelRoute?.protocol ??
6320: req.protocol);
6321: const bedrockMantle = isBedrockMantleDispatch(
6322: providerRouteUsable,
6323: effectiveProtocol,
6324: );
6325: const selfBuiltUpstreamUrl = bedrockMantle
6326: ? bedrockMantleUrl(config.bedrockRegion)
6327: : effectiveProtocol === "vertex"
6328: ? `https://${vertexHost(config.vertexRegion)}`
6329: : null;
6330: const effectiveUpstreamBase =
6331: headerUpstream ??
6332: selfBuiltUpstreamUrl ??
6333: providerRoute?.url ??
6334: modelRoute?.url ??
6335: (effectiveProtocol === "anthropic"
6336: ? config.upstreamAnthropic
6337: : effectiveProtocol === "gemini"
6338: ? GEMINI_DEFAULT_UPSTREAM
6339: : config.upstreamOpenAI);
6340:
6341: return {
6342: providerHeader,
6343: providerID,
6344: ...
<path>/home/byk/Code/opencode-lore-v2/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
6565: effectiveUpstreamBase === "https://api.anthropic.com";
6566: const effectiveCache =
6567: cache && !isNativeAnthropic
6568: ? {
6569: ...cache,
6570: systemTTL: "5m" as const,
6571: conversationTTL: "5m" as const,
6572: }
6573: : cache;
6574: const result = buildAnthropicRequest(req, effectiveCache);
6575: url = `${effectiveUpstreamBase}${result.url}`;
6576: headers = result.headers;
6577: body = result.body;
6578: // AWS Bedrock (bedrock-mantle): remap the model id in the OUTGOING body to
6579: // the mantle catalog form (`anthropic.<model>`). Only the upstream body is
6580: // remapped — `req.model` stays the client id for session/cache tracking. ...
Found 50 matches
/home/byk/Code/opencode-lore-v2/packages/gateway/src/upstream-error-hint.ts:
Line 37: * an `x-api-key` (`api-key` scheme), so it is excluded by the `bearer` check —
Line 40: * That path is undocumented for mantle (which uses `x-api-key`) and low-risk.
/home/byk/Code/opencode-lore-v2/packages/gateway/src/translate/vertex.ts:
Line 155: * - `x-api-key`: replaced by the GCP OAuth2 bearer (set by the caller);
Line 165: "x-api-key",
/home/byk/Code/opencode-lore-v2/packages/gateway/src/translate/types.ts:
Line 793: "proxy-authorization",
Line 813: "x-api-key",
Line 815: "authorization",
Line 830: * (`x-api-key` / `Authorization`). This is intentional: a corporate-proxy
/home/byk/Code/opencode-lore-v2/packages/gateway/src/translate/gemini.ts:
Line 352: headers.authorization = `Bearer ${credential.value}`;
/home/byk/Code/opencode-lore-v2/packages/gateway/src/translate/bedrock.ts:
Line 6: * Bedrock API key (`x-api-key`) and ...
<path>/home/byk/Code/opencode-lore-v2/packages/gateway/src/auth.ts</path>
<type>file</type>
<content>
70: function isValidApiKey(value: string | undefined): value is string {
71: return value !== undefined && /^\S+$/.test(value);
72: }
73:
74: /**
75: * Extract auth from request headers.
76: *
77: * Accepts one of `x-api-key` (Anthropic SDK default), `x-goog-api-key`
78: * (Gemini), or `Authorization: Bearer` (OAuth / Claude Code subscriptions).
79: * Returns `null` when no valid credential is present or when multiple auth
80: * mechanisms are present. Rejecting ambiguity here prevents fingerprint and
81: * upstream-routing callers from silently selecting one credential by priority.
82: */
83: export function extractAuth(
84: headers: Record<string, string> | null | undefined,
85: ): AuthCredential | null {
86: if (!headers || hasConflictingAuthHeaders(headers)) return null;
87:
88: const apiKey = getHeaderValue(headers, "x-api-key");
89: if (isValidApiKey(apiKey)) ...
Found 100 matches (more matches available)
/home/byk/Code/opencode-lore-v2/packages/core/test/crypto.test.ts:
Line 157: // reject this. Guards against a future both-sides drop of domain separation
Line 175: // blob would open, so this test catches a both-sides drop of `info`.
Line 209: const dek = lc.generateDek(); // reuse the 32-byte value as both a DEK and a KEK
/home/byk/Code/opencode-lore-v2/packages/core/test/db.test.ts:
Line 425: test("v75/v76: both-columns state (partial v75→v76) converges on re-open", () => {
Line 456: // both idempotently. Dropping the column (not just NULLing it) is what
Line 792: // Drop both tables to simulate the broken state
Line 2334: // Survives both the single-session and bulk load paths.
Line 2384: // Survives both the single-session and bulk load paths.
/home/byk/Code/opencode-lore-v2/packages/core/test/cost-bulk-queries.test.ts:
Line 205: // idx_temporal_session. ...
No files found
Found 26 matches
/home/byk/Code/opencode-lore-v2/packages/gateway/src/ui.ts:
Line 2370: const query = url.searchParams.get("q") ?? "";
Line 2371: const projectFilter = url.searchParams.get("project") ?? "";
Line 2372: const scope = (url.searchParams.get("scope") ?? "all") as
/home/byk/Code/opencode-lore-v2/packages/gateway/src/translate/bedrock-runtime.ts:
Line 170: const match = BEDROCK_RUNTIME_PATH_RE.exec(new URL(req.url).pathname);
/home/byk/Code/opencode-lore-v2/packages/gateway/src/telemetry-privacy.ts:
Line 184: url.search = "";
/home/byk/Code/opencode-lore-v2/packages/gateway/src/server.ts:
Line 654: const key = new URL(req.url).searchParams.get("key");
Line 827: const url = new URL(req.url);
Line 1163: const pathname = new URL(req.url ?? "/", "http://gateway.local")
/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/login.ts:
Line 187: url.searchParams.get("token") ??
Line 188: ...
<path>/home/byk/Code/opencode-lore-v2/packages/gateway/src/server.ts</path>
<type>file</type>
<content>
790: if (config.allowRemoteManagement) {
791: log.notice(
792: "warning: remote management access is enabled; every client accepted by the listener can access /ui and /api",
793: );
794: }
795:
796: // Bootstrap the daily spend counter from DB (recovers today's spend after restart)
797: if (getDailyBudget() > 0) {
798: bootstrapDailySpend();
799: }
800:
801: // Wire embedding-worker OOM backoff/latch events to Sentry. Idempotent: the
802: // hook is assigned (not stacked), so a repeat startServer() is harmless.
803: setupEmbeddingFailureCapture();
804:
805: // Wire cache-bust-spiral detection to Sentry (#797). Same idempotency
806: // guarantee as the embedding hook above.
807: setupBustSpiralCapture();
808:
809: // Wire read-path timing (forSession/recall) to Sentry (#966 B). ...
Found 5 matches
/home/byk/Code/opencode-lore-v2/packages/gateway/src/server.ts:
Line 213: function isDataPlanePath(pathname: string): boolean {
Line 831: const dataPlanePath = isDataPlanePath(pathname);
Line 1165: if (isDataPlanePath(pathname) && req.headers.origin !== undefined) {
Line 1174: if (isDataPlanePath(pathname)) {
/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/data.ts:
Line 2751: const DATA_HELP = `
<path>/home/byk/Code/opencode-lore-v2/packages/gateway/src/server.ts</path>
<type>file</type>
<content>
190: const LOOPBACK_ADDRESSES = new BlockList();
191: LOOPBACK_ADDRESSES.addSubnet("127.0.0.0", 8, "ipv4");
192: LOOPBACK_ADDRESSES.addAddress("::1", "ipv6");
193:
194: /** True only for a numeric loopback socket address. Hostnames are not trusted. */
195: export function isLoopbackAddress(address: string | undefined): boolean {
196: if (!address) return false;
197: const family = isIP(address);
198: if (family === 4) return LOOPBACK_ADDRESSES.check(address, "ipv4");
199: if (family === 6) return LOOPBACK_ADDRESSES.check(address, "ipv6");
200: return false;
201: }
202:
203: function isManagementPath(pathname: string): boolean {
204: return (
205: pathname === "/" ||
206: pathname === "/api" ||
207: pathname.startsWith("/api/") ||
208: pathname === "/ui" ||
209: pathname.startsWith("/ui/")
210: );
211: }
212:
213: function ...
Found 100 matches (more matches available) /home/byk/Code/opencode-lore-v2/packages/gateway/src/ui.ts: Line 2174: // Find the project path from the project ID /home/byk/Code/opencode-lore-v2/packages/gateway/src/translate/types.ts: Line 540: gitRemote?: string; Line 799: "x-lore-project", Line 800: "x-lore-git-remote", /home/byk/Code/opencode-lore-v2/packages/gateway/src/synthetic-tools.ts: Line 534: gitRemote?: string; Line 542: * or `[remote "origin"]`. Only yields `gitRemote`. Line 582: result.gitRemote = normalizeRemoteUrl(rawUrl); Line 615: result.gitRemote = normalizeRemoteUrl(remoteRaw); /home/byk/Code/opencode-lore-v2/packages/gateway/src/suggest.ts: Line 12: * Tier P — a dominant absolute project path found in stored message content Line 151: // --- Tier P: dominant absolute project path in content --- Line 152: // Count each known-project path by how many distinct messages mention ...
<path>/home/byk/Code/opencode-lore-v2/packages/gateway/src/config.ts</path>
<type>file</type>
<content>
1170: // ---------------------------------------------------------------------------
1171:
1172: export type ProjectPathSource = "header" | "inferred" | "cwd";
1173:
1174: export type ProjectPathResult = {
1175: path: string;
1176: source: ProjectPathSource;
1177: /** Normalized git remote URL from `X-Lore-Git-Remote` header, if provided. */
1178: gitRemote?: string;
1179: /**
1180: * Set when an `X-Lore-Project` header was present but OVERRIDDEN by an
1181: * authoritative system-prompt inference that disagreed with it. Carries the
1182: * (rejected) header path so the session layer can detect and correct an
1183: * existing confident binding to a stale/static header — and so the gateway
1184: * can log a one-time warning about the misconfiguration. Absent when the
1185: * header agreed with (or matched) the inference, or when no header was sent. ...
RUN v4.1.8 /home/byk/Code/opencode-lore-v2
Test Files 1 passed (1)
Tests 10 passed (10)
Start at 16:43:51
Duration 944ms (transform 605ms, setup 664ms, import 24ms, tests 49ms, environment 0ms)
RUN v4.1.8 /home/byk/Code/opencode-lore-v2
Test Files 4 passed (4)
Tests 27 passed (27)
Start at 16:43:53
Duration 5.29s (transform 4.51s, setup 2.17s, import 7.66s, tests 4.03s, environment 1ms)
> lore-monorepo@ typecheck /home/byk/Code/opencode-lore-v2 > pnpm -r run typecheck Scope: 5 of 6 workspace projects packages/core typecheck$ tsc --noEmit && tsc --noEmit -p tsconfig.eval.json packages/core typecheck: Done packages/gateway typecheck$ tsc --noEmit packages/gateway typecheck: Done packages/opencode typecheck$ tsc --noEmit packages/pi typecheck$ tsc --noEmit packages/pi typecheck: Done packages/opencode typecheck: Done
...output truncated... Full output saved to: /home/byk/.local/share/opencode/tool-output/tool_0870fcce9001HcYnB8VeRnF3QG packages/gateway/test/recall-stream.test.ts:1325:8: warning typescript(no-non-null-assertion): Forbidden non-null assertion. help: Consider using the optional chain operator `?.` instead. `x!.y` is equivalent to `x.y` at runtime and will throw if `x` is `null` or `undefined`, but `x?.y` will return `undefined`. packages/gateway/test/recall-stream.test.ts:1329:13: warning typescript(no-non-null-assertion): Forbidden non-null assertion. help: Consider using the optional chain operator `?.` instead. `x!.y` is equivalent to `x.y` at runtime and will throw if `x` is `null` or `undefined`, but `x?.y` will return `undefined`. packages/gateway/test/recall-stream.test.ts:1342:20: warning typescript(no-non-null-assertion): Forbidden non-null assertion. help: Consider using the optional chain operator `?.` instead. `x!.y` is equivalent to `x.y` at runtime and will throw if ...
> lore-monorepo@ format:check /home/byk/Code/opencode-lore-v2 > oxfmt --check Checking formatting... All matched files use the correct format. Finished in 665ms on 846 files using 4 threads.
> lore-monorepo@ pretest /home/byk/Code/opencode-lore-v2 > pnpm --filter @loreai/gateway run bundle > @loreai/gateway@0.40.0 bundle /home/byk/Code/opencode-lore-v2/packages/gateway > tsx script/bundle.ts dist/index.cjs 16.7mb ⚠️ dist/index.cjs.map 43.5mb ⚡ Done in 2854ms dist/index.bun.js 16.1mb ⚠️ ⚡ Done in 1727ms dist/embedding-worker.cjs 565.1kb ⚡ Done in 202ms dist/embedding-worker.js 564.8kb ⚡ Done in 169ms dist/vector-worker.cjs 11.1kb ⚡ Done in 15ms dist/vector-worker.js 10.3kb ⚡ Done in 11ms ✓ Debug ID injected: ec73babe-887b-4885-8db8-0b3364db55f7 No SENTRY_AUTH_TOKEN — skipping sourcemap upload ✓ @loreai/gateway npm bundle complete (v0.40.0) dist/index.cjs — CJS bundle (Node.js, node:sqlite) dist/index.bun.js — ESM bundle (Bun, bun:sqlite) dist/embedding-worker.cjs — embedding worker CJS (Node.js) dist/embedding-worker.js — embedding worker ESM (Bun) dist/vector-worker.cjs — vector-search worker CJS ...
> lore-monorepo@ pretest /home/byk/Code/opencode-lore-v2 > pnpm --filter @loreai/gateway run bundle > @loreai/gateway@0.40.0 bundle /home/byk/Code/opencode-lore-v2/packages/gateway > tsx script/bundle.ts dist/index.cjs 16.7mb ⚠️ dist/index.cjs.map 43.5mb ⚡ Done in 3347ms dist/index.bun.js 16.1mb ⚠️ ⚡ Done in 1631ms dist/embedding-worker.cjs 565.1kb ⚡ Done in 180ms dist/embedding-worker.js 564.8kb ⚡ Done in 160ms dist/vector-worker.cjs 11.1kb ⚡ Done in 9ms dist/vector-worker.js 10.3kb ⚡ Done in 9ms ✓ Debug ID injected: ec73babe-887b-4885-8db8-0b3364db55f7 No SENTRY_AUTH_TOKEN — skipping sourcemap upload ✓ @loreai/gateway npm bundle complete (v0.40.0) dist/index.cjs — CJS bundle (Node.js, node:sqlite) dist/index.bun.js — ESM bundle (Bun, bun:sqlite) dist/embedding-worker.cjs — embedding worker CJS (Node.js) dist/embedding-worker.js — embedding worker ESM (Bun) dist/vector-worker.cjs — vector-search worker CJS ...
<skill_content name="jj-guide"> # Skill: jj-guide # jj Guide for AI Agents Jujutsu (jj) is a Git-compatible VCS with mutable commits, automatic snapshotting, no staging area, and first-class conflicts. This skill teaches you how to use it safely from a non-interactive agent environment. If `.jj/` exists in the repo root, this is a jj repo. **Use `jj` commands, not `git`.** In a colocated repo (`.jj/` *and* `.git/`), git tools can read the state, but mutations should go through `jj` so the operation log stays consistent. ## Critical Rules - **NEVER** use interactive flags (`-i`, `--interactive`). TUI prompts hang in agent environments. This applies to `jj split -i`, `jj squash -i`, `jj commit -i`, `jj resolve`, `jj diffedit`, etc. - **ALWAYS** pass `-m "msg"` when describing/committing. Without `-m`, an editor opens and hangs. - **VERIFY** mutations with `jj st` and `jj log` after `squash`, `abandon`, `rebase`, `restore`, `commit`. ...
Working copy changes: M packages/core/src/fetch-interceptor.ts M packages/core/src/index.ts A packages/core/test/fetch-interceptor-request.test.ts M packages/opencode/package.json A packages/opencode/script/build.ts M packages/opencode/src/index.ts M packages/opencode/src/internal.ts A packages/opencode/src/server-core.ts A packages/opencode/src/server-runtime.ts A packages/opencode/src/server.ts M packages/opencode/test/internal.test.ts A packages/opencode/test/package.test.ts A packages/opencode/test/server-runtime.test.ts A packages/opencode/test/server.test.ts M pnpm-lock.yaml Working copy (@) : wlpqmtos 52e6687e lore-v2-plugin | feat(opencode): add V2 server plugin Parent commit (@-): uutomtup 42911412 main | fix(gateway): preserve large recall continuations (#1730) wlpqmtosolpkopymsmpyonmmvoqpzlyx 52e6687e1eae545273185978c57838d8782e4e92 feat(opencode): add V2 server plugin uutomtupslqmmvuzknuurlrokzlrruuv 429114122aa1170fd171aa3f0a2bb97e5a6bd6aa fix(gateway): preserve large ...
diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts
index dfecbf9788..bbdd69b201 100644
--- a/packages/core/src/index.ts
+++ b/packages/core/src/index.ts
@@ -354,7 +354,10 @@
export { SemanticTokenCache } from "./semantic-token-cache";
export {
installFetchInterceptor,
+ rewriteRequest,
shouldIntercept,
+ type DynamicRequestHeaders,
+ type DynamicRequestHeadersSource,
type FetchInterceptorConfig,
} from "./fetch-interceptor";
export * as workerModel from "./worker-model";
diff --git a/packages/opencode/package.json b/packages/opencode/package.json
index 2dc3111e7d..612407f54f 100644
--- a/packages/opencode/package.json
+++ b/packages/opencode/package.json
@@ -11,14 +11,25 @@
"types": "./src/index.ts",
"bun": "./src/index.ts",
"default": "./src/index.ts"
+ },
+ "./server": {
+ "types": "./src/server.ts",
+ "bun": "./dist/server.js",
+ "default": "./dist/server.js"
}
},
"scripts": {
"typecheck": ...
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/src/index.ts</path>
<type>file</type>
<content>
380: "chat.headers": async (input, output) => {
381: Object.assign(
382: output.headers,
383: gatewayAccessHeadersForRemote(gatewayBase),
384: );
385: // Inject stable session ID — OpenCode's DB session ID survives restarts,
386: // unlike x-session-affinity (nanoid regenerated per process).
387: output.headers["x-lore-session-id"] = input.sessionID;
388: output.headers["x-lore-agent"] = input.agent;
389: // Flag OpenCode Task sub-agents so the gateway sizes their LTM
390: // injection (see #1300). A sub-agent runs in a child session carrying a
391: // parentID; forward it as the `x-parent-session-id` signal the gateway
392: // already understands (Claude Code sends this natively). Resolution is
393: // cached and never blocks or throws on failure. ...
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/src/index.ts</path>
<type>file</type>
<content>
100: if (!handle.owned) {
101: log.info(`reusing existing gateway at ${url}`);
102: }
103:
104: return url;
105: } catch (e) {
106: const msg = e instanceof Error ? e.message : String(e);
107: lastGatewayStartError = msg;
108: log.info("failed to start gateway in-process:", msg);
109: return null;
110: }
111: }
112:
113: // Captures the underlying reason the in-process gateway failed to start so
114: // the user-facing error can include the real cause (port conflict, DB lock,
115: // stale build, etc.) instead of just "Ensure @loreai/gateway is installed."
116: let lastGatewayStartError: string | null = null;
117:
118: // Process-wide initialization state — shared across all sessions.
119: // The plugin function is called once per OpenCode session/project, but
120: // lore init only needs to run once per process. ...
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/src/index.ts</path> <type>file</type> <content> 184: /** 185: * Resolve a session's parent session ID via the OpenCode SDK. 186: * 187: * OpenCode Task sub-agents run in a child session whose `parentID` points at 188: * the session that spawned them; primary sessions have no parent. We forward a 189: * non-null parent as the `x-parent-session-id` header so the gateway flags the 190: * session as a sub-agent and sizes its LTM injection accordingly (#1300) — the 191: * same signal Claude Code emits natively for its Task sub-agents. 192: * 193: * Cached per session (parentID is immutable). A successful lookup — including 194: * the common `null` for a primary session — is cached so we never re-query. ...
1 export * as SessionModelRequest from "./model-request.js"
2
3 import { HttpOptions, LanguageModel, LLM, LLMRequest, Message, SystemPart } from "@opencode/ai"
4 import type { StreamOptions } from "@opencode/ai/route"
5 import type { SessionRequestKind } from "@opencode/plugin/effect/session"
6 import type { Agent } from "@opencode/schema/agent"
7 import type { Model } from "@opencode/schema/model"
8 import type { Content } from "@opencode/schema/tool"
9 import { Cause, Config, Context, Effect, Layer, Result, Stream } from "effect"
10 import { HttpClientRequest, HttpClientResponse } from "effect/unstable/http"
11 import { makeLocationNode } from "@opencode/util/effect/app-node"
12 import { App } from "../app.js"
13 import { Permission } from "../permission.js"
--
208 "x-session-affinity": session.id,
209 "X-Session-Id": session.id,
210 ...(session.parentID ? { "x-parent-session-id": session.parentID } : {}),
...
300 // The definition objects we hand to hooks, mapped back to their tools. Hooks rename a
301 // tool by moving its definition to a new key; recognizing the object recovers the tool.
302 const given = new Map(
303 tools.definitions.map(
304 (tool) => [{ description: tool.description, input: { ...tool.inputSchema } }, tool] as const,
305 ),
306 )
307 // Hooks mutate this record in place: edit descriptions and schemas, rename, or remove.
308 const definitions = Object.fromEntries(Array.from(given, ([definition, tool]) => [tool.name, definition]))
309 const context: PluginHooks.Domains["session"]["context"] = {
310 sessionID: session.id,
311 agent: input.scope.contextAgentID ?? input.scope.agentID,
312 model: resolved.ref,
313 system: input.transcript.system,
314 messages: input.transcript.messages,
315 tools: definitions,
...
Found 5 matches
/home/byk/Code/opencode-lore-v2/packages/opencode/src/internal.ts:
Line 133: // it prepares context. OpenCode installs its own default before this
/home/byk/Code/opencode-lore-v2/packages/opencode/src/index.ts:
Line 26: * URL context), this plugin installs a fetch-level interceptor that
Line 32: * Per-request context (session ID, agent name, provider ID) is injected
/home/byk/Code/opencode-lore-v2/packages/opencode/src/server.ts:
Line 31: await ctx.session.hook("model.request", async (event) => {
Line 48: await ctx.session.hook("http.request", async (event) => {
180 return Message.text(IMAGE_REMOVED)
181 }
182 if (part.type !== "tool-result" || part.result.type !== "content") return part
183 return {
184 ...part,
185 result: {
186 ...part.result,
187 value: part.result.value.map((item: Content) => {
188 if (item.type !== "file" || !isImage(item.mime) || imageBytes - removed <= IMAGE_BYTES_TARGET) return item
189 removed += Buffer.byteLength(item.uri)
190 return { type: "text" as const, text: IMAGE_REMOVED }
191 }),
192 },
193 }
194 }),
195 }),
196 )
197 }
198
199 /** The identity a plugin hook sees for one outbound request. */
200 interface HookScope {
201 readonly sessionID: SessionSchema.ID
202 readonly agent: Agent.ID
203 readonly model: Model.Ref
204 readonly kind: SessionRequestKind
205 }
...
Found 13 matches
/home/byk/Code/opencode-lore-v2/packages/opencode/test/server.test.ts:
Line 10: projectPath: "/workspace/project",
Line 44: workspaceID?: string;
Line 65: location: {
Line 67: ...(options.workspaceID ? { workspaceID: options.workspaceID } : {}),
Line 129: test("registers hidden workers and location-scoped routing hooks", async () => {
Line 250: test("keeps two location scopes independent when one closes", async () => {
Line 255: projectPath: "/workspace/a",
Line 262: projectPath: "/workspace/b",
Line 295: runtime: expect.objectContaining({ projectPath: "/workspace/b" }),
/home/byk/Code/opencode-lore-v2/packages/opencode/test/server-runtime.test.ts:
Line 30: test("shares an owned gateway until every location releases it", async () => {
Line 47: expect(first?.projectPath).toBe("/workspace/one");
Line 49: expect(second?.projectPath).toBe("/workspace/two");
Line 134: ...
227 const McpEndpoints = ClientApi.groups["server.mcp"].endpoints 228 const ModelEndpoints = ClientApi.groups["server.model"].endpoints 229 const PluginEndpoints = ClientApi.groups["server.plugin"].endpoints 230 const PermissionEndpoints = ClientApi.groups["server.permission"].endpoints 231 const ProviderEndpoints = ClientApi.groups["server.provider"].endpoints 232 const ReferenceEndpoints = ClientApi.groups["server.reference"].endpoints 233 const SessionEndpoints = ClientApi.groups["server.session"].endpoints 234 const SkillEndpoints = ClientApi.groups["server.skill"].endpoints 235 const VcsEndpoints = ClientApi.groups["server.vcs"].endpoints 236 const WebSearchEndpoints = ClientApi.groups["server.websearch"].endpoints 237 const WorktreeEndpoints = ClientApi.groups["server.worktree"].endpoints 238 const context = yield* Effect.context<Scope.Scope>() ...
250 (execute: Tool.Info["execute"]): Info["execute"] =>
251 (input, context) =>
252 run(
253 execute(input, {
254 ...context,
255 progress: (update) => Effect.promise(() => context.progress(update)),
256 }),
257 )
258
259 const adaptApiMethod = <PromiseMethod>(
260 endpoint: HttpApiEndpoint.Top,
261 method: (input: never) => Effect.Effect<unknown, unknown>,
262 ) => {
263 const compiled = compileEndpoint(endpoint)
264 return ((input?: unknown) =>
265 Effect.gen(function* () {
266 const decoded = yield* Effect.forEach(compiled.decode, (decode) => decode(input ?? {}))
267 const result = yield* method(Object.assign({}, ...decoded) as never)
268 if (compiled.noContent) return undefined
269 return yield* ...
No files found
Found 1 matches /home/byk/Code/opencode-lore-v2/packages/opencode/src/internal.ts: Line 115: export function applyLoreProviderConfig(
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/src/internal.ts</path> <type>file</type> <content> 100: * (it always passes `options.baseURL` to the @ai-sdk factory, and the 101: * @ai-sdk `loadOptionalSetting()` only consults the env var when the 102: * factory receives an undefined `baseURL`). Every other @ai-sdk provider 103: * (google, mistral, groq, cohere, xai, perplexity, togetherai, vercel, 104: * alibaba, deepinfra, gateway, openrouter, cerebras, etc.) has NO 105: * baseURL env var at all. Iterating over `cfg.provider` is the only 106: * universal lever. 107: * 108: * Deep-merges per-provider so user-set keys under `provider.<id>` (custom 109: * headers, model overrides, etc.) are preserved. 110: * 111: * Exported for direct testing — the config hook delegates here so unit tests 112: * can verify the merge logic without spinning up a real gateway (the 113: * surrounding `LorePlugin` skips gateway start in `NODE_ENV=test`). ...
Found 89 matches
/home/byk/Code/opencode-lore-v2/packages/gateway/src/config.ts:
Line 506: return new URL(raw);
Line 546: const parsed = new URL(upstreamUrl);
Line 578: const url = new URL(sanitized);
Line 595: const url = new URL(value);
Line 633: const parsed = new URL(url);
Line 782: return new URL(effectiveUpstreamBase).origin + upstreamPath;
/home/byk/Code/opencode-lore-v2/packages/gateway/src/api.ts:
Line 107: const gitRemote = url.searchParams.get("git_remote") ?? undefined;
Line 108: const pathParam = url.searchParams.get("path") ?? undefined;
Line 119: const raw = url.searchParams.get("limit");
Line 176: const sessionId = url.searchParams.get("session") ?? undefined;
Line 447: const query = url.searchParams.get("q");
Line 466: const rawScope = url.searchParams.get("scope") ?? "all";
Line 475: const sessionID = url.searchParams.get("session") ?? ...
true gateway.example.com.evil
node:internal/modules/esm/resolve:271
throw new ERR_MODULE_NOT_FOUND(
^
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/home/byk/Code/opencode-lore-v2/packages/core/src/log' imported from /home/byk/Code/opencode-lore-v2/packages/core/src/fetch-interceptor.ts
at finalizeResolution (node:internal/modules/esm/resolve:271:11)
at moduleResolve (node:internal/modules/esm/resolve:865:10)
at defaultResolve (node:internal/modules/esm/resolve:992:11)
at #cachedDefaultResolve (node:internal/modules/esm/loader:691:20)
at #resolveAndMaybeBlockOnLoaderThread (node:internal/modules/esm/loader:708:38)
at ModuleLoader.resolveSync (node:internal/modules/esm/loader:740:52)
at #resolve (node:internal/modules/esm/loader:673:17)
at ModuleLoader.getOrCreateModuleJob (node:internal/modules/esm/loader:593:35)
at ModuleJob.syncLink (node:internal/modules/esm/module_job:163:33)
at ModuleJob.link (node:internal/modules/esm/module_job:253:17) {
code: ...
node:internal/process/promises:394
triggerUncaughtException(err, true /* fromPromise */);
^
Error: Transform failed with 2 errors:
/eval.ts:1:160: ERROR: Top-level await is currently not supported with the "cjs" output format
/eval.ts:1:243: ERROR: Top-level await is currently not supported with the "cjs" output format
at failureErrorWithLog (/home/byk/Code/opencode-lore-v2/node_modules/.pnpm/esbuild@0.28.1/node_modules/esbuild/lib/main.js:1748:15)
at /home/byk/Code/opencode-lore-v2/node_modules/.pnpm/esbuild@0.28.1/node_modules/esbuild/lib/main.js:1017:50
at responseCallbacks.<computed> (/home/byk/Code/opencode-lore-v2/node_modules/.pnpm/esbuild@0.28.1/node_modules/esbuild/lib/main.js:884:9)
at handleIncomingPacket (/home/byk/Code/opencode-lore-v2/node_modules/.pnpm/esbuild@0.28.1/node_modules/esbuild/lib/main.js:939:12)
at Socket.readFromStdout (/home/byk/Code/opencode-lore-v2/node_modules/.pnpm/esbuild@0.28.1/node_modules/esbuild/lib/main.js:862:7)
...
{"identical":true,"url":"https://gateway.example.com.evil/v1/messages","seen":[{"authorization":"Bearer secret","content-type":"text/plain;charset=UTF-8"}]}
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/ai/src/protocols/gemini.ts:841: endpoint: Endpoint.path(({ request }) => `/models/${request.model.id}:streamGenerateContent?alt=sse`, {
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/ai/src/protocols/google-images.ts:141: `${(input.baseURL ?? DEFAULT_BASE_URL).replace(/\/$/, "")}/models/${request.model.id}:generateContent`,
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/ai/src/protocols/google-images.ts:276: "Google generateContent does not fetch public image URLs; use bytes, a data URL, or a Gemini file URI",
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/ai/src/protocols/google-images.ts:285: ImageInputs.invalid("Google generateContent requires Gemini file URIs rather than provider file IDs"),
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/ai/src/providers/amazon-bedrock.ts:22: /** Override the computed `https://bedrock-runtime.<region>.amazonaws.com` URL. ...
810 /**
811 * The Gemini protocol — request body construction, body schema, and the
812 * streaming-event state machine shared by Google AI Studio and Vertex Gemini.
813 */
814 export const protocol = Protocol.make({
815 id: ADAPTER,
816 body: {
817 schema: GeminiBody,
818 from: fromRequest,
819 },
820 stream: {
821 event: Protocol.jsonEvent(GeminiEvent),
822 initial: (request) => ({
823 route: `${request.model.provider}/${request.model.route.id}`,
824 providerMetadataKey: request.model.route.providerMetadataKey ?? String(request.model.provider),
825 hasToolCalls: false,
826 lifecycle: Lifecycle.initial(),
827 nextReasoningId: 0,
828 nextTextId: 0,
829 }),
830 step,
831 onHalt: (state) => Effect.succeed(finish(state)),
832 },
833 })
834
835 export const route = Route.make({
836 id: ADAPTER,
837 provider: "google",
838 ...
1 import { Effect, Encoding, Schema } from "effect"
2 import { Route } from "../route/client.js"
3 import { Endpoint } from "../route/endpoint.js"
4 import { Protocol } from "../route/protocol.js"
5 import {
6 AIError,
7 LLMEvent,
8 Usage,
9 type CacheHint,
--
773
774 export const route = Route.make({
775 id: ADAPTER,
776 provider: "bedrock",
777 providerMetadataKey: "bedrock",
778 protocol,
779 // Bedrock's URL embeds the region in the route endpoint host and the
780 // validated modelId in the path. We read the validated body so the URL
781 // matches the body that gets signed.
782 endpoint: Endpoint.path<BedrockConverseBody>(
783 ({ body }) => `/model/${encodeURIComponent(body.modelId)}/converse-stream`,
784 ),
785 auth: BedrockAuth.auth,
786 framing,
787 })
788
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/config/plugin/provider.ts:12: id: "opencode.config.provider",
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/provider/azure.ts:153: ...(typeof provider.settings?.baseURL === "string"
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/provider/azure.ts:154: ? { baseURL: expandResourceName(provider.settings.baseURL, resourceName) }
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/provider/cloudflare-workers-ai.ts:43: if (typeof provider.settings?.baseURL === "string") return
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/provider/cloudflare-workers-ai.ts:45: if (accountId) provider.settings = { ...provider.settings, baseURL: workersEndpoint(accountId) }
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/provider/google-vertex.ts:81: ...(typeof provider.settings?.baseURL === ...
1 export * as ConfigProviderPlugin from "./provider.js"
2
3 import { define } from "@opencode/plugin/effect/plugin"
4 import { Document, type Entry } from "@opencode/schema/config"
5 import { Money } from "@opencode/schema/money"
6 import { Effect } from "effect"
7 import { Config } from "../../config.js"
8 import { Provider } from "../../provider.js"
9 import { ConfigEntryObserver } from "./entry-observer.js"
10
11 export const Plugin = define({
12 id: "opencode.config.provider",
13 effect: Effect.fn(function* (ctx) {
14 const config = yield* Config.Service
15 const loaded = yield* ConfigEntryObserver.observe(
16 config,
17 ctx.event,
18 ctx.integration.reload().pipe(Effect.andThen(ctx.catalog.reload())),
19 )
20 yield* ctx.integration.transform((integrations) => {
21 for (const [id, provider] of configuredProviders(loaded.entries)) {
22 ...
1 export * as ConfigProviderPlugin from "./provider.js"
2
3 import { define } from "@opencode/plugin/effect/plugin"
4 import { Document, type Entry } from "@opencode/schema/config"
5 import { Money } from "@opencode/schema/money"
6 import { Effect } from "effect"
7 import { Config } from "../../config.js"
8 import { Provider } from "../../provider.js"
9 import { ConfigEntryObserver } from "./entry-observer.js"
10
11 export const Plugin = define({
12 id: "opencode.config.provider",
13 effect: Effect.fn(function* (ctx) {
14 const config = yield* Config.Service
15 const loaded = yield* ConfigEntryObserver.observe(
16 config,
17 ctx.event,
18 ctx.integration.reload().pipe(Effect.andThen(ctx.catalog.reload())),
19 )
20 yield* ctx.integration.transform((integrations) => {
21 for (const [id, provider] of configuredProviders(loaded.entries)) {
22 ...
12 import { Config } from "../config.js"
13 import { Credential } from "../credential.js"
14 import { ConfigAgentPlugin } from "../config/plugin/agent.js"
15 import { ConfigCommandPlugin } from "../config/plugin/command.js"
16 import { ConfigCompactionPlugin } from "../config/plugin/compaction.js"
17 import { ConfigFormatterPlugin } from "../config/plugin/formatter.js"
18 import { ConfigImagePlugin } from "../config/plugin/image.js"
19 import { ConfigInstructionPlugin } from "../config/plugin/instruction.js"
20 import { ConfigLocationWatcherPlugin } from "../config/plugin/location-watcher.js"
21 import { ConfigMcpPlugin } from "../config/plugin/mcp.js"
22 import { ConfigProviderPlugin } from "../config/plugin/provider.js"
23 import { ConfigPolicyPlugin } from "../config/plugin/policy.js"
24 import { ConfigReferencePlugin } from "../config/plugin/reference.js"
25 import { ConfigShellPlugin } from "../config/plugin/shell.js"
...
215 OpenCodeTools.Plugin, 216 QuestionTool.Plugin, 217 ReadTool.Plugin, 218 ShellTool.Plugin, 219 SkillTool.Plugin, 220 SubagentTool.Plugin, 221 WebFetchTool.Plugin, 222 WebSearchTool.Plugin, 223 WriteTool.Plugin, 224 WarmingPlugin.Plugin, 225 ] as const satisfies readonly InternalPlugin[] 226 227 const post = [ 228 ConfigInstructionPlugin.Plugin, 229 ConfigReferencePlugin.Plugin, 230 ConfigAgentPlugin.Plugin, 231 ConfigCommandPlugin.Plugin, 232 ConfigCompactionPlugin.Plugin, 233 ConfigFormatterPlugin.Plugin, 234 ConfigImagePlugin.Plugin, 235 ConfigLocationWatcherPlugin.Plugin, 236 ConfigShellPlugin.Plugin, 237 ConfigSnapshotPlugin.Plugin, 238 ConfigToolOutputPlugin.Plugin, 239 ConfigSkillPlugin.Plugin, 240 ConfigProviderPlugin.Plugin, 241 ConfigWebSearchPlugin.Plugin, 242 ConfigWorktreePlugin.Plugin, 243 VariantPlugin.Plugin, 244 ...
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/internal.ts:247:export const list = Effect.fn("PluginInternal.list")(function* () {
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/supervisor.ts:125: const internal = yield* PluginInternal.list()
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/supervisor.ts:144: ...internal.pre.map((plugin) => ({ ...plugin, revision: "internal", source: { type: "builtin" as const } })),
2ac698d65aa4690a694307e9cbdf44537ea9a4fb:packages/core/src/plugin/supervisor.ts:148: const post = internal.post.map((plugin) => ({
115
116 export const layer = Layer.effectDiscard(
117 Effect.gen(function* () {
118 const registry = yield* Plugin.Service
119 const sdk = yield* SdkPlugins.Service
120 const instance = yield* InstancePlugins.Service
121 const sources = yield* ConfigPluginSource.Service
122 const modules = yield* PluginModule.make()
123 const bus = yield* Bus.Service
124 const updates = yield* PluginUpdate.Service
125 const internal = yield* PluginInternal.list()
126 let release: Effect.Effect<void> | undefined = yield* registry.hold()
127 yield* Effect.addFinalizer(() => release ?? Effect.void)
128 // Built-ins capture services from this layer; unload them before those services close.
129 yield* Effect.addFinalizer(registry.close)
130 let packages = new Set<string>()
131 // Last generation handed to the registry per target; a failed reload keeps it in place. ...
1 export * as PluginSupervisor from "./supervisor.js"
2
3 import { Event } from "@opencode/schema/config"
4 import { Cause, Effect, Layer, Queue, Stream } from "effect"
5 import path from "path"
6 import { ConfigPluginSource } from "../config/plugin/source.js"
7 import { makeLocationNode } from "@opencode/util/effect/app-node"
8 import { Bus } from "../bus.js"
9 import { Npm } from "@opencode/util/npm"
10 import { Plugin } from "../plugin.js"
11 import { InstancePlugins } from "./instance.js"
12 import { PluginInternal } from "./internal.js"
13 import { PluginModule } from "./module.js"
14 import { SdkPlugins } from "./sdk.js"
15 import { PluginUpdate } from "./update.js"
16 import { Watcher } from "../filesystem/watcher.js"
17
18 const resolve = Effect.fn("PluginSupervisor.resolve")(function* (
19 modules: Effect.Success<ReturnType<typeof PluginModule.make>>,
20 pre: readonly ...
Found 4 matches /home/byk/Code/opencode-lore-v2/packages/gateway/src/server.ts: Line 223: GEMINI_PATH_RE.test(pathname) || Line 631: const GEMINI_PATH_RE = Line 940: // GEMINI_PATH_RE) so the Gemini CLI and @ai-sdk/google both match. Line 942: const gm = pathname.match(GEMINI_PATH_RE);
<path>/home/byk/Code/opencode-lore-v2/packages/gateway/src/server.ts</path>
<type>file</type>
<content>
620: return errorResponse(502, "api_error", `Gateway pipeline error: ${msg}`);
621: }
622: }
623:
624: /**
625: * Matches a native Gemini `generateContent` endpoint path, capturing the model
626: * id and the verb. Version-prefix-agnostic (`/v1beta/models/...`,
627: * `/v1/models/...`, or bare `/models/...`) so both the Gemini CLI
628: * (`GOOGLE_GEMINI_BASE_URL` → `/v1beta/...`) and `@ai-sdk/google` (baseURL
629: * pinned to `${gateway}/v1` → `/v1/...`) are matched.
630: */
631: const GEMINI_PATH_RE =
632: /\/models\/([^/:]+):(generateContent|streamGenerateContent)$/;
633:
634: async function handleGeminiGenerateContent(
635: req: Request,
636: config: GatewayConfig,
637: model: string,
638: stream: boolean,
639: ): Promise<Response> {
640: let body: unknown;
641: try {
642: body = JSON.parse(await decodeRequestBody(req));
643: } catch {
644: ...
Found 39 matches
/home/byk/Code/opencode-lore-v2/packages/opencode/test/server.test.ts:
Line 117: delete process.env.LORE_UPSTREAM_OPENAI;
Line 161: expect(state.callbacks.has("model.request")).toBe(true);
Line 170: baseURL: "https://api.openai.com/v1",
Line 172: await state.callbacks.get("model.request")?.(
Line 190: expect(modelEvent.baseURL).toBe("http://127.0.0.1:3207/v1");
Line 239: baseURL: "https://api.openai.com/v1",
Line 241: await state.callbacks.get("model.request")?.(event as unknown as never);
Line 286: await second.callbacks.get("model.request")?.({
Line 291: baseURL: "https://api.openai.com/v1",
/home/byk/Code/opencode-lore-v2/packages/opencode/test/server-runtime.test.ts:
Line 122: process.env.LORE_UPSTREAM_OPENAI = "https://upstream.example/v1";
Line 123: process.env.LORE_UPSTREAM_EXTRA_HEADERS = [
/home/byk/Code/opencode-lore-v2/packages/opencode/test/routing.e2e.test.ts:
Line 12: * ...
1 export * as PluginModule from "./module.js"
2
3 import type { Plugin } from "@opencode/plugin/effect/plugin"
4 import { Host } from "@opencode/plugin/host"
5 import { createPluginSources } from "@opencode/plugin/source"
6 import { Npm } from "@opencode/util/npm"
7 import { Deferred, Effect, FiberSet, PubSub, Schema, Stream } from "effect"
8 import path from "path"
9 import { stat } from "node:fs/promises"
10 import { fileURLToPath, pathToFileURL } from "url"
11 import type { ConfigPluginSource } from "../config/plugin/source.js"
12 import type { Generation } from "../plugin.js"
13 import { PluginPromise } from "./promise.js"
14 import { Watcher } from "../filesystem/watcher.js"
15
16 export const make = Effect.fn("PluginModule.make")(function* () {
17 const watcher = yield* Watcher.Service
18 const scope = yield* Effect.scope
19 const runPromise = yield* FiberSet.makeRuntimePromise()
20 ...
No files found
No files found
Found 3 matches
/home/byk/Code/opencode-lore-v2/packages/opencode/test/gateway-smoke.test.ts:
Line 55: const res = await fetch(`${base}/health`);
Line 104: // Occupy a port with a server that responds to /health like a lore gateway.
Line 109: if (url.pathname === "/health") {
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/test/gateway-smoke.test.ts</path>
<type>file</type>
<content>
1: import { describe, test, expect, afterAll } from "vitest";
2: import { probeGateway } from "../src/internal";
3:
4: /**
5: * Smoke tests for the in-process gateway startup.
6: *
7: * These exercise startGateway from @loreai/gateway directly (which is what
8: * the plugin's startInProcess delegates to). Tests use ephemeral ports so
9: * they don't collide with a running gateway.
10: */
11:
12: // Minimal view of the @loreai/gateway module surface used by these tests.
13: type GatewayServer = { stop: () => void; port: number; hosts: string[] };
14: type GatewayModule = {
15: loadConfig: () => { port: number } & Record<string, unknown>;
16: startServer: (config: unknown) => Promise<GatewayServer>;
17: };
18:
19: // Track shutdown handles to clean up after tests. ...
Found 18 matches
/home/byk/Code/opencode-lore-v2/packages/opencode/src/server-runtime.ts:
Line 5: probeGateway,
Line 148: if (await probeGateway(url)) return url;
Line 156: if (await probeGateway(url)) return url;
Line 162: readPortFile: () => number | null;
Line 164: const port = gateway.readPortFile();
Line 173: if (await probeGateway(url)) return url;
/home/byk/Code/opencode-lore-v2/packages/opencode/src/internal.ts:
Line 154: export async function probeGateway(
Line 158: const controller = new AbortController();
Line 159: const timer = setTimeout(() => controller.abort(), timeoutMs);
Line 162: if (isLoopbackUrl(url)) return await probeLoopback(url, controller.signal);
Line 163: return (await fetch(url, { signal: controller.signal })).ok;
/home/byk/Code/opencode-lore-v2/packages/opencode/src/index.ts:
Line 17: probeGateway,
Line 49: if (await probeGateway(url)) return url;
Line 58: if (await ...
<path>/home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-install.test.ts</path>
<type>file</type>
<content>
1: /**
2: * End-to-end tests for installFetchInterceptor.
3: *
4: * These exercise the actual interception flow — URL rewriting, header
5: * injection, X-Lore-Upstream-URL derivation, and the body-shape fallback —
6: * by installing the interceptor over a stubbed originalFetch and asserting
7: * what URL/headers/body the gateway would receive.
8: */
9: import { describe, test, expect, beforeEach, afterEach, vi } from "vitest";
10: import {
11: installFetchInterceptor,
12: interceptUrlForProtocol,
13: } from "../src/fetch-interceptor";
14:
15: const GATEWAY = "http://127.0.0.1:3207";
16:
17: type Captured = { url: string; init: RequestInit | undefined };
18:
19: describe("installFetchInterceptor — end-to-end routing", () => {
20: let cleanup: () => void;
21: let captured: Captured | null;
22: let realFetch: typeof globalThis.fetch;
23: let ...
Found 100 matches (more matches available)
/home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-request.test.ts:
Line 11: test("routes a V2-style Request without losing method, body, auth, path, or query", async () => {
Line 12: const body = JSON.stringify({
Line 26: body,
Line 54: expect(request.bodyUsed).toBe(false);
Line 55: expect(await routed.text()).toBe(body);
Line 62: body: JSON.stringify({ model: "gpt-5", input: [] }),
Line 70: test("returns a direct gateway Request unchanged while observing its headers", async () => {
Line 75: body: JSON.stringify({ model: "claude", messages: [] }),
Line 92: "http://localhost:8000/v1/messages",
Line 99: body: JSON.stringify({ model: "claude", messages: [] }),
Line 115: test("routes a streaming body on a known path without reading it", async () => {
Line 116: const body = new ReadableStream<Uint8Array>({
Line 118: ...
<path>/home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-install.test.ts</path>
<type>file</type>
<content>
220: });
221: });
222:
223: describe("x-lore-upstream-path — original endpoint preservation (#1052)", () => {
224: test("GitHub Copilot /chat/completions (no /v1) preserves the bare path", async () => {
225: // Body-detected (Path 2): Copilot's endpoint has no /v1/ segment, so the
226: // URL patterns miss and we fall back to body-shape detection.
227: await fetch("https://api.githubcopilot.com/chat/completions", {
228: method: "POST",
229: body: JSON.stringify({ model: "gpt-4", messages: [] }),
230: });
231: expect(captured?.url).toBe(`${GATEWAY}/v1/chat/completions`);
232: expect(headerVal("x-lore-upstream-url")).toBe(
233: "https://api.githubcopilot.com",
234: );
235: // The crux of #1052: the gateway must learn the real endpoint omits /v1/. ...
Error: No such path: packages/opencode/dist/server.js tracked-dist-exit=1 M packages/core/src/fetch-interceptor.ts M packages/core/src/index.ts A packages/core/test/fetch-interceptor-request.test.ts M packages/opencode/package.json A packages/opencode/script/build.ts M packages/opencode/src/index.ts M packages/opencode/src/internal.ts A packages/opencode/src/server-core.ts A packages/opencode/src/server-runtime.ts A packages/opencode/src/server.ts M packages/opencode/test/internal.test.ts A packages/opencode/test/package.test.ts A packages/opencode/test/server-runtime.test.ts A packages/opencode/test/server.test.ts M pnpm-lock.yaml
1 export * as Host from "./host.js"
2
3 import path from "node:path"
4 import { importModule, resolveModule } from "@opencode/util/runtime-import"
5
6 export interface Target {
7 readonly directory: string
8 readonly name?: string
9 }
10
11 export interface Entrypoints {
12 readonly server?: string
13 readonly tui?: string
14 readonly rpc?: string
15 }
16
17 export function resolve(target: Target): Entrypoints {
18 const entry = (subpaths: readonly string[]) => {
19 for (const subpath of subpaths) {
20 const specifier = target.name
21 ? [target.name, subpath].filter(Boolean).join("/")
22 : path.resolve(target.directory, subpath || "index")
23 try {
24 return resolveModule(specifier, target.directory)
25 } catch (error) {
26 if (
27 !(error instanceof Error) ||
28 !("code" in ...
<path>/home/byk/Code/opencode-lore-v2/packages/opencode/package.json</path>
<type>file</type>
<content>
1: {
2: "name": "@loreai/opencode",
3: "version": "0.40.0",
4: "type": "module",
5: "license": "FSL-1.1-Apache-2.0",
6: "description": "Three-tier memory architecture for OpenCode — distillation, not summarization",
7: "main": "./src/index.ts",
8: "types": "./src/index.ts",
9: "exports": {
10: ".": {
11: "types": "./src/index.ts",
12: "bun": "./src/index.ts",
13: "default": "./src/index.ts"
14: },
15: "./server": {
16: "types": "./src/server.ts",
17: "bun": "./dist/server.js",
18: "default": "./dist/server.js"
19: }
20: },
21: "scripts": {
22: "typecheck": "tsc --noEmit",
23: "build": "tsx script/build.ts"
24: },
25: "peerDependencies": {
26: "@opencode-ai/plugin": ">=1.1.0",
27: "@opencode/plugin": ">=0.0.0"
28: },
29: "peerDependenciesMeta": {
30: "@opencode/plugin": {
31: ...
(no output)
Found 100 matches (more matches available)
/home/byk/Code/opencode/packages/core/test/session-runner.test.ts:
Line 927: model: { id: ModelV2.ID.make("replacement"), providerID: ProviderV2.ID.make("fake") },
Line 979: model: { id: ModelV2.ID.make("replacement"), providerID: ProviderV2.ID.make("fake") },
Line 1021: model: { id: ModelV2.ID.make("replacement"), providerID: ProviderV2.ID.make("fake") },
Line 1560: model: { id: ModelV2.ID.make("replacement"), providerID: ProviderV2.ID.make("fake") },
Line 2275: model: { id: ModelV2.ID.make("fake-model"), providerID: ProviderV2.ID.make("fake") },
Line 2339: model: { id: ModelV2.ID.make("fake-model"), providerID: ProviderV2.ID.make("fake") },
Line 2399: model: { id: ModelV2.ID.make("fake-model"), providerID: ProviderV2.ID.make("fake") },
Line 2521: it.effect("adds session correlation headers to model requests", () =>
Line 2537: it.effect("adds the parent ...
No files found
Found 14 matches
/home/byk/Code/opencode/packages/core/test/session-runner.test.ts:
Line 2521: it.effect("adds session correlation headers to model requests", () =>
Line 2537: it.effect("adds the parent session header to child model requests", () =>
/home/byk/Code/opencode/packages/core/test/catalog.test.ts:
Line 177: model.request.body.baseURL = "https://override.example.com"
Line 216: it.effect("resolves provider and model request merges", () =>
Line 228: model.request.headers.model = "model"
Line 229: model.request.headers.shared = "model"
Line 230: model.request.body.model = true
Line 231: model.request.body.request = true
Line 232: model.request.body.shared = "model"
Line 237: expect(model.request.headers).toEqual({ provider: "provider", shared: "model", model: "model" })
Line 238: expect(model.request.body).toEqual({ provider: true, model: true, request: true, shared: ...
Found 100 matches (more matches available)
/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/upgrade-recovery.ts:
Line 1215: "Canonical standalone executable is missing; invoke the authenticated upgrade backup path to recover it",
/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/uninstall.ts:
Line 178: readProcessRecord: () => GatewayProcessRecord | null;
Line 180: record: GatewayProcessRecord,
Line 181: ) => Promise<"authenticated" | "rejected" | "unavailable" | "timeout">;
Line 184: probePort: (baseURL: string) => Promise<GatewayHealthStatus>;
Line 610: `Gateway process discovery evidence is invalid: ${processInspection.reason}. Run \`lore stop\`, inspect runtime records, then retry uninstall.`,
Line 613: const record =
Line 615: ? processInspection.record
Line 616: : io.readProcessRecord();
Line 617: if (record !== null) {
Line 618: const status = await io.authenticateProcess(record);
Line ...
Found 26 matches
/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/uninstall.ts:
Line 2767: const { inspectGatewayProcessFile, readGatewayProcessFile } =
Line 2770: const { probeGatewayStatus, probeGatewayProcessStatus } =
Line 2803: readProcessRecord: readGatewayProcessFile,
Line 2804: authenticateProcess: probeGatewayProcessStatus,
/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/stop.ts:
Line 13: readGatewayProcessFile,
Line 25: probeGatewayProcess,
Line 403: readRecord: readGatewayProcessFile,
Line 405: authenticate: probeGatewayProcess,
/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/start.ts:
Line 21: readGatewayProcessFile,
Line 149: readProcess: readGatewayProcessFile,
Line 150: authenticate: probeGatewayProcessHost,
Line 157: const current = readGatewayProcessFile();
Line 198: export async function probeGatewayIdentity(
Line 207: export async function ...
<path>/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/start.ts</path>
<type>file</type>
<content>
130:
131: export type GatewayShutdownRequestResult =
132: | "accepted"
133: | "unsupported"
134: | "failed";
135:
136: export interface StartGatewayIO {
137: readProcess: () => GatewayProcessRecord | null;
138: authenticate: (record: GatewayProcessRecord) => Promise<string | null>;
139: writePort: (port: number, token: string) => void;
140: removePort: (port: number, token: string) => void;
141: writeProcess: (record: GatewayProcessRecord) => void;
142: removeProcess: (pid: number, record?: GatewayProcessRecord) => void;
143: startServer: typeof startServer;
144: resetPipelineState: typeof resetPipelineState;
145: createProcessShutdownController: typeof makeProcessShutdownController;
146: }
147:
148: const realStartGatewayIO: StartGatewayIO = {
149: readProcess: readGatewayProcessFile,
150: authenticate: probeGatewayProcessHost,
151: writePort: ...
Found 14 matches
/home/byk/Code/opencode-lore-v2/packages/gateway/src/portfile.ts:
Line 98: export function readPortFile(): number | null {
/home/byk/Code/opencode-lore-v2/packages/gateway/src/pidfile.ts:
Line 346: export function readGatewayProcessFile(): GatewayProcessRecord | null {
/home/byk/Code/opencode-lore-v2/packages/gateway/src/index.ts:
Line 24: export { readPortFile } from "./portfile";
Line 25: export { readGatewayProcessFile } from "./pidfile";
/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/uninstall.ts:
Line 2767: const { inspectGatewayProcessFile, readGatewayProcessFile } =
Line 2803: readProcessRecord: readGatewayProcessFile,
/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/stop.ts:
Line 13: readGatewayProcessFile,
Line 403: readRecord: readGatewayProcessFile,
/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/start.ts:
Line 21: readGatewayProcessFile,
Line 149: readProcess: ...
<path>/home/byk/Code/opencode-lore-v2/packages/gateway/src/index.ts</path>
<type>file</type>
<content>
1: /**
2: * Lore Gateway — package entry point.
3: *
4: * Library exports for programmatic use, plus `runCli()` for the CLI binary.
5: *
6: * Library usage:
7: * import { startServer, loadConfig } from "@loreai/gateway";
8: *
9: * CLI usage (via bin wrapper):
10: * lore start
11: * lore run claude
12: */
13: import "../instrument";
14: import { fileURLToPath } from "node:url";
15:
16: // ---------------------------------------------------------------------------
17: // Library API
18: // ---------------------------------------------------------------------------
19:
20: export { loadConfig, DEFAULT_PORTS, DEFAULT_PORT } from "./config";
21: export type { GatewayConfig } from "./config";
22: export { startServer } from "./server";
23: export { handleRequest, resetPipelineState } from "./pipeline";
24: export { readPortFile } from "./portfile";
25: export { ...
package/dist/server.js
package/package.json
package/src/server.ts
{"types":"./src/server.ts","bun":"./dist/server.js","default":"./dist/server.js"}
src/,dist/,README.md,LICENSE
* 🔴 (18:46) User stated that `__filename` is always defined in CJS bundles and Node.js CJS. In `/home/byk/Code/opencode-lore-v2/packages/gateway/src/index.ts` lines 52–69, direct-execution detection first checks `typeof __filename === "string"` and compares `process.argv[1] === __filename`; otherwise the ESM path compares `process.argv[1] === fileURLToPath(import.meta.url)`, returning `false` on…
* 🔴 (18:43) Search found 14 references to `readPortFile` / `readGatewayProcessFile`: `/home/byk/Code/opencode-lore-v2/packages/gateway/src/portfile.ts` line 98 exports `readPortFile(): number | null`; `/home/byk/Code/opencode-lore-v2/packages/gateway/src/pidfile.ts` line 346 exports `readGatewayProcessFile(): GatewayProcessRecord | null`; `/home/byk/Code/opencode-lore-v2/packages/gateway/src/ind…
* 🔴 (18:41) `/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/start.ts` defines `GatewayShutdownRequestResult` as `"accepted" | "unsupported" | "failed"` and `StartGatewayIO` with `readProcess`, `authenticate`, `writePort`, `removePort`, `writeProcess`, `removeProcess`, `startServer`, `resetPipelineState`, and `createProcessShutdownController`. * 🔴 (18:41) `realStartGatewayIO` maps proc…
* 🔴 (18:27) `/home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-install.test.ts` defines end-to-end routing tests around `installFetchInterceptor` and `interceptUrlForProtocol`, using gateway `http://127.0.0.1:3207`, injected context headers `x-lore-session-id: sess-123` and `x-lore-project: /home/me/proj`, and observers for `authorization` and `x-api-key`. * 🔴 (18:27) URL-mat…
* 🔴 (18:25) Search found 18 matches related to gateway probing and port-file discovery across `/home/byk/Code/opencode-lore-v2/packages/opencode/src/server-runtime.ts`, `/home/byk/Code/opencode-lore-v2/packages/opencode/src/internal.ts`, and `/home/byk/Code/opencode-lore-v2/packages/opencode/src/index.ts`. * 🔴 (18:25) `/home/byk/Code/opencode-lore-v2/packages/opencode/src/server-runtime.ts` imp…
* 🔴 (18:05) In `packages/core/src/plugin/supervisor.ts`, a failed package revision “never became a generation,” so `resolve()` retains `packages.get(operation.target) ?? running.get(operation.target)`, restores it to `packages`, and re-enables its plugin ID. * 🔴 (18:05) `resolve()` in `packages/core/src/plugin/supervisor.ts` matches selectors as exact IDs, `"*"`, or prefix wildcards ending in `…
* 🔴 (17:59) `applyLoreProviderConfig()` in `/home/byk/Code/opencode-lore-v2/packages/opencode/src/internal.ts` always passes `options.baseURL` to the `@ai-sdk` factory; `@ai-sdk`’s `loadOptionalSetting()` consults the environment variable only when the factory receives an undefined `baseURL`. * 🔴 (17:59) The provider-routing rationale in `/home/byk/Code/opencode-lore-v2/packages/opencode/src/in…
* 🔴 (17:50) Search found context-related references in `/home/byk/Code/opencode-lore-v2/packages/opencode/src/internal.ts` line 133, `/home/byk/Code/opencode-lore-v2/packages/opencode/src/index.ts` lines 26 and 32, and `/home/byk/Code/opencode-lore-v2/packages/opencode/src/server.ts` lines 31 and 48. * 🔴 (17:50) `/home/byk/Code/opencode-lore-v2/packages/opencode/src/server.ts` registers a `"mod…
* 🔴 (17:47) In the model-request preparation code at lines 300–308, `given` is a `Map` from hook-facing definition objects `{ description: tool.description, input: { ...tool.inputSchema } }` back to their original tools; `definitions` is created with canonical `tool.name` keys and those definition objects as values. * 🔴 (17:47) The `"session"` / `"context"` hook receives `context` with `session…
* 🔴 (17:47) User supplied OpenCode model-request implementation code importing `HttpOptions`, `LanguageModel`, `LLM`, `LLMRequest`, `Message`, and `SystemPart` from `@opencode/ai`; `StreamOptions` from `@opencode/ai/route`; `SessionRequestKind`, `Agent`, `Model`, and `Content`; Effect primitives; `HttpClientRequest`/`HttpClientResponse`; `makeLocationNode`; `App`; and `Permission`. * 🔴 (17:47) …
* 🔴 (17:24) A new monorepo test run in `/home/byk/Code/opencode-lore-v2` reached Vitest `v4.1.8` after successfully rebuilding `@loreai/gateway@0.40.0`; this build completed `dist/index.cjs` in `3347ms`, `dist/index.bun.js` in `1631ms`, `dist/embedding-worker.cjs` in `180ms`, `dist/embedding-worker.js` in `160ms`, `dist/vector-worker.cjs` in `9ms`, and `dist/vector-worker.js` in `9ms`. * 🔴 (17:…
* 🔴 (16:49) In `/home/byk/Code/opencode-lore-v2`, monorepo `pretest` ran `pnpm --filter @loreai/gateway run bundle`, invoking `tsx script/bundle.ts` for `@loreai/gateway@0.40.0`. * 🔴 (16:49) Gateway bundle outputs were generated successfully: `dist/index.cjs` (`16.7mb`, `2854ms`), `dist/index.cjs.map` (`43.5mb`), `dist/index.bun.js` (`16.1mb`, `1727ms`), `dist/embedding-worker.cjs` (`565.1kb`, …
* 🔴 (16:45) Monorepo typecheck command `pnpm -r run typecheck` completed successfully in `/home/byk/Code/opencode-lore-v2`, covering 5 of 6 workspace projects: `packages/core` ran `tsc --noEmit && tsc --noEmit -p tsconfig.eval.json`; `packages/gateway`, `packages/opencode`, and `packages/pi` each ran `tsc --noEmit`; all reported `Done`. * 🔴 (16:46) Static-analysis output was truncated and saved…
* 🔴 (16:42) `/home/byk/Code/opencode-lore-v2/packages/gateway/src/server.ts` wires `setupRecallContinuationFailureCapture()` to report only the allowlisted recall-continuation failure category; the assignment-based hook “never captures request or provider content.” * 🔴 (16:42) Management-route authorization uses `node:http` socket metadata and “never from Forwarded,” `X-Forwarded-For`, `Host`, …
* 🔴 (16:39) `/home/byk/Code/opencode-lore-v2/packages/gateway/src/pipeline.ts` defines `ResolvedRequestUpstreamRoute` with `providerHeader?`, selected `providerID?`, `headerUpstream?`, `headerUpstreamPath?`, `providerRoute`, `modelRoute`, `effectiveProtocol`, `effectiveUpstreamBase`, and `bedrockMantle`. * 🔴 (16:39) `captureLegacyGlobalAuth()` preserves the legacy process-global credential only…
* 🔴 (16:35) `/home/byk/Code/opencode-lore-v2/packages/core/src/fetch-interceptor.ts` implements fetch-level interception by wrapping `globalThis.fetch`, allowing provider SDKs to construct requests with their original authentication, headers, and URLs before transparent rerouting through the Lore gateway. * 🔴 (16:35) `FetchInterceptorConfig` contains `gatewayBase: string`, dynamic per-request `…
* 🔴 (16:34) Root `/home/byk/Code/opencode-lore-v2/package.json` defines private ESM package `lore-monorepo`, licensed `FSL-1.1-Apache-2.0`, described as `Monorepo root for Lore — three-tier memory architecture`; both `main` and export `"."` point to `./packages/opencode/src/index.ts`. * 🔴 (16:34) Root toolchain configuration uses `packageManager: pnpm@10.28.0`; Volta pins Node `24.16.0` and pnp…
* 🔴 (16:25) At commit `2ac698d65aa4690a694307e9cbdf44537ea9a4fb`, Git reported `fatal: path 'packages/client/src/promise/api/session.ts' does not exist`. * 🔴 (16:28) Under `packages/client/src/promise/` at commit `2ac698d65aa4690a694307e9cbdf44537ea9a4fb`, the relevant files found were `packages/client/src/promise/api.ts` and `packages/client/src/promise/generated/.httpapi-codegen.json`. * 🔴 (…
* 🔴 (16:18) User provided a State module defining `TransformCallback<Editor>`, `MakeEditor<State, Editor>`, Effect-based `Registration.dispose`, scoped `Transform<Editor>`, `Reload`, `Transformable<Editor>`, and `Failure { state: string; cause: unknown }`. * 🔴 (16:18) State registration grouping uses `CurrentGroup = Context.Reference<RegistrationGroup | undefined>("@opencode/State/CurrentGroup"…
* 🟡 (16:15) `/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules/@opencode/plugin/dist/promise/adapter.js` is a 443-line compiled Promise-to-Effect plugin adapter; source references at commit `2ac698d65aa4690a694307e9cbdf44537ea9a4fb` point to `packages/plugin/src/promise/adapter.ts`. * 🟡 (16:15) `makeStreams()` captures the Effect context and tracks each async iterator’s `close()` i…
* 🔴 (16:04) User asserted that the `--local` flag always disables remote mode: `opts.local === true` sets `config.remoteGateway = false` and `config.remoteGatewayAutoDetected = false`. * 🟡 (16:04) In `/home/byk/Code/opencode-lore-v2/packages/gateway/src/cli/start.ts`, `startGateway(opts, ioOverrides)` executes `startGatewayLocked()` under `withLifecycleLock("gateway-start", ...)`; CLI values ov…
* 🟡 (16:01) The provided Session title service defines `MAX_LENGTH = 100`, `MAX_CONTEXT_LENGTH = 8_000`, `MAX_FIRST_MESSAGE_LENGTH = 2_000`, and `titleChanged = Symbol("Session title changed")`; `truncate()` limits generated titles to 100 characters by retaining the first 97 and appending `...`, while `isUntitled()` delegates to `isExactRootFallback()` using the title and creation epoch millisec…
* 🔴 (15:59) User stated that user declines must “never become model-facing tool output.” In the provided `SessionModelRequest` implementation, `Permission.DeclinedError` and `QuestionTool.CancelledError` deliberately travel through the defect tunnel beneath blanket `mapError`, then `declineDefect()` resurfaces them exactly once as typed `ExecuteError` failures at the runner execution seam. * 🟡 …
* 🟡 (15:56) `/home/byk/Code/opencode/packages/core/src/plugin/internal.ts` defines `PluginInternal.Requirements` as the union of `AgentV2.Service`, `Catalog.Service`, `CommandV2.Service`, `Config.Service`, `EventV2.Service`, `FileSystem.Service`, `FSUtil.Service`, `Global.Service`, `HttpClient.HttpClient`, `Integration.Service`, `Location.Service`, `ModelsDev.Service`, `Npm.Service`, `Reference.…
* 🔴 (15:55) User specified that `error()` messages are “Always visible — these indicate real failures.” * 🟡 (15:55) `/home/byk/Code/opencode-lore-v2/packages/core/src/log.ts` lines 408–429 implement `maybeRotate()`: it opens and tightens the active log via `openLogFileForAppend(logPath)`, rotates only when `stat.size > LOG_MAX_BYTES`, removes the existing `${logPath}.1`, renames the active file…
* 🟡 (15:52) OpenCode’s ACP session-model implementation appears in `/home/byk/Code/opencode/packages/opencode/src/acp/service.ts`: `SetSessionModelRequest` at line 27, readonly `setSessionModel` signature at line 68, and `Effect.fn("ACP.setSessionModel")` implementation at line 467; `/home/byk/Code/opencode/packages/opencode/src/acp/agent.ts` imports the request type at line 16 and exposes `unst…
Date: Sep 9, 2026 * 🔴 (15:51) User specified that unreadable streaming request bodies are passed through and “never rewritten to gateway.” * 🔴 (15:51) User specified that the process-global original-fetch slot must contain the real pre-install fetch, “never the installed interceptor.” * 🔴 (15:51) User required project fallback metadata to remain “always self-consistent”: a project path is neve…
* 🟡 (15:47) Dependency lookup found no files at `/home/byk/Code/opencode-lore-v2/node_modules/@opencode`; the workspace-scoped modules instead reside under `/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules`, containing `.bin/`, `@loreai/`, `@opencode-ai/`, `@opencode/`, and `@types/`. * 🟡 (15:48) Inspected `/home/byk/Code/opencode-lore-v2/packages/opencode/node_modules/@opencode/p…
* 🟡 (15:47) The remaining `pnpm-lock.yaml` diff was read from `/home/byk/.local/share/opencode/tool-output/tool_086d9a529001mPJ3OxODe1p7FP`, covering lines 2,001–3,142 and reaching the end of the 3,142-line file. * 🟡 (15:47) The OpenTelemetry snapshot adds parallel `@opentelemetry/api@1.9.0` resolutions for `@opentelemetry/core@2.8.0`, `@opentelemetry/exporter-trace-otlp-http@0.214.0`, `@opente…
* 🟡 (15:47) The `pnpm-lock.yaml` diff continued via tool output `/home/byk/.local/share/opencode/tool-output/tool_086d9a529001mPJ3OxODe1p7FP`, showing lines 1,001–2,000 of 3,142. * 🟡 (15:47) Newly added npm-resolution packages requiring Node `^20.17.0 || >=22.9.0` are `npm-package-arg@13.0.2`, `npm-packlist@10.0.4`, `npm-pick-manifest@11.0.3`, `npm-registry-fetch@19.1.1`, `pacote@21.5.1` (`hasB…
* 🟡 (15:47) The displayed artifact is a `pnpm-lock.yaml` diff (`c9b41a1b23` → `b2983d8ba4`); the file contains 3,142 lines, and this tool result showed lines 1–1,000. * 🟡 (15:47) A workspace importer adds direct dependency `@opencode/plugin` with specifier `0.0.0-beta-19378` and resolved peer context `0.0.0-beta-19378(@opentelemetry/api-logs@0.214.0)(@opentelemetry/resources@2.7.1(@opentelemetr…
Date: September 9, 2026 * 🟡 (15:46) A truncated dependency-lockfile diff was saved in full at `/home/byk/.local/share/opencode/tool-output/tool_086d9a529001mPJ3OxODe1p7FP`. * 🟡 (15:46) The lockfile adds the OpenCode beta SDK family at exact version `0.0.0-beta-19378`: `@opencode/ai`, `@opencode/client`, `@opencode/plugin`, `@opencode/protocol`, `@opencode/schema`, and `@opencode/util`. * 🟡 (15…
Date: September 9, 2026 * 🔴 [requested-tests] (15:46) `packages/opencode/test/internal.test.ts` adds a test for `parseUpstreamExtraHeaders("x-empty:\r\nx-team: platform\r\ninvalid")`, expecting `[["x-empty", ""], ["x-team", "platform"]]`; this verifies empty header values and CRLF parsing while discarding an invalid colonless line. * 🔴 [requested-tests] (15:46) New `packages/opencode/test/packa…
Date: September 9, 2026 * 🔴 (15:46) `packages/opencode/package.json` adds the `./server` export with `types: "./src/server.ts"` and Bun/default runtime entry `./dist/server.js`; changes `build` from the raw-TypeScript no-op message to `tsx script/build.ts`; adds optional peer dependency `@opencode/plugin >=0.0.0`, dev dependency `@opencode/plugin 0.0.0-beta-19378`, and `dist/` to the published f…
Date: September 9, 2026 * 🔴 (15:44) User stated the repository is a colocated Jujutsu repo (`.jj/` and `.git/`): mutations must use `jj`, while Git tooling is permitted only for read-only operations or functionality unavailable in `jj`. * 🔴 (15:44) User stated Jujutsu operations “never fail on conflict”; `rebase`, `new`, and `squash` record conflicts in the resulting commit, after which `jj st`…
## September 9, 2026 🔴 (15:43) User identified the exact frozen Lore V2 port review target as repository `/home/byk/Code/opencode-lore-v2`, jj change `wlpqmtos`, commit `52e6687e1eae545273185978c57838d8782e4e92`, parent `429114122aa1170fd171aa3f0a2bb97e5a6bd6aa`, and `jj diff --git` SHA-256 `e58f101082669135fc7f3f11d466c22f696de14270c63747d021efecc8e0bf95`. 🔴 (15:43) User stated artifact hashes…