@xortex/xcode 3.1.0 → 3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/xcode +1 -1
- package/entrypoints/cli.tsx +1 -1
- package/macro.ts +1 -1
- package/package.json +58 -1
- package/INSTALLATION.md +0 -285
- package/QUICKSTART.md +0 -151
- package/SYSTEM_PROMPT.md +0 -583
- package/SYSTEM_PROMPT_EXTRACTED.md +0 -1
- package/Untitled +0 -1
- package/bun.lock +0 -645
- package/extract_prompt.ts +0 -304
- package/inspect.js +0 -7
- package/install.sh +0 -221
- package/moreright/useMoreRight.tsx +0 -26
- package/native-ts/color-diff/index.ts +0 -999
- package/native-ts/file-index/index.ts +0 -370
- package/native-ts/yoga-layout/enums.ts +0 -134
- package/native-ts/yoga-layout/index.ts +0 -2578
- package/outputStyles/loadOutputStylesDir.ts +0 -98
- package/patch-box.js +0 -54
- package/patch-compact.js +0 -13
- package/patch-condensed-center.js +0 -13
- package/patch-condensed-row.js +0 -13
- package/patch-condensed.js +0 -13
- package/patch-final.js +0 -58
- package/patch-input-body.js +0 -46
- package/patch-input-body2.js +0 -35
- package/patch-input-style.js +0 -13
- package/patch-input-width.js +0 -13
- package/patch-layout.js +0 -87
- package/patch-logo-row.js +0 -12
- package/patch-width.js +0 -13
- package/patch-width2.js +0 -13
- package/patch2.js +0 -74
- package/patch3.js +0 -13
- package/plugins/builtinPlugins.ts +0 -159
- package/plugins/bundled/index.ts +0 -23
- package/public/claude-files.png +0 -0
- package/public/leak-tweet.png +0 -0
- package/server/createDirectConnectSession.ts +0 -88
- package/server/directConnectManager.ts +0 -213
- package/server/types.ts +0 -57
- package/stub_types.sh +0 -13
- package/vim/motions.ts +0 -82
- package/vim/operators.ts +0 -556
- package/vim/textObjects.ts +0 -186
- package/vim/transitions.ts +0 -490
- package/vim/types.ts +0 -199
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Built-in Plugin Registry
|
|
3
|
-
*
|
|
4
|
-
* Manages built-in plugins that ship with the CLI and can be enabled/disabled
|
|
5
|
-
* by users via the /plugin UI.
|
|
6
|
-
*
|
|
7
|
-
* Built-in plugins differ from bundled skills (src/skills/bundled/) in that:
|
|
8
|
-
* - They appear in the /plugin UI under a "Built-in" section
|
|
9
|
-
* - Users can enable/disable them (persisted to user settings)
|
|
10
|
-
* - They can provide multiple components (skills, hooks, MCP servers)
|
|
11
|
-
*
|
|
12
|
-
* Plugin IDs use the format `{name}@builtin` to distinguish them from
|
|
13
|
-
* marketplace plugins (`{name}@{marketplace}`).
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import type { Command } from '../commands.js'
|
|
17
|
-
import type { BundledSkillDefinition } from '../skills/bundledSkills.js'
|
|
18
|
-
import type { BuiltinPluginDefinition, LoadedPlugin } from '../types/plugin.js'
|
|
19
|
-
import { getSettings_DEPRECATED } from '../utils/settings/settings.js'
|
|
20
|
-
|
|
21
|
-
const BUILTIN_PLUGINS: Map<string, BuiltinPluginDefinition> = new Map()
|
|
22
|
-
|
|
23
|
-
export const BUILTIN_MARKETPLACE_NAME = 'builtin'
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Register a built-in plugin. Call this from initBuiltinPlugins() at startup.
|
|
27
|
-
*/
|
|
28
|
-
export function registerBuiltinPlugin(
|
|
29
|
-
definition: BuiltinPluginDefinition,
|
|
30
|
-
): void {
|
|
31
|
-
BUILTIN_PLUGINS.set(definition.name, definition)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Check if a plugin ID represents a built-in plugin (ends with @builtin).
|
|
36
|
-
*/
|
|
37
|
-
export function isBuiltinPluginId(pluginId: string): boolean {
|
|
38
|
-
return pluginId.endsWith(`@${BUILTIN_MARKETPLACE_NAME}`)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Get a specific built-in plugin definition by name.
|
|
43
|
-
* Useful for the /plugin UI to show the skills/hooks/MCP list without
|
|
44
|
-
* a marketplace lookup.
|
|
45
|
-
*/
|
|
46
|
-
export function getBuiltinPluginDefinition(
|
|
47
|
-
name: string,
|
|
48
|
-
): BuiltinPluginDefinition | undefined {
|
|
49
|
-
return BUILTIN_PLUGINS.get(name)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Get all registered built-in plugins as LoadedPlugin objects, split into
|
|
54
|
-
* enabled/disabled based on user settings (with defaultEnabled as fallback).
|
|
55
|
-
* Plugins whose isAvailable() returns false are omitted entirely.
|
|
56
|
-
*/
|
|
57
|
-
export function getBuiltinPlugins(): {
|
|
58
|
-
enabled: LoadedPlugin[]
|
|
59
|
-
disabled: LoadedPlugin[]
|
|
60
|
-
} {
|
|
61
|
-
const settings = getSettings_DEPRECATED()
|
|
62
|
-
const enabled: LoadedPlugin[] = []
|
|
63
|
-
const disabled: LoadedPlugin[] = []
|
|
64
|
-
|
|
65
|
-
for (const [name, definition] of BUILTIN_PLUGINS) {
|
|
66
|
-
if (definition.isAvailable && !definition.isAvailable()) {
|
|
67
|
-
continue
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const pluginId = `${name}@${BUILTIN_MARKETPLACE_NAME}`
|
|
71
|
-
const userSetting = settings?.enabledPlugins?.[pluginId]
|
|
72
|
-
// Enabled state: user preference > plugin default > true
|
|
73
|
-
const isEnabled =
|
|
74
|
-
userSetting !== undefined
|
|
75
|
-
? userSetting === true
|
|
76
|
-
: (definition.defaultEnabled ?? true)
|
|
77
|
-
|
|
78
|
-
const plugin: LoadedPlugin = {
|
|
79
|
-
name,
|
|
80
|
-
manifest: {
|
|
81
|
-
name,
|
|
82
|
-
description: definition.description,
|
|
83
|
-
version: definition.version,
|
|
84
|
-
},
|
|
85
|
-
path: BUILTIN_MARKETPLACE_NAME, // sentinel — no filesystem path
|
|
86
|
-
source: pluginId,
|
|
87
|
-
repository: pluginId,
|
|
88
|
-
enabled: isEnabled,
|
|
89
|
-
isBuiltin: true,
|
|
90
|
-
hooksConfig: definition.hooks,
|
|
91
|
-
mcpServers: definition.mcpServers,
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (isEnabled) {
|
|
95
|
-
enabled.push(plugin)
|
|
96
|
-
} else {
|
|
97
|
-
disabled.push(plugin)
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return { enabled, disabled }
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Get skills from enabled built-in plugins as Command objects.
|
|
106
|
-
* Skills from disabled plugins are not returned.
|
|
107
|
-
*/
|
|
108
|
-
export function getBuiltinPluginSkillCommands(): Command[] {
|
|
109
|
-
const { enabled } = getBuiltinPlugins()
|
|
110
|
-
const commands: Command[] = []
|
|
111
|
-
|
|
112
|
-
for (const plugin of enabled) {
|
|
113
|
-
const definition = BUILTIN_PLUGINS.get(plugin.name)
|
|
114
|
-
if (!definition?.skills) continue
|
|
115
|
-
for (const skill of definition.skills) {
|
|
116
|
-
commands.push(skillDefinitionToCommand(skill))
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return commands
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Clear built-in plugins registry (for testing).
|
|
125
|
-
*/
|
|
126
|
-
export function clearBuiltinPlugins(): void {
|
|
127
|
-
BUILTIN_PLUGINS.clear()
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// --
|
|
131
|
-
|
|
132
|
-
function skillDefinitionToCommand(definition: BundledSkillDefinition): Command {
|
|
133
|
-
return {
|
|
134
|
-
type: 'prompt',
|
|
135
|
-
name: definition.name,
|
|
136
|
-
description: definition.description,
|
|
137
|
-
hasUserSpecifiedDescription: true,
|
|
138
|
-
allowedTools: definition.allowedTools ?? [],
|
|
139
|
-
argumentHint: definition.argumentHint,
|
|
140
|
-
whenToUse: definition.whenToUse,
|
|
141
|
-
model: definition.model,
|
|
142
|
-
disableModelInvocation: definition.disableModelInvocation ?? false,
|
|
143
|
-
userInvocable: definition.userInvocable ?? true,
|
|
144
|
-
contentLength: 0,
|
|
145
|
-
// 'bundled' not 'builtin' — 'builtin' in Command.source means hardcoded
|
|
146
|
-
// slash commands (/help, /clear). Using 'bundled' keeps these skills in
|
|
147
|
-
// the Skill tool's listing, analytics name logging, and prompt-truncation
|
|
148
|
-
// exemption. The user-toggleable aspect is tracked on LoadedPlugin.isBuiltin.
|
|
149
|
-
source: 'bundled',
|
|
150
|
-
loadedFrom: 'bundled',
|
|
151
|
-
hooks: definition.hooks,
|
|
152
|
-
context: definition.context,
|
|
153
|
-
agent: definition.agent,
|
|
154
|
-
isEnabled: definition.isEnabled ?? (() => true),
|
|
155
|
-
isHidden: !(definition.userInvocable ?? true),
|
|
156
|
-
progressMessage: 'running',
|
|
157
|
-
getPromptForCommand: definition.getPromptForCommand,
|
|
158
|
-
}
|
|
159
|
-
}
|
package/plugins/bundled/index.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Built-in Plugin Initialization
|
|
3
|
-
*
|
|
4
|
-
* Initializes built-in plugins that ship with the CLI and appear in the
|
|
5
|
-
* /plugin UI for users to enable/disable.
|
|
6
|
-
*
|
|
7
|
-
* Not all bundled features should be built-in plugins — use this for
|
|
8
|
-
* features that users should be able to explicitly enable/disable. For
|
|
9
|
-
* features with complex setup or automatic-enabling logic (e.g.
|
|
10
|
-
* claude-in-chrome), use src/skills/bundled/ instead.
|
|
11
|
-
*
|
|
12
|
-
* To add a new built-in plugin:
|
|
13
|
-
* 1. Import registerBuiltinPlugin from '../builtinPlugins.js'
|
|
14
|
-
* 2. Call registerBuiltinPlugin() with the plugin definition here
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Initialize built-in plugins. Called during CLI startup.
|
|
19
|
-
*/
|
|
20
|
-
export function initBuiltinPlugins(): void {
|
|
21
|
-
// No built-in plugins registered yet — this is the scaffolding for
|
|
22
|
-
// migrating bundled skills that should be user-toggleable.
|
|
23
|
-
}
|
package/public/claude-files.png
DELETED
|
Binary file
|
package/public/leak-tweet.png
DELETED
|
Binary file
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/* eslint-disable eslint-plugin-n/no-unsupported-features/node-builtins */
|
|
2
|
-
|
|
3
|
-
import { errorMessage } from '../utils/errors.js'
|
|
4
|
-
import { jsonStringify } from '../utils/slowOperations.js'
|
|
5
|
-
import type { DirectConnectConfig } from './directConnectManager.js'
|
|
6
|
-
import { connectResponseSchema } from './types.js'
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Errors thrown by createDirectConnectSession when the connection fails.
|
|
10
|
-
*/
|
|
11
|
-
export class DirectConnectError extends Error {
|
|
12
|
-
constructor(message: string) {
|
|
13
|
-
super(message)
|
|
14
|
-
this.name = 'DirectConnectError'
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Create a session on a direct-connect server.
|
|
20
|
-
*
|
|
21
|
-
* Posts to `${serverUrl}/sessions`, validates the response, and returns
|
|
22
|
-
* a DirectConnectConfig ready for use by the REPL or headless runner.
|
|
23
|
-
*
|
|
24
|
-
* Throws DirectConnectError on network, HTTP, or response-parsing failures.
|
|
25
|
-
*/
|
|
26
|
-
export async function createDirectConnectSession({
|
|
27
|
-
serverUrl,
|
|
28
|
-
authToken,
|
|
29
|
-
cwd,
|
|
30
|
-
dangerouslySkipPermissions,
|
|
31
|
-
}: {
|
|
32
|
-
serverUrl: string
|
|
33
|
-
authToken?: string
|
|
34
|
-
cwd: string
|
|
35
|
-
dangerouslySkipPermissions?: boolean
|
|
36
|
-
}): Promise<{
|
|
37
|
-
config: DirectConnectConfig
|
|
38
|
-
workDir?: string
|
|
39
|
-
}> {
|
|
40
|
-
const headers: Record<string, string> = {
|
|
41
|
-
'content-type': 'application/json',
|
|
42
|
-
}
|
|
43
|
-
if (authToken) {
|
|
44
|
-
headers['authorization'] = `Bearer ${authToken}`
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
let resp: Response
|
|
48
|
-
try {
|
|
49
|
-
resp = await fetch(`${serverUrl}/sessions`, {
|
|
50
|
-
method: 'POST',
|
|
51
|
-
headers,
|
|
52
|
-
body: jsonStringify({
|
|
53
|
-
cwd,
|
|
54
|
-
...(dangerouslySkipPermissions && {
|
|
55
|
-
dangerously_skip_permissions: true,
|
|
56
|
-
}),
|
|
57
|
-
}),
|
|
58
|
-
})
|
|
59
|
-
} catch (err) {
|
|
60
|
-
throw new DirectConnectError(
|
|
61
|
-
`Failed to connect to server at ${serverUrl}: ${errorMessage(err)}`,
|
|
62
|
-
)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (!resp.ok) {
|
|
66
|
-
throw new DirectConnectError(
|
|
67
|
-
`Failed to create session: ${resp.status} ${resp.statusText}`,
|
|
68
|
-
)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const result = connectResponseSchema().safeParse(await resp.json())
|
|
72
|
-
if (!result.success) {
|
|
73
|
-
throw new DirectConnectError(
|
|
74
|
-
`Invalid session response: ${result.error.message}`,
|
|
75
|
-
)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const data = result.data
|
|
79
|
-
return {
|
|
80
|
-
config: {
|
|
81
|
-
serverUrl,
|
|
82
|
-
sessionId: data.session_id,
|
|
83
|
-
wsUrl: data.ws_url,
|
|
84
|
-
authToken,
|
|
85
|
-
},
|
|
86
|
-
workDir: data.work_dir,
|
|
87
|
-
}
|
|
88
|
-
}
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
/* eslint-disable eslint-plugin-n/no-unsupported-features/node-builtins */
|
|
2
|
-
|
|
3
|
-
import type { SDKMessage } from '../entrypoints/agentSdkTypes.js'
|
|
4
|
-
import type {
|
|
5
|
-
SDKControlPermissionRequest,
|
|
6
|
-
StdoutMessage,
|
|
7
|
-
} from '../entrypoints/sdk/controlTypes.js'
|
|
8
|
-
import type { RemotePermissionResponse } from '../remote/RemoteSessionManager.js'
|
|
9
|
-
import { logForDebugging } from '../utils/debug.js'
|
|
10
|
-
import { jsonParse, jsonStringify } from '../utils/slowOperations.js'
|
|
11
|
-
import type { RemoteMessageContent } from '../utils/teleport/api.js'
|
|
12
|
-
|
|
13
|
-
export type DirectConnectConfig = {
|
|
14
|
-
serverUrl: string
|
|
15
|
-
sessionId: string
|
|
16
|
-
wsUrl: string
|
|
17
|
-
authToken?: string
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export type DirectConnectCallbacks = {
|
|
21
|
-
onMessage: (message: SDKMessage) => void
|
|
22
|
-
onPermissionRequest: (
|
|
23
|
-
request: SDKControlPermissionRequest,
|
|
24
|
-
requestId: string,
|
|
25
|
-
) => void
|
|
26
|
-
onConnected?: () => void
|
|
27
|
-
onDisconnected?: () => void
|
|
28
|
-
onError?: (error: Error) => void
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function isStdoutMessage(value: unknown): value is StdoutMessage {
|
|
32
|
-
return (
|
|
33
|
-
typeof value === 'object' &&
|
|
34
|
-
value !== null &&
|
|
35
|
-
'type' in value &&
|
|
36
|
-
typeof value.type === 'string'
|
|
37
|
-
)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export class DirectConnectSessionManager {
|
|
41
|
-
private ws: WebSocket | null = null
|
|
42
|
-
private config: DirectConnectConfig
|
|
43
|
-
private callbacks: DirectConnectCallbacks
|
|
44
|
-
|
|
45
|
-
constructor(config: DirectConnectConfig, callbacks: DirectConnectCallbacks) {
|
|
46
|
-
this.config = config
|
|
47
|
-
this.callbacks = callbacks
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
connect(): void {
|
|
51
|
-
const headers: Record<string, string> = {}
|
|
52
|
-
if (this.config.authToken) {
|
|
53
|
-
headers['authorization'] = `Bearer ${this.config.authToken}`
|
|
54
|
-
}
|
|
55
|
-
// Bun's WebSocket supports headers option but the DOM typings don't
|
|
56
|
-
this.ws = new WebSocket(this.config.wsUrl, {
|
|
57
|
-
headers,
|
|
58
|
-
} as unknown as string[])
|
|
59
|
-
|
|
60
|
-
this.ws.addEventListener('open', () => {
|
|
61
|
-
this.callbacks.onConnected?.()
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
this.ws.addEventListener('message', event => {
|
|
65
|
-
const data = typeof event.data === 'string' ? event.data : ''
|
|
66
|
-
const lines = data.split('\n').filter((l: string) => l.trim())
|
|
67
|
-
|
|
68
|
-
for (const line of lines) {
|
|
69
|
-
let raw: unknown
|
|
70
|
-
try {
|
|
71
|
-
raw = jsonParse(line)
|
|
72
|
-
} catch {
|
|
73
|
-
continue
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (!isStdoutMessage(raw)) {
|
|
77
|
-
continue
|
|
78
|
-
}
|
|
79
|
-
const parsed = raw
|
|
80
|
-
|
|
81
|
-
// Handle control requests (permission requests)
|
|
82
|
-
if (parsed.type === 'control_request') {
|
|
83
|
-
if (parsed.request.subtype === 'can_use_tool') {
|
|
84
|
-
this.callbacks.onPermissionRequest(
|
|
85
|
-
parsed.request,
|
|
86
|
-
parsed.request_id,
|
|
87
|
-
)
|
|
88
|
-
} else {
|
|
89
|
-
// Send an error response for unrecognized subtypes so the
|
|
90
|
-
// server doesn't hang waiting for a reply that never comes.
|
|
91
|
-
logForDebugging(
|
|
92
|
-
`[DirectConnect] Unsupported control request subtype: ${parsed.request.subtype}`,
|
|
93
|
-
)
|
|
94
|
-
this.sendErrorResponse(
|
|
95
|
-
parsed.request_id,
|
|
96
|
-
`Unsupported control request subtype: ${parsed.request.subtype}`,
|
|
97
|
-
)
|
|
98
|
-
}
|
|
99
|
-
continue
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Forward SDK messages (assistant, result, system, etc.)
|
|
103
|
-
if (
|
|
104
|
-
parsed.type !== 'control_response' &&
|
|
105
|
-
parsed.type !== 'keep_alive' &&
|
|
106
|
-
parsed.type !== 'control_cancel_request' &&
|
|
107
|
-
parsed.type !== 'streamlined_text' &&
|
|
108
|
-
parsed.type !== 'streamlined_tool_use_summary' &&
|
|
109
|
-
!(parsed.type === 'system' && parsed.subtype === 'post_turn_summary')
|
|
110
|
-
) {
|
|
111
|
-
this.callbacks.onMessage(parsed)
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
this.ws.addEventListener('close', () => {
|
|
117
|
-
this.callbacks.onDisconnected?.()
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
this.ws.addEventListener('error', () => {
|
|
121
|
-
this.callbacks.onError?.(new Error('WebSocket connection error'))
|
|
122
|
-
})
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
sendMessage(content: RemoteMessageContent): boolean {
|
|
126
|
-
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
127
|
-
return false
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Must match SDKUserMessage format expected by `--input-format stream-json`
|
|
131
|
-
const message = jsonStringify({
|
|
132
|
-
type: 'user',
|
|
133
|
-
message: {
|
|
134
|
-
role: 'user',
|
|
135
|
-
content: content,
|
|
136
|
-
},
|
|
137
|
-
parent_tool_use_id: null,
|
|
138
|
-
session_id: '',
|
|
139
|
-
})
|
|
140
|
-
this.ws.send(message)
|
|
141
|
-
return true
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
respondToPermissionRequest(
|
|
145
|
-
requestId: string,
|
|
146
|
-
result: RemotePermissionResponse,
|
|
147
|
-
): void {
|
|
148
|
-
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
149
|
-
return
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Must match SDKControlResponse format expected by StructuredIO
|
|
153
|
-
const response = jsonStringify({
|
|
154
|
-
type: 'control_response',
|
|
155
|
-
response: {
|
|
156
|
-
subtype: 'success',
|
|
157
|
-
request_id: requestId,
|
|
158
|
-
response: {
|
|
159
|
-
behavior: result.behavior,
|
|
160
|
-
...(result.behavior === 'allow'
|
|
161
|
-
? { updatedInput: result.updatedInput }
|
|
162
|
-
: { message: result.message }),
|
|
163
|
-
},
|
|
164
|
-
},
|
|
165
|
-
})
|
|
166
|
-
this.ws.send(response)
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Send an interrupt signal to cancel the current request
|
|
171
|
-
*/
|
|
172
|
-
sendInterrupt(): void {
|
|
173
|
-
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
174
|
-
return
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Must match SDKControlRequest format expected by StructuredIO
|
|
178
|
-
const request = jsonStringify({
|
|
179
|
-
type: 'control_request',
|
|
180
|
-
request_id: crypto.randomUUID(),
|
|
181
|
-
request: {
|
|
182
|
-
subtype: 'interrupt',
|
|
183
|
-
},
|
|
184
|
-
})
|
|
185
|
-
this.ws.send(request)
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
private sendErrorResponse(requestId: string, error: string): void {
|
|
189
|
-
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
190
|
-
return
|
|
191
|
-
}
|
|
192
|
-
const response = jsonStringify({
|
|
193
|
-
type: 'control_response',
|
|
194
|
-
response: {
|
|
195
|
-
subtype: 'error',
|
|
196
|
-
request_id: requestId,
|
|
197
|
-
error,
|
|
198
|
-
},
|
|
199
|
-
})
|
|
200
|
-
this.ws.send(response)
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
disconnect(): void {
|
|
204
|
-
if (this.ws) {
|
|
205
|
-
this.ws.close()
|
|
206
|
-
this.ws = null
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
isConnected(): boolean {
|
|
211
|
-
return this.ws?.readyState === WebSocket.OPEN
|
|
212
|
-
}
|
|
213
|
-
}
|
package/server/types.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import type { ChildProcess } from 'child_process'
|
|
2
|
-
import { z } from 'zod/v4'
|
|
3
|
-
import { lazySchema } from '../utils/lazySchema.js'
|
|
4
|
-
|
|
5
|
-
export const connectResponseSchema = lazySchema(() =>
|
|
6
|
-
z.object({
|
|
7
|
-
session_id: z.string(),
|
|
8
|
-
ws_url: z.string(),
|
|
9
|
-
work_dir: z.string().optional(),
|
|
10
|
-
}),
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
export type ServerConfig = {
|
|
14
|
-
port: number
|
|
15
|
-
host: string
|
|
16
|
-
authToken: string
|
|
17
|
-
unix?: string
|
|
18
|
-
/** Idle timeout for detached sessions (ms). 0 = never expire. */
|
|
19
|
-
idleTimeoutMs?: number
|
|
20
|
-
/** Maximum number of concurrent sessions. */
|
|
21
|
-
maxSessions?: number
|
|
22
|
-
/** Default workspace directory for sessions that don't specify cwd. */
|
|
23
|
-
workspace?: string
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export type SessionState =
|
|
27
|
-
| 'starting'
|
|
28
|
-
| 'running'
|
|
29
|
-
| 'detached'
|
|
30
|
-
| 'stopping'
|
|
31
|
-
| 'stopped'
|
|
32
|
-
|
|
33
|
-
export type SessionInfo = {
|
|
34
|
-
id: string
|
|
35
|
-
status: SessionState
|
|
36
|
-
createdAt: number
|
|
37
|
-
workDir: string
|
|
38
|
-
process: ChildProcess | null
|
|
39
|
-
sessionKey?: string
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Stable session key → session metadata. Persisted to ~/.claude/server-sessions.json
|
|
44
|
-
* so sessions can be resumed across server restarts.
|
|
45
|
-
*/
|
|
46
|
-
export type SessionIndexEntry = {
|
|
47
|
-
/** Server-assigned session ID (matches the subprocess's claude session). */
|
|
48
|
-
sessionId: string
|
|
49
|
-
/** The claude transcript session ID for --resume. Same as sessionId for direct sessions. */
|
|
50
|
-
transcriptSessionId: string
|
|
51
|
-
cwd: string
|
|
52
|
-
permissionMode?: string
|
|
53
|
-
createdAt: number
|
|
54
|
-
lastActiveAt: number
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export type SessionIndex = Record<string, SessionIndexEntry>
|
package/stub_types.sh
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Auto-generate stub types.ts files for all missing modules
|
|
3
|
-
|
|
4
|
-
cd /Users/vedantmahajan/Desktop/Xortex/claude-code
|
|
5
|
-
|
|
6
|
-
# Find all directories that need types.ts
|
|
7
|
-
find . -name "*.ts" -o -name "*.tsx" | xargs grep -h "from './types.js'" 2>/dev/null | sed "s/.*from '\([^']*\)'.*/\1/" | sort -u | while read path; do
|
|
8
|
-
dir=$(dirname "$path")
|
|
9
|
-
if [ ! -f "$dir/types.ts" ] && [ ! -f "$dir/types.js" ]; then
|
|
10
|
-
echo "// Stub types file for $dir" > "$dir/types.ts"
|
|
11
|
-
echo "Created stub: $dir/types.ts"
|
|
12
|
-
fi
|
|
13
|
-
done
|
package/vim/motions.ts
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Vim Motion Functions
|
|
3
|
-
*
|
|
4
|
-
* Pure functions for resolving vim motions to cursor positions.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { Cursor } from '../utils/Cursor.js'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Resolve a motion to a target cursor position.
|
|
11
|
-
* Does not modify anything - pure calculation.
|
|
12
|
-
*/
|
|
13
|
-
export function resolveMotion(
|
|
14
|
-
key: string,
|
|
15
|
-
cursor: Cursor,
|
|
16
|
-
count: number,
|
|
17
|
-
): Cursor {
|
|
18
|
-
let result = cursor
|
|
19
|
-
for (let i = 0; i < count; i++) {
|
|
20
|
-
const next = applySingleMotion(key, result)
|
|
21
|
-
if (next.equals(result)) break
|
|
22
|
-
result = next
|
|
23
|
-
}
|
|
24
|
-
return result
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Apply a single motion step.
|
|
29
|
-
*/
|
|
30
|
-
function applySingleMotion(key: string, cursor: Cursor): Cursor {
|
|
31
|
-
switch (key) {
|
|
32
|
-
case 'h':
|
|
33
|
-
return cursor.left()
|
|
34
|
-
case 'l':
|
|
35
|
-
return cursor.right()
|
|
36
|
-
case 'j':
|
|
37
|
-
return cursor.downLogicalLine()
|
|
38
|
-
case 'k':
|
|
39
|
-
return cursor.upLogicalLine()
|
|
40
|
-
case 'gj':
|
|
41
|
-
return cursor.down()
|
|
42
|
-
case 'gk':
|
|
43
|
-
return cursor.up()
|
|
44
|
-
case 'w':
|
|
45
|
-
return cursor.nextVimWord()
|
|
46
|
-
case 'b':
|
|
47
|
-
return cursor.prevVimWord()
|
|
48
|
-
case 'e':
|
|
49
|
-
return cursor.endOfVimWord()
|
|
50
|
-
case 'W':
|
|
51
|
-
return cursor.nextWORD()
|
|
52
|
-
case 'B':
|
|
53
|
-
return cursor.prevWORD()
|
|
54
|
-
case 'E':
|
|
55
|
-
return cursor.endOfWORD()
|
|
56
|
-
case '0':
|
|
57
|
-
return cursor.startOfLogicalLine()
|
|
58
|
-
case '^':
|
|
59
|
-
return cursor.firstNonBlankInLogicalLine()
|
|
60
|
-
case '$':
|
|
61
|
-
return cursor.endOfLogicalLine()
|
|
62
|
-
case 'G':
|
|
63
|
-
return cursor.startOfLastLine()
|
|
64
|
-
default:
|
|
65
|
-
return cursor
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Check if a motion is inclusive (includes character at destination).
|
|
71
|
-
*/
|
|
72
|
-
export function isInclusiveMotion(key: string): boolean {
|
|
73
|
-
return 'eE$'.includes(key)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Check if a motion is linewise (operates on full lines when used with operators).
|
|
78
|
-
* Note: gj/gk are characterwise exclusive per `:help gj`, not linewise.
|
|
79
|
-
*/
|
|
80
|
-
export function isLinewiseMotion(key: string): boolean {
|
|
81
|
-
return 'jkG'.includes(key) || key === 'gg'
|
|
82
|
-
}
|