Revert "style: lint"

This reverts commit 98f40d7d0b.
This commit is contained in:
Neko Ayaka
2026-08-26 20:13:10 +08:00
parent cfcfc513ef
commit 146b3da65a
1625 changed files with 75440 additions and 75453 deletions
+15 -15
View File
@@ -7,12 +7,7 @@ import { ContextUpdateStrategy, Client as ServerClient } from '@proj-airi/server
import { nanoid } from 'nanoid'
export class Client {
private client: null | ServerClient<Events> = null
async appendContext(context: string): Promise<void> {
const id = nanoid()
this.send({ data: { contextId: id, id, strategy: ContextUpdateStrategy.AppendSelf, text: context }, type: 'context:update' })
}
private client: ServerClient<Events> | null = null
async connect(): Promise<boolean> {
try {
@@ -35,15 +30,6 @@ export class Client {
}
}
isConnected(): boolean {
return !!this.client
}
async replaceContext(context: string): Promise<void> {
const id = nanoid()
this.send({ data: { contextId: id, id, strategy: ContextUpdateStrategy.ReplaceSelf, text: context }, type: 'context:update' })
}
private async send(event: WebSocketEventOptionalSource<Events>): Promise<void> {
if (!this.client) {
useLogger().warn('Cannot send event: not connected to AIRI Server Channel')
@@ -58,4 +44,18 @@ export class Client {
useLogger().errorWithError('Failed to send event to AIRI:', error)
}
}
async replaceContext(context: string): Promise<void> {
const id = nanoid()
this.send({ type: 'context:update', data: { strategy: ContextUpdateStrategy.ReplaceSelf, text: context, id, contextId: id } })
}
async appendContext(context: string): Promise<void> {
const id = nanoid()
this.send({ type: 'context:update', data: { strategy: ContextUpdateStrategy.AppendSelf, text: context, id, contextId: id } })
}
isConnected(): boolean {
return !!this.client
}
}
@@ -22,31 +22,31 @@ export class ContextCollector {
// File information
const file = {
fileName: document.fileName,
languageId: document.languageId,
path: document.uri.fsPath,
languageId: document.languageId,
fileName: document.fileName,
workspaceFolder: this.getWorkspaceFolder(document.uri),
}
// Cursor position
const cursor = {
character: position.character,
line: position.line,
character: position.character,
}
// Selected text
const selection = editor.selection.isEmpty
? undefined
: {
end: {
character: editor.selection.end.character,
line: editor.selection.end.line,
},
start: {
character: editor.selection.start.character,
line: editor.selection.start.line,
},
text: document.getText(editor.selection),
start: {
line: editor.selection.start.line,
character: editor.selection.start.character,
},
end: {
line: editor.selection.end.line,
character: editor.selection.end.character,
},
}
// Current line
@@ -62,12 +62,12 @@ export class ContextCollector {
const git = await this.getGitInfo(document.uri)
return {
context,
currentLine,
cursor,
file,
git,
cursor,
selection,
currentLine,
context,
git,
timestamp: Date.now(),
}
}
@@ -96,13 +96,21 @@ export class ContextCollector {
after.push(document.lineAt(i).text)
}
return { after, before }
return { before, after }
}
/**
* Get workspace folder path
*/
private getWorkspaceFolder(uri: vscode.Uri): string | undefined {
const folder = vscode.workspace.getWorkspaceFolder(uri)
return folder?.uri.fsPath
}
/**
* Get Git information (simplified)
*/
private async getGitInfo(uri: vscode.Uri): Promise<undefined | { branch: string, isDirty: boolean }> {
private async getGitInfo(uri: vscode.Uri): Promise<{ branch: string, isDirty: boolean } | undefined> {
try {
const gitExtension = vscode.extensions.getExtension('vscode.git')?.exports
if (!gitExtension)
@@ -122,12 +130,4 @@ export class ContextCollector {
return undefined
}
}
/**
* Get workspace folder path
*/
private getWorkspaceFolder(uri: vscode.Uri): string | undefined {
const folder = vscode.workspace.getWorkspaceFolder(uri)
return folder?.uri.fsPath
}
}
@@ -50,44 +50,82 @@ export async function activate(context: vscode.ExtensionContext) {
})
const extension = injeca.provide('extension', {
dependsOn: { client, vscodeContext, contextCollector, eventListeners, lifecycle, controlLoopInterval },
build: ({ dependsOn }) => setup({ ...dependsOn, isEnabled, sendInterval }),
dependsOn: { client, contextCollector, controlLoopInterval, eventListeners, lifecycle, vscodeContext },
})
injeca.invoke({
callback: noop,
dependsOn: { extension },
callback: noop,
})
await injeca.start()
}
/**
* Deactivate the plugin
*/
export async function deactivate() {
const { client } = await injeca.resolve({ client: { key: 'proj-airi:client' } as unknown as ProvidedBy<Client> })
const { eventListeners } = await injeca.resolve({ eventListeners: { key: 'self:event-listeners' } as unknown as ProvidedBy<vscode.Disposable[]> })
const { controlLoopInterval } = await injeca.resolve({ controlLoopInterval: { key: 'self:control-loop:interval:send' } as unknown as ProvidedBy<IntervalHandle> })
async function setup(params: {
client: Client
vscodeContext: vscode.ExtensionContext
contextCollector: ContextCollector
eventListeners: vscode.Disposable[]
lifecycle: Lifecycle
controlLoopInterval: IntervalHandle
isEnabled: boolean
sendInterval: number
}) {
// Connect to Airi Channel Server
if (params.isEnabled) {
const connected = await params.client.connect()
if (connected) {
window.showInformationMessage('AIRI Server Channel connected!')
}
else {
window.showWarningMessage('AIRI Server Channel connection failed!')
}
}
unregisterListeners({ controlLoopInterval, eventListeners })
client?.disconnect()
useLogger().log('AIRI deactivated!')
// Register commands
params.vscodeContext.subscriptions.push(
commands.registerCommand('airi-vscode.enable', async () => {
params.isEnabled = true
await params.client.connect()
await registerListeners({ ...params })
window.showInformationMessage('AIRI enabled!')
}),
commands.registerCommand('airi-vscode.disable', () => {
params.isEnabled = false
unregisterListeners({ eventListeners: params.eventListeners, controlLoopInterval: params.controlLoopInterval })
params.client.disconnect()
window.showInformationMessage('AIRI disabled!')
}),
commands.registerCommand('airi-vscode.status', () => {
const status = params.isEnabled && params.client ? 'Connected' : 'Disconnected'
window.showInformationMessage(`AIRI Server Channel status: ${status}.`)
}),
)
// Register event listeners if enabled
if (params.isEnabled) {
await registerListeners({ ...params })
}
useLogger().log('AIRI activated successfully')
}
/**
* Register event listeners for file save and editor switch
*/
async function registerListeners(params: {
client: Client
contextCollector: ContextCollector
controlLoopInterval: IntervalHandle
eventListeners: vscode.Disposable[]
isEnabled: boolean
lifecycle: Lifecycle
eventListeners: vscode.Disposable[]
client: Client
controlLoopInterval: IntervalHandle
isEnabled: boolean
sendInterval: number
}) {
unregisterListeners({ controlLoopInterval: params.controlLoopInterval, eventListeners: params.eventListeners })
unregisterListeners({ eventListeners: params.eventListeners, controlLoopInterval: params.controlLoopInterval })
// File save event
params.eventListeners.push(
@@ -137,66 +175,24 @@ async function registerListeners(params: {
}
}
async function setup(params: {
client: Client
contextCollector: ContextCollector
controlLoopInterval: IntervalHandle
eventListeners: vscode.Disposable[]
isEnabled: boolean
lifecycle: Lifecycle
sendInterval: number
vscodeContext: vscode.ExtensionContext
}) {
// Connect to Airi Channel Server
if (params.isEnabled) {
const connected = await params.client.connect()
if (connected) {
window.showInformationMessage('AIRI Server Channel connected!')
}
else {
window.showWarningMessage('AIRI Server Channel connection failed!')
}
}
// Register commands
params.vscodeContext.subscriptions.push(
commands.registerCommand('airi-vscode.enable', async () => {
params.isEnabled = true
await params.client.connect()
await registerListeners({ ...params })
window.showInformationMessage('AIRI enabled!')
}),
commands.registerCommand('airi-vscode.disable', () => {
params.isEnabled = false
unregisterListeners({ controlLoopInterval: params.controlLoopInterval, eventListeners: params.eventListeners })
params.client.disconnect()
window.showInformationMessage('AIRI disabled!')
}),
commands.registerCommand('airi-vscode.status', () => {
const status = params.isEnabled && params.client ? 'Connected' : 'Disconnected'
window.showInformationMessage(`AIRI Server Channel status: ${status}.`)
}),
)
// Register event listeners if enabled
if (params.isEnabled) {
await registerListeners({ ...params })
}
useLogger().log('AIRI activated successfully')
/**
* Unregister all event listeners
*/
function unregisterListeners(params: { eventListeners: vscode.Disposable[], controlLoopInterval: IntervalHandle }) {
params.eventListeners.forEach(listener => listener.dispose())
params.eventListeners = []
stopMonitoring({ controlLoopInterval: params.controlLoopInterval })
}
/**
* Start monitoring the coding context
*/
function startMonitoring(params: {
client: Client
contextCollector: ContextCollector
lifecycle: Lifecycle
client: Client
controlLoopInterval: IntervalHandle
isEnabled: boolean
lifecycle: Lifecycle
sendInterval: number
}) {
stopMonitoring({ controlLoopInterval: params.controlLoopInterval })
@@ -233,10 +229,14 @@ function stopMonitoring(params: { controlLoopInterval: IntervalHandle }) {
}
/**
* Unregister all event listeners
* Deactivate the plugin
*/
function unregisterListeners(params: { controlLoopInterval: IntervalHandle, eventListeners: vscode.Disposable[] }) {
params.eventListeners.forEach(listener => listener.dispose())
params.eventListeners = []
stopMonitoring({ controlLoopInterval: params.controlLoopInterval })
export async function deactivate() {
const { client } = await injeca.resolve({ client: { key: 'proj-airi:client' } as unknown as ProvidedBy<Client> })
const { eventListeners } = await injeca.resolve({ eventListeners: { key: 'self:event-listeners' } as unknown as ProvidedBy<vscode.Disposable[]> })
const { controlLoopInterval } = await injeca.resolve({ controlLoopInterval: { key: 'self:control-loop:interval:send' } as unknown as ProvidedBy<IntervalHandle> })
unregisterListeners({ eventListeners, controlLoopInterval })
client?.disconnect()
useLogger().log('AIRI deactivated!')
}
+40 -40
View File
@@ -2,6 +2,44 @@
* Coding context information
*/
export interface CodingContext {
/**
* File information
*
* @example {
* "path": "/home/neko/Git/github.com/moeru-ai/airi/package.json",
* "languageId": "json",
* "fileName": "/home/neko/Git/github.com/moeru-ai/airi/package.json"
* }
*/
file: {
path: string
languageId: string
fileName: string
workspaceFolder?: string
}
/**
* Cursor position
*
* {
* "line": 5,
* "character": 35
* }
*/
cursor: {
line: number
character: number
}
/** Selected text */
selection?: {
text: string
start: { line: number, character: number }
end: { line: number, character: number }
}
/** Current line */
currentLine: {
lineNumber: number
text: string
}
/**
* Context (previous and next N lines)
*
@@ -23,52 +61,14 @@ export interface CodingContext {
* }
*/
context: {
after: string[]
before: string[]
}
/** Current line */
currentLine: {
lineNumber: number
text: string
}
/**
* Cursor position
*
* {
* "line": 5,
* "character": 35
* }
*/
cursor: {
character: number
line: number
}
/**
* File information
*
* @example {
* "path": "/home/neko/Git/github.com/moeru-ai/airi/package.json",
* "languageId": "json",
* "fileName": "/home/neko/Git/github.com/moeru-ai/airi/package.json"
* }
*/
file: {
fileName: string
languageId: string
path: string
workspaceFolder?: string
after: string[]
}
/** Git information */
git?: {
branch: string
isDirty: boolean
}
/** Selected text */
selection?: {
end: { character: number, line: number }
start: { character: number, line: number }
text: string
}
/**
* Timestamp
*
@@ -81,6 +81,6 @@ export interface CodingContext {
* Event types sent to Airi
*/
export interface Events {
data: CodingContext
type: 'coding:context' | 'coding:save' | 'coding:switch-file'
data: CodingContext
}