xling 0.7.0 → 0.7.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/dist/{base-ZLSUOdyk.d.ts → base-BxGCoslm.d.ts} +2 -2
- package/dist/base-CSwZL00J.js +1 -30
- package/dist/{base-B5MGQGLN.d.ts → base-D1BJt9i-.d.ts} +3 -2
- package/dist/base-DtcPVpvU.js +1 -68
- package/dist/claude-C6lOG2Mk.js +1 -206
- package/dist/claude-lgXq7-0w.js +1 -0
- package/dist/claudeDefault-ewrEKzlX.js +1 -18
- package/dist/client-DTC49Rug.js +1 -88
- package/dist/codex-Dl7Rx7Nr.js +1 -83
- package/dist/codex-sOnl7pFp.js +1 -0
- package/dist/commands/git/index.js +5 -35
- package/dist/commands/git/prc.js +2 -121
- package/dist/commands/git/prr.js +2 -80
- package/dist/commands/git/prv.js +2 -70
- package/dist/commands/git/worktree.js +3 -135
- package/dist/commands/git/wta.js +3 -78
- package/dist/commands/git/wtl.js +3 -42
- package/dist/commands/git/wtp.js +3 -42
- package/dist/commands/git/wtr.js +3 -77
- package/dist/commands/git/wts.js +2 -99
- package/dist/commands/p/index.js +15 -380
- package/dist/commands/settings/get.js +2 -119
- package/dist/commands/settings/inspect.js +3 -85
- package/dist/commands/settings/list.js +6 -151
- package/dist/commands/settings/set.js +2 -87
- package/dist/commands/settings/switch.js +4 -165
- package/dist/commands/sx/index.js +12 -93
- package/dist/commands/version/index.js +1 -22
- package/dist/commands/x/index.js +4 -104
- package/dist/config-JHw2hqMN.js +1 -141
- package/dist/create-CKUHliul.js +1 -95
- package/dist/dispatcher-5y9x6plQ.js +1 -0
- package/dist/dispatcher-BYazaYbC.js +1 -75
- package/dist/dispatcher-D4bEJonH.js +1 -30
- package/dist/domain/git.js +1 -3
- package/dist/domain/interfaces.d.ts +2 -2
- package/dist/domain/interfaces.js +1 -1
- package/dist/domain/types.d.ts +1 -1
- package/dist/domain/types.js +1 -1
- package/dist/domain/validators.d.ts +1 -1
- package/dist/domain/validators.js +1 -57
- package/dist/domain/xling/config.js +1 -3
- package/dist/domain/xling/template.js +1 -3
- package/dist/editor-CUiekAEb.js +1 -31
- package/dist/errors-pXKbCKbL.js +1 -115
- package/dist/format-a_tYXjv9.js +4 -229
- package/dist/fsStore-S8RslR8L.js +1 -122
- package/dist/gemini-DQoPiuiw.js +1 -49
- package/dist/git-BZvqM5hz.js +1 -12
- package/dist/{interfaces-Cy1OFHgI.d.ts → interfaces-D5gBXflS.d.ts} +2 -1
- package/dist/pr-DjdO-vJk.js +1 -61
- package/dist/providerRegistry-Cljln1eo.js +1 -151
- package/dist/router-DX-dIEei.js +1 -177
- package/dist/run.js +1 -13
- package/dist/runner-Bi5mGd-w.js +1 -203
- package/dist/runner-DYk4q6mP.js +1 -145
- package/dist/services/git/create.js +1 -6
- package/dist/services/git/dispatcher.js +1 -10
- package/dist/services/git/pr.js +1 -6
- package/dist/services/git/utils.js +1 -5
- package/dist/services/git/view.js +1 -6
- package/dist/services/git/worktree.js +1 -5
- package/dist/services/launch/adapters/base.d.ts +3 -3
- package/dist/services/launch/adapters/base.js +1 -4
- package/dist/services/launch/adapters/claude.d.ts +6 -3
- package/dist/services/launch/adapters/claude.js +1 -5
- package/dist/services/launch/adapters/codex.d.ts +6 -3
- package/dist/services/launch/adapters/codex.js +1 -5
- package/dist/services/launch/dispatcher.d.ts +2 -2
- package/dist/services/launch/dispatcher.js +1 -8
- package/dist/services/prompt/client.js +1 -3
- package/dist/services/prompt/providerRegistry.js +1 -10
- package/dist/services/prompt/router.js +1 -13
- package/dist/services/prompt/types.js +1 -3
- package/dist/services/settings/adapters/base.d.ts +3 -3
- package/dist/services/settings/adapters/base.js +1 -5
- package/dist/services/settings/adapters/claude.d.ts +3 -3
- package/dist/services/settings/adapters/claude.js +1 -9
- package/dist/services/settings/adapters/codex.d.ts +3 -3
- package/dist/services/settings/adapters/codex.js +1 -6
- package/dist/services/settings/adapters/gemini.d.ts +3 -3
- package/dist/services/settings/adapters/gemini.js +1 -6
- package/dist/services/settings/adapters/xling.d.ts +3 -3
- package/dist/services/settings/adapters/xling.js +1 -9
- package/dist/services/settings/dispatcher.d.ts +2 -2
- package/dist/services/settings/dispatcher.js +1 -15
- package/dist/services/settings/fsStore.d.ts +1 -1
- package/dist/services/settings/fsStore.js +1 -4
- package/dist/services/settings/templates/claudeDefault.d.ts +1 -1
- package/dist/services/settings/templates/claudeDefault.js +1 -3
- package/dist/services/shortcuts/runner.js +1 -11
- package/dist/services/shortcuts/types.js +1 -3
- package/dist/template-B19CdPfg.js +1 -164
- package/dist/types-99-EmVXg.js +2 -25
- package/dist/types-DblJSHMa.js +1 -23
- package/dist/{types-5rST51Xi.d.ts → types-RoapPbyI.d.ts} +1 -0
- package/dist/utils/editor.js +1 -4
- package/dist/utils/errors.js +1 -3
- package/dist/utils/format.d.ts +1 -1
- package/dist/utils/format.js +1 -3
- package/dist/utils/logger.js +1 -42
- package/dist/utils/runner.d.ts +1 -1
- package/dist/utils/runner.js +1 -3
- package/dist/utils-DDnNMPIq.js +1 -35
- package/dist/view-JZaEEspp.js +1 -84
- package/dist/worktree-BuIXmI0X.js +3 -205
- package/dist/xling-BxVsmPja.js +1 -254
- package/package.json +1 -1
- package/dist/claude-YXQbPr5h.js +0 -29
- package/dist/codex-UE8EaZGt.js +0 -30
- package/dist/dispatcher-BCISF-Uw.js +0 -87
package/dist/pr-DjdO-vJk.js
CHANGED
|
@@ -1,61 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { r as runCommand } from "./runner-DYk4q6mP.js";
|
|
3
|
-
import { t as detectGhCli } from "./utils-DDnNMPIq.js";
|
|
4
|
-
|
|
5
|
-
//#region src/services/git/pr.ts
|
|
6
|
-
/**
|
|
7
|
-
* Checkout a PR branch
|
|
8
|
-
* Strategy: Try gh CLI first, fallback to git fetch if unavailable
|
|
9
|
-
* @param request PR checkout request
|
|
10
|
-
* @param cwd Working directory
|
|
11
|
-
* @returns Command result
|
|
12
|
-
*/
|
|
13
|
-
async function checkoutPr(request, cwd) {
|
|
14
|
-
const { id, branch = `pr/${id}`, strategy, remote = "origin" } = request;
|
|
15
|
-
if (strategy !== "git") {
|
|
16
|
-
if (await detectGhCli()) try {
|
|
17
|
-
if ((await runCommand("gh", [
|
|
18
|
-
"pr",
|
|
19
|
-
"checkout",
|
|
20
|
-
id
|
|
21
|
-
], {
|
|
22
|
-
cwd,
|
|
23
|
-
throwOnError: false
|
|
24
|
-
})).success) return {
|
|
25
|
-
success: true,
|
|
26
|
-
message: `Checked out PR #${id} using GitHub CLI`,
|
|
27
|
-
details: {
|
|
28
|
-
strategy: "gh",
|
|
29
|
-
branch
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
} catch {}
|
|
33
|
-
}
|
|
34
|
-
const prRef = `pull/${id}/head:${branch}`;
|
|
35
|
-
const fetchResult = await runCommand("git", [
|
|
36
|
-
"fetch",
|
|
37
|
-
remote,
|
|
38
|
-
prRef
|
|
39
|
-
], {
|
|
40
|
-
cwd,
|
|
41
|
-
throwOnError: false
|
|
42
|
-
});
|
|
43
|
-
if (!fetchResult.success) throw new GitCommandError(`git fetch ${remote} ${prRef}`, fetchResult.stderr);
|
|
44
|
-
const switchResult = await runCommand("git", ["switch", branch], {
|
|
45
|
-
cwd,
|
|
46
|
-
throwOnError: false
|
|
47
|
-
});
|
|
48
|
-
if (!switchResult.success) throw new GitCommandError(`git switch ${branch}`, switchResult.stderr);
|
|
49
|
-
return {
|
|
50
|
-
success: true,
|
|
51
|
-
message: `Checked out PR #${id} to branch '${branch}' using git`,
|
|
52
|
-
details: {
|
|
53
|
-
strategy: "git",
|
|
54
|
-
branch,
|
|
55
|
-
remote
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
//#endregion
|
|
61
|
-
export { checkoutPr as t };
|
|
1
|
+
import{o as e}from"./errors-pXKbCKbL.js";import{r as t}from"./runner-DYk4q6mP.js";import{t as n}from"./utils-DDnNMPIq.js";async function r(r,i){let{id:a,branch:o=`pr/${a}`,strategy:s,remote:c=`origin`}=r;if(s!==`git`&&await n())try{if((await t(`gh`,[`pr`,`checkout`,a],{cwd:i,throwOnError:!1})).success)return{success:!0,message:`Checked out PR #${a} using GitHub CLI`,details:{strategy:`gh`,branch:o}}}catch{}let l=`pull/${a}/head:${o}`,u=await t(`git`,[`fetch`,c,l],{cwd:i,throwOnError:!1});if(!u.success)throw new e(`git fetch ${c} ${l}`,u.stderr);let d=await t(`git`,[`switch`,o],{cwd:i,throwOnError:!1});if(!d.success)throw new e(`git switch ${o}`,d.stderr);return{success:!0,message:`Checked out PR #${a} to branch '${o}' using git`,details:{strategy:`git`,branch:o,remote:c}}}export{r as t};
|
|
@@ -1,151 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { t as XlingAdapter } from "./xling-BxVsmPja.js";
|
|
3
|
-
|
|
4
|
-
//#region src/services/prompt/providerRegistry.ts
|
|
5
|
-
/**
|
|
6
|
-
* Registry for managing AI providers and model routing
|
|
7
|
-
*
|
|
8
|
-
* Responsibilities:
|
|
9
|
-
* - Load and cache configuration
|
|
10
|
-
* - Sort providers by priority
|
|
11
|
-
* - Index models for quick lookup
|
|
12
|
-
* - Provide routing API for model requests
|
|
13
|
-
*/
|
|
14
|
-
var ProviderRegistry = class ProviderRegistry {
|
|
15
|
-
#providers;
|
|
16
|
-
#modelIndex;
|
|
17
|
-
#defaultModel;
|
|
18
|
-
constructor(config) {
|
|
19
|
-
this.#providers = this.#sortByPriority(config.prompt.providers);
|
|
20
|
-
this.#defaultModel = config.prompt.defaultModel;
|
|
21
|
-
this.#modelIndex = this.#buildModelIndex();
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Sort providers by priority (lower number = higher priority)
|
|
25
|
-
* Undefined priority is treated as lowest priority
|
|
26
|
-
*/
|
|
27
|
-
#sortByPriority(providers) {
|
|
28
|
-
return [...providers].sort((a, b) => {
|
|
29
|
-
return getNormalizedPriority(a.priority) - getNormalizedPriority(b.priority);
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Build model index: model name -> [providers that support it]
|
|
34
|
-
* Providers are already sorted by priority
|
|
35
|
-
*/
|
|
36
|
-
#buildModelIndex() {
|
|
37
|
-
const index = /* @__PURE__ */ new Map();
|
|
38
|
-
for (const provider of this.#providers) for (const model of provider.models) {
|
|
39
|
-
if (!index.has(model)) index.set(model, []);
|
|
40
|
-
index.get(model).push(provider);
|
|
41
|
-
}
|
|
42
|
-
return index;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Get all providers that support a specific model, sorted by priority
|
|
46
|
-
* Returns empty array if model is not supported
|
|
47
|
-
*/
|
|
48
|
-
getProvidersForModel(modelId) {
|
|
49
|
-
return this.#modelIndex.get(modelId) || [];
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Get all available models across all providers
|
|
53
|
-
*/
|
|
54
|
-
getAllModels() {
|
|
55
|
-
return Array.from(this.#modelIndex.keys()).sort();
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Get all registered providers
|
|
59
|
-
*/
|
|
60
|
-
getAllProviders() {
|
|
61
|
-
return [...this.#providers];
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Get provider by name
|
|
65
|
-
*/
|
|
66
|
-
getProviderByName(name) {
|
|
67
|
-
return this.#providers.find((p) => p.name === name);
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Get default model
|
|
71
|
-
*/
|
|
72
|
-
getDefaultModel() {
|
|
73
|
-
return this.#defaultModel;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Check if a model is supported by any provider
|
|
77
|
-
*/
|
|
78
|
-
isModelSupported(modelId) {
|
|
79
|
-
return this.#modelIndex.has(modelId);
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Get statistics about the registry
|
|
83
|
-
*/
|
|
84
|
-
getStats() {
|
|
85
|
-
return {
|
|
86
|
-
providerCount: this.#providers.length,
|
|
87
|
-
modelCount: this.#modelIndex.size,
|
|
88
|
-
defaultModel: this.#defaultModel
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Reload configuration from disk
|
|
93
|
-
*/
|
|
94
|
-
async reload() {
|
|
95
|
-
const adapter = new XlingAdapter();
|
|
96
|
-
const config = adapter.readConfig(adapter.resolvePath("user"));
|
|
97
|
-
this.#providers = this.#sortByPriority(config.prompt.providers);
|
|
98
|
-
this.#defaultModel = config.prompt.defaultModel;
|
|
99
|
-
this.#modelIndex = this.#buildModelIndex();
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Factory method to create registry from configuration file
|
|
103
|
-
*/
|
|
104
|
-
static async fromConfig() {
|
|
105
|
-
const adapter = new XlingAdapter();
|
|
106
|
-
return new ProviderRegistry(adapter.readConfig(adapter.resolvePath("user")));
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Get providers for a model, with fallback to default model if specified model is not found
|
|
110
|
-
*/
|
|
111
|
-
getProvidersWithFallback(modelId) {
|
|
112
|
-
if (modelId) {
|
|
113
|
-
const providers = this.getProvidersForModel(modelId);
|
|
114
|
-
if (providers.length > 0) return {
|
|
115
|
-
model: modelId,
|
|
116
|
-
providers
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
if (this.#defaultModel) {
|
|
120
|
-
const providers = this.getProvidersForModel(this.#defaultModel);
|
|
121
|
-
if (providers.length > 0) return {
|
|
122
|
-
model: this.#defaultModel,
|
|
123
|
-
providers
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
return null;
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
/**
|
|
130
|
-
* Singleton instance for global access
|
|
131
|
-
* Lazy-loaded on first access
|
|
132
|
-
*/
|
|
133
|
-
let registryInstance = null;
|
|
134
|
-
/**
|
|
135
|
-
* Get the global registry instance
|
|
136
|
-
* Creates it if it doesn't exist
|
|
137
|
-
*/
|
|
138
|
-
async function getRegistry() {
|
|
139
|
-
if (!registryInstance) registryInstance = await ProviderRegistry.fromConfig();
|
|
140
|
-
return registryInstance;
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Reset the global registry instance
|
|
144
|
-
* Useful for testing or forcing a reload
|
|
145
|
-
*/
|
|
146
|
-
function resetRegistry() {
|
|
147
|
-
registryInstance = null;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
//#endregion
|
|
151
|
-
export { getRegistry as n, resetRegistry as r, ProviderRegistry as t };
|
|
1
|
+
import{d as e}from"./config-JHw2hqMN.js";import{t}from"./xling-BxVsmPja.js";var n=class n{#e;#t;#n;constructor(e){this.#e=this.#r(e.prompt.providers),this.#n=e.prompt.defaultModel,this.#t=this.#i()}#r(t){return[...t].sort((t,n)=>e(t.priority)-e(n.priority))}#i(){let e=new Map;for(let t of this.#e)for(let n of t.models)e.has(n)||e.set(n,[]),e.get(n).push(t);return e}getProvidersForModel(e){return this.#t.get(e)||[]}getAllModels(){return Array.from(this.#t.keys()).sort()}getAllProviders(){return[...this.#e]}getProviderByName(e){return this.#e.find(t=>t.name===e)}getDefaultModel(){return this.#n}isModelSupported(e){return this.#t.has(e)}getStats(){return{providerCount:this.#e.length,modelCount:this.#t.size,defaultModel:this.#n}}async reload(){let e=new t,n=e.readConfig(e.resolvePath(`user`));this.#e=this.#r(n.prompt.providers),this.#n=n.prompt.defaultModel,this.#t=this.#i()}static async fromConfig(){let e=new t;return new n(e.readConfig(e.resolvePath(`user`)))}getProvidersWithFallback(e){if(e){let t=this.getProvidersForModel(e);if(t.length>0)return{model:e,providers:t}}if(this.#n){let e=this.getProvidersForModel(this.#n);if(e.length>0)return{model:this.#n,providers:e}}return null}};let r=null;async function i(){return r||=await n.fromConfig(),r}function a(){r=null}export{i as n,a as r,n as t};
|
package/dist/router-DX-dIEei.js
CHANGED
|
@@ -1,177 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { t as PromptClient } from "./client-DTC49Rug.js";
|
|
3
|
-
import { n as ModelNotSupportedError, t as AllProvidersFailedError } from "./types-99-EmVXg.js";
|
|
4
|
-
|
|
5
|
-
//#region src/services/prompt/router.ts
|
|
6
|
-
/**
|
|
7
|
-
* Simple console logger
|
|
8
|
-
*/
|
|
9
|
-
const defaultLogger = {
|
|
10
|
-
debug: (msg, ...args) => console.debug(`[Router] ${msg}`, ...args),
|
|
11
|
-
info: (msg, ...args) => console.info(`[Router] ${msg}`, ...args),
|
|
12
|
-
warn: (msg, ...args) => console.warn(`[Router] ${msg}`, ...args),
|
|
13
|
-
error: (msg, ...args) => console.error(`[Router] ${msg}`, ...args)
|
|
14
|
-
};
|
|
15
|
-
/**
|
|
16
|
-
* Model Router with intelligent provider selection and fallback
|
|
17
|
-
*/
|
|
18
|
-
var ModelRouter = class {
|
|
19
|
-
#registry;
|
|
20
|
-
#clients;
|
|
21
|
-
#retryPolicy;
|
|
22
|
-
#logger;
|
|
23
|
-
constructor(config, logger) {
|
|
24
|
-
this.#registry = new ProviderRegistry(config);
|
|
25
|
-
this.#clients = /* @__PURE__ */ new Map();
|
|
26
|
-
this.#retryPolicy = config.prompt.retryPolicy || {
|
|
27
|
-
maxRetries: 2,
|
|
28
|
-
backoffMs: 1e3
|
|
29
|
-
};
|
|
30
|
-
this.#logger = logger || defaultLogger;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Get or create a client for a provider
|
|
34
|
-
*/
|
|
35
|
-
#getOrCreateClient(provider) {
|
|
36
|
-
if (!this.#clients.has(provider.name)) this.#clients.set(provider.name, new PromptClient(provider));
|
|
37
|
-
return this.#clients.get(provider.name);
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Execute a prompt request with automatic provider selection and fallback
|
|
41
|
-
*/
|
|
42
|
-
async execute(request) {
|
|
43
|
-
const modelId = request.model || this.#registry.getDefaultModel();
|
|
44
|
-
if (!modelId) throw new Error("No model specified and no default model configured. Please specify a model with --model or configure a default model.");
|
|
45
|
-
const providers = this.#registry.getProvidersForModel(modelId);
|
|
46
|
-
if (providers.length === 0) throw new ModelNotSupportedError(modelId, this.#registry.getAllModels());
|
|
47
|
-
this.#logger.info(`Using model: ${modelId} (${providers.length} provider(s) available)`);
|
|
48
|
-
return await this.#tryWithFallback(modelId, request, providers);
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Try executing the request with automatic fallback to other providers
|
|
52
|
-
*/
|
|
53
|
-
async #tryWithFallback(modelId, request, providers) {
|
|
54
|
-
const errors = [];
|
|
55
|
-
for (let i = 0; i < providers.length; i++) {
|
|
56
|
-
const provider = providers[i];
|
|
57
|
-
const isLastProvider = i === providers.length - 1;
|
|
58
|
-
try {
|
|
59
|
-
this.#logger.debug(`Trying provider: ${provider.name} (priority: ${provider.priority || "default"})`);
|
|
60
|
-
const client = this.#getOrCreateClient(provider);
|
|
61
|
-
const requestWithModel = {
|
|
62
|
-
...request,
|
|
63
|
-
model: modelId
|
|
64
|
-
};
|
|
65
|
-
const result = await this.#executeWithTimeout(() => client.generate(requestWithModel), provider.timeout || 6e4);
|
|
66
|
-
this.#logger.info(`✓ Successfully used provider: ${provider.name}`);
|
|
67
|
-
return result;
|
|
68
|
-
} catch (error) {
|
|
69
|
-
const err = error;
|
|
70
|
-
this.#logger.warn(`✗ Provider ${provider.name} failed: ${err.message}`);
|
|
71
|
-
errors.push({
|
|
72
|
-
provider: provider.name,
|
|
73
|
-
error: err
|
|
74
|
-
});
|
|
75
|
-
if (!(this.#isRetriableError(err) && !isLastProvider)) {
|
|
76
|
-
if (isLastProvider && errors.length > 1) throw new AllProvidersFailedError(modelId, errors);
|
|
77
|
-
throw err;
|
|
78
|
-
}
|
|
79
|
-
if (!isLastProvider) await this.#backoff(i);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
throw new AllProvidersFailedError(modelId, errors);
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Check if an error is retriable
|
|
86
|
-
*
|
|
87
|
-
* Retriable errors:
|
|
88
|
-
* - Network errors (ECONNREFUSED, ETIMEDOUT, ENOTFOUND)
|
|
89
|
-
* - 5xx server errors
|
|
90
|
-
* - 429 rate limit (optional, can be configured)
|
|
91
|
-
*
|
|
92
|
-
* Non-retriable errors:
|
|
93
|
-
* - 400 Bad Request
|
|
94
|
-
* - 401 Unauthorized
|
|
95
|
-
* - 403 Forbidden
|
|
96
|
-
* - 404 Not Found
|
|
97
|
-
*/
|
|
98
|
-
#isRetriableError(error) {
|
|
99
|
-
const message = error.message.toLowerCase();
|
|
100
|
-
if (message.includes("econnrefused") || message.includes("etimedout") || message.includes("enotfound") || message.includes("network") || message.includes("fetch failed")) return true;
|
|
101
|
-
const errorWithStatus = error;
|
|
102
|
-
if (typeof errorWithStatus.status === "number") {
|
|
103
|
-
const status = errorWithStatus.status;
|
|
104
|
-
if (status >= 500 && status < 600) return true;
|
|
105
|
-
if (status === 429) return true;
|
|
106
|
-
if (status >= 400 && status < 500) return false;
|
|
107
|
-
}
|
|
108
|
-
if (message.match(/\b(5\d{2}|429)\b/)) return true;
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Apply exponential backoff delay
|
|
113
|
-
*/
|
|
114
|
-
async #backoff(attempt) {
|
|
115
|
-
const delay = Math.min(this.#retryPolicy.backoffMs * Math.pow(2, attempt), 3e4);
|
|
116
|
-
this.#logger.debug(`Backing off for ${delay}ms before next attempt`);
|
|
117
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Execute a function with timeout
|
|
121
|
-
*/
|
|
122
|
-
async #executeWithTimeout(fn, timeoutMs) {
|
|
123
|
-
return new Promise((resolve, reject) => {
|
|
124
|
-
const timer = setTimeout(() => {
|
|
125
|
-
reject(/* @__PURE__ */ new Error(`Request timed out after ${timeoutMs}ms`));
|
|
126
|
-
}, timeoutMs);
|
|
127
|
-
fn().then((result) => {
|
|
128
|
-
clearTimeout(timer);
|
|
129
|
-
resolve(result);
|
|
130
|
-
}).catch((error) => {
|
|
131
|
-
clearTimeout(timer);
|
|
132
|
-
reject(error);
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Execute a prompt request with streaming support
|
|
138
|
-
* Simplified version without retry logic for interactive mode
|
|
139
|
-
*/
|
|
140
|
-
async executeStream(request) {
|
|
141
|
-
const modelId = request.model || this.#registry.getDefaultModel();
|
|
142
|
-
if (!modelId) throw new Error("No model specified and no default model configured. Please specify a model with --model or configure a default model.");
|
|
143
|
-
const providers = this.#registry.getProvidersForModel(modelId);
|
|
144
|
-
if (providers.length === 0) throw new ModelNotSupportedError(modelId, this.#registry.getAllModels());
|
|
145
|
-
const provider = providers[0];
|
|
146
|
-
const client = this.#getOrCreateClient(provider);
|
|
147
|
-
this.#logger.debug(`Streaming with model: ${modelId} via provider: ${provider.name}`);
|
|
148
|
-
const requestWithModel = {
|
|
149
|
-
...request,
|
|
150
|
-
model: modelId
|
|
151
|
-
};
|
|
152
|
-
return await client.stream(requestWithModel);
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Get registry instance
|
|
156
|
-
*/
|
|
157
|
-
getRegistry() {
|
|
158
|
-
return this.#registry;
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Clear client cache (useful for testing)
|
|
162
|
-
*/
|
|
163
|
-
clearClients() {
|
|
164
|
-
this.#clients.clear();
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
/**
|
|
168
|
-
* Factory method to create router from config file
|
|
169
|
-
*/
|
|
170
|
-
async function createRouter(logger) {
|
|
171
|
-
const { XlingAdapter } = await import("./services/settings/adapters/xling.js");
|
|
172
|
-
const adapter = new XlingAdapter();
|
|
173
|
-
return new ModelRouter(adapter.readConfig(adapter.resolvePath("user")), logger);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
//#endregion
|
|
177
|
-
export { createRouter as n, ModelRouter as t };
|
|
1
|
+
import{t as e}from"./providerRegistry-Cljln1eo.js";import{t}from"./client-DTC49Rug.js";import{n,t as r}from"./types-99-EmVXg.js";const i={debug:(e,...t)=>console.debug(`[Router] ${e}`,...t),info:(e,...t)=>console.info(`[Router] ${e}`,...t),warn:(e,...t)=>console.warn(`[Router] ${e}`,...t),error:(e,...t)=>console.error(`[Router] ${e}`,...t)};var a=class{#e;#t;#n;#r;constructor(t,n){this.#e=new e(t),this.#t=new Map,this.#n=t.prompt.retryPolicy||{maxRetries:2,backoffMs:1e3},this.#r=n||i}#i(e){return this.#t.has(e.name)||this.#t.set(e.name,new t(e)),this.#t.get(e.name)}async execute(e){let t=e.model||this.#e.getDefaultModel();if(!t)throw Error(`No model specified and no default model configured. Please specify a model with --model or configure a default model.`);let r=this.#e.getProvidersForModel(t);if(r.length===0)throw new n(t,this.#e.getAllModels());return this.#r.info(`Using model: ${t} (${r.length} provider(s) available)`),await this.#a(t,e,r)}async#a(e,t,n){let i=[];for(let a=0;a<n.length;a++){let o=n[a],s=a===n.length-1;try{this.#r.debug(`Trying provider: ${o.name} (priority: ${o.priority||`default`})`);let n=this.#i(o),r={...t,model:e},i=await this.#c(()=>n.generate(r),o.timeout||6e4);return this.#r.info(`✓ Successfully used provider: ${o.name}`),i}catch(t){let n=t;if(this.#r.warn(`✗ Provider ${o.name} failed: ${n.message}`),i.push({provider:o.name,error:n}),!(this.#o(n)&&!s))throw s&&i.length>1?new r(e,i):n;s||await this.#s(a)}}throw new r(e,i)}#o(e){let t=e.message.toLowerCase();if(t.includes(`econnrefused`)||t.includes(`etimedout`)||t.includes(`enotfound`)||t.includes(`network`)||t.includes(`fetch failed`))return!0;let n=e;if(typeof n.status==`number`){let e=n.status;if(e>=500&&e<600||e===429)return!0;if(e>=400&&e<500)return!1}return!!t.match(/\b(5\d{2}|429)\b/)}async#s(e){let t=Math.min(this.#n.backoffMs*2**e,3e4);this.#r.debug(`Backing off for ${t}ms before next attempt`),await new Promise(e=>setTimeout(e,t))}async#c(e,t){return new Promise((n,r)=>{let i=setTimeout(()=>{r(Error(`Request timed out after ${t}ms`))},t);e().then(e=>{clearTimeout(i),n(e)}).catch(e=>{clearTimeout(i),r(e)})})}async executeStream(e){let t=e.model||this.#e.getDefaultModel();if(!t)throw Error(`No model specified and no default model configured. Please specify a model with --model or configure a default model.`);let r=this.#e.getProvidersForModel(t);if(r.length===0)throw new n(t,this.#e.getAllModels());let i=r[0],a=this.#i(i);this.#r.debug(`Streaming with model: ${t} via provider: ${i.name}`);let o={...e,model:t};return await a.stream(o)}getRegistry(){return this.#e}clearClients(){this.#t.clear()}};async function o(e){let{XlingAdapter:t}=await import(`./services/settings/adapters/xling.js`),n=new t;return new a(n.readConfig(n.resolvePath(`user`)),e)}export{o as n,a as t};
|
package/dist/run.js
CHANGED
|
@@ -1,14 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
//#region src/run.ts
|
|
5
|
-
/**
|
|
6
|
-
* xling CLI entry point
|
|
7
|
-
*/
|
|
8
|
-
await execute({
|
|
9
|
-
development: false,
|
|
10
|
-
dir: import.meta.url
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
//#endregion
|
|
14
|
-
export { };
|
|
2
|
+
import{execute as e}from"@oclif/core";await e({development:!1,dir:import.meta.url});export{};
|
package/dist/runner-Bi5mGd-w.js
CHANGED
|
@@ -1,203 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { n as ShortcutNotFoundError, t as CircularShortcutError } from "./types-DblJSHMa.js";
|
|
3
|
-
import { spawn } from "child_process";
|
|
4
|
-
|
|
5
|
-
//#region src/services/shortcuts/runner.ts
|
|
6
|
-
/**
|
|
7
|
-
* Shortcut runner service
|
|
8
|
-
* Handles loading, listing, and executing command shortcuts
|
|
9
|
-
*/
|
|
10
|
-
/**
|
|
11
|
-
* Service for managing and executing command shortcuts
|
|
12
|
-
*/
|
|
13
|
-
var ShortcutRunner = class {
|
|
14
|
-
#adapter;
|
|
15
|
-
#config;
|
|
16
|
-
constructor(config) {
|
|
17
|
-
this.#config = config;
|
|
18
|
-
this.#adapter = new XlingAdapter();
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Load all shortcuts from configuration
|
|
22
|
-
*/
|
|
23
|
-
async load() {
|
|
24
|
-
return this.#adapter.getShortcuts("user");
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Get formatted list of shortcuts for display
|
|
28
|
-
*/
|
|
29
|
-
async list() {
|
|
30
|
-
const shortcuts = await this.load();
|
|
31
|
-
return Object.entries(shortcuts).map(([name, config]) => {
|
|
32
|
-
let type;
|
|
33
|
-
let display;
|
|
34
|
-
if (config.command) {
|
|
35
|
-
type = "command";
|
|
36
|
-
display = config.command;
|
|
37
|
-
} else if (config.shell) {
|
|
38
|
-
type = "shell";
|
|
39
|
-
const shellCommand = this.#resolveShellCommand(config.shell);
|
|
40
|
-
display = shellCommand.length > 50 ? shellCommand.substring(0, 47) + "..." : shellCommand;
|
|
41
|
-
} else if (config.pipeline) {
|
|
42
|
-
type = "pipeline";
|
|
43
|
-
display = this.#resolvePipeline(config.pipeline).map((step) => step.command).join(" | ");
|
|
44
|
-
} else {
|
|
45
|
-
type = "command";
|
|
46
|
-
display = "unknown";
|
|
47
|
-
}
|
|
48
|
-
return {
|
|
49
|
-
name,
|
|
50
|
-
type,
|
|
51
|
-
command: display,
|
|
52
|
-
args: config.args || [],
|
|
53
|
-
description: config.description
|
|
54
|
-
};
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Execute a shortcut by name
|
|
59
|
-
* @param name - Shortcut name
|
|
60
|
-
* @param passthroughArgs - Additional arguments to append
|
|
61
|
-
*/
|
|
62
|
-
async run(name, passthroughArgs) {
|
|
63
|
-
const shortcuts = await this.load();
|
|
64
|
-
const shortcut = shortcuts[name];
|
|
65
|
-
if (!shortcut) throw new ShortcutNotFoundError(name, Object.keys(shortcuts));
|
|
66
|
-
this.#validateShortcut(name, shortcut);
|
|
67
|
-
if (shortcut.command) await this.#runCommand(shortcut, passthroughArgs);
|
|
68
|
-
else if (shortcut.shell) await this.#runShell(shortcut.shell);
|
|
69
|
-
else if (shortcut.pipeline) await this.#runPipeline(shortcut.pipeline);
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Execute a command shortcut
|
|
73
|
-
*/
|
|
74
|
-
async #runCommand(shortcut, passthroughArgs) {
|
|
75
|
-
const finalArgs = [...shortcut.args || [], ...passthroughArgs];
|
|
76
|
-
await this.#config.runCommand(shortcut.command, finalArgs);
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Execute a shell shortcut
|
|
80
|
-
* Supports both string and platform-specific shell commands
|
|
81
|
-
*/
|
|
82
|
-
async #runShell(shellCommand) {
|
|
83
|
-
return new Promise((resolve, reject) => {
|
|
84
|
-
const shellConfig = this.#getShellConfig();
|
|
85
|
-
const child = spawn(this.#resolveShellCommand(shellCommand), {
|
|
86
|
-
shell: shellConfig,
|
|
87
|
-
stdio: "inherit"
|
|
88
|
-
});
|
|
89
|
-
child.on("error", (error) => {
|
|
90
|
-
reject(/* @__PURE__ */ new Error(`Failed to execute shell command: ${error.message}`));
|
|
91
|
-
});
|
|
92
|
-
child.on("exit", (code) => {
|
|
93
|
-
if (code === 0) resolve();
|
|
94
|
-
else reject(/* @__PURE__ */ new Error(`Shell command exited with code ${code}`));
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Resolve platform-specific shell command
|
|
100
|
-
* Returns the appropriate command for the current platform
|
|
101
|
-
*/
|
|
102
|
-
#resolveShellCommand(shellCommand) {
|
|
103
|
-
if (typeof shellCommand === "string") return shellCommand;
|
|
104
|
-
return this.#resolvePlatformValue(shellCommand);
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Get platform-specific shell configuration
|
|
108
|
-
* Windows: Use PowerShell 7 (pwsh)
|
|
109
|
-
* Unix: Use default shell
|
|
110
|
-
*/
|
|
111
|
-
#getShellConfig() {
|
|
112
|
-
if (process.platform === "win32") return "pwsh";
|
|
113
|
-
return true;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Execute a pipeline shortcut
|
|
117
|
-
* Supports both array and platform-specific pipelines
|
|
118
|
-
*/
|
|
119
|
-
async #runPipeline(pipeline) {
|
|
120
|
-
return new Promise((resolve, reject) => {
|
|
121
|
-
const resolvedPipeline = this.#resolvePipeline(pipeline);
|
|
122
|
-
const processes = [];
|
|
123
|
-
for (let i = 0; i < resolvedPipeline.length; i++) {
|
|
124
|
-
const step = resolvedPipeline[i];
|
|
125
|
-
const isFirst = i === 0;
|
|
126
|
-
const isLast = i === resolvedPipeline.length - 1;
|
|
127
|
-
const command = step.command;
|
|
128
|
-
const args = step.args || [];
|
|
129
|
-
const isShellCommand = command === "pwsh" || command === "powershell" || command === "cmd" || command.includes("\\") || command.includes("/");
|
|
130
|
-
const needsShell = process.platform === "win32" && !isShellCommand;
|
|
131
|
-
const child = spawn(command, args, {
|
|
132
|
-
stdio: [
|
|
133
|
-
isFirst ? "inherit" : "pipe",
|
|
134
|
-
isLast ? "inherit" : "pipe",
|
|
135
|
-
"inherit"
|
|
136
|
-
],
|
|
137
|
-
shell: needsShell,
|
|
138
|
-
cwd: process.cwd(),
|
|
139
|
-
env: process.env
|
|
140
|
-
});
|
|
141
|
-
if (!isFirst && processes[i - 1]) processes[i - 1].stdout?.pipe(child.stdin);
|
|
142
|
-
processes.push(child);
|
|
143
|
-
child.on("error", (error) => {
|
|
144
|
-
reject(/* @__PURE__ */ new Error(`Failed to execute pipeline step "${step.command}": ${error.message}`));
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
processes[processes.length - 1].on("exit", (code) => {
|
|
148
|
-
if (code === 0) resolve();
|
|
149
|
-
else reject(/* @__PURE__ */ new Error(`Pipeline exited with code ${code}`));
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Resolve platform-specific pipeline
|
|
155
|
-
* Returns the appropriate pipeline for the current platform
|
|
156
|
-
* Also resolves platform-specific command/args within each step
|
|
157
|
-
*/
|
|
158
|
-
#resolvePipeline(pipeline) {
|
|
159
|
-
return (Array.isArray(pipeline) ? pipeline : this.#resolvePlatformPipeline(pipeline)).map((step) => ({
|
|
160
|
-
command: this.#resolvePlatformValue(step.command),
|
|
161
|
-
args: step.args ? this.#resolvePlatformValue(step.args) : void 0
|
|
162
|
-
}));
|
|
163
|
-
}
|
|
164
|
-
#resolvePlatformPipeline(pipeline) {
|
|
165
|
-
const platform = process.platform;
|
|
166
|
-
if (platform === "win32" && pipeline.win32) return pipeline.win32;
|
|
167
|
-
if (platform === "darwin" && pipeline.darwin) return pipeline.darwin;
|
|
168
|
-
if (platform === "linux" && pipeline.linux) return pipeline.linux;
|
|
169
|
-
return pipeline.default;
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Resolve platform-specific value (command or args)
|
|
173
|
-
* Returns the appropriate value for the current platform
|
|
174
|
-
*/
|
|
175
|
-
#resolvePlatformValue(value) {
|
|
176
|
-
if (!this.#isPlatformValue(value)) return value;
|
|
177
|
-
const platform = process.platform;
|
|
178
|
-
if (platform === "win32" && value.win32 !== void 0) return value.win32;
|
|
179
|
-
if (platform === "darwin" && value.darwin !== void 0) return value.darwin;
|
|
180
|
-
if (platform === "linux" && value.linux !== void 0) return value.linux;
|
|
181
|
-
return value.default;
|
|
182
|
-
}
|
|
183
|
-
#isPlatformValue(value) {
|
|
184
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) && "default" in value;
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Validate shortcut configuration
|
|
188
|
-
* @throws {CircularShortcutError} if shortcut creates circular reference
|
|
189
|
-
*/
|
|
190
|
-
#validateShortcut(name, shortcut) {
|
|
191
|
-
if (shortcut.command === "sx") throw new CircularShortcutError(name);
|
|
192
|
-
if (shortcut.pipeline) {
|
|
193
|
-
const resolvedPipeline = this.#resolvePipeline(shortcut.pipeline);
|
|
194
|
-
for (const step of resolvedPipeline) if (step.command === "xling" && step.args?.includes("sx")) throw new CircularShortcutError(name);
|
|
195
|
-
}
|
|
196
|
-
if (shortcut.shell) {
|
|
197
|
-
if (this.#resolveShellCommand(shortcut.shell).includes("xling sx")) throw new CircularShortcutError(name);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
//#endregion
|
|
203
|
-
export { ShortcutRunner as t };
|
|
1
|
+
import{t as e}from"./xling-BxVsmPja.js";import{n as t,t as n}from"./types-DblJSHMa.js";import{spawn as r}from"child_process";var i=class{#e;#t;constructor(t){this.#t=t,this.#e=new e}async load(){return this.#e.getShortcuts(`user`)}async list(){let e=await this.load();return Object.entries(e).map(([e,t])=>{let n,r;if(t.command)n=`command`,r=t.command;else if(t.shell){n=`shell`;let e=this.#i(t.shell);r=e.length>50?e.substring(0,47)+`...`:e}else t.pipeline?(n=`pipeline`,r=this.#s(t.pipeline).map(e=>e.command).join(` | `)):(n=`command`,r=`unknown`);return{name:e,type:n,command:r,args:t.args||[],description:t.description}})}async run(e,n){let r=await this.load(),i=r[e];if(!i)throw new t(e,Object.keys(r));this.#d(e,i),i.command?await this.#n(i,n):i.shell?await this.#r(i.shell):i.pipeline&&await this.#o(i.pipeline)}async#n(e,t){let n=[...e.args||[],...t];await this.#t.runCommand(e.command,n)}async#r(e){return new Promise((t,n)=>{let i=this.#a(),a=r(this.#i(e),{shell:i,stdio:`inherit`});a.on(`error`,e=>{n(Error(`Failed to execute shell command: ${e.message}`))}),a.on(`exit`,e=>{e===0?t():n(Error(`Shell command exited with code ${e}`))})})}#i(e){return typeof e==`string`?e:this.#l(e)}#a(){return process.platform===`win32`?`pwsh`:!0}async#o(e){return new Promise((t,n)=>{let i=this.#s(e),a=[];for(let e=0;e<i.length;e++){let t=i[e],o=e===0,s=e===i.length-1,c=t.command,l=t.args||[],u=c===`pwsh`||c===`powershell`||c===`cmd`||c.includes(`\\`)||c.includes(`/`),d=process.platform===`win32`&&!u,f=r(c,l,{stdio:[o?`inherit`:`pipe`,s?`inherit`:`pipe`,`inherit`],shell:d,cwd:process.cwd(),env:process.env});!o&&a[e-1]&&a[e-1].stdout?.pipe(f.stdin),a.push(f),f.on(`error`,e=>{n(Error(`Failed to execute pipeline step "${t.command}": ${e.message}`))})}a[a.length-1].on(`exit`,e=>{e===0?t():n(Error(`Pipeline exited with code ${e}`))})})}#s(e){return(Array.isArray(e)?e:this.#c(e)).map(e=>({command:this.#l(e.command),args:e.args?this.#l(e.args):void 0}))}#c(e){let t=process.platform;return t===`win32`&&e.win32?e.win32:t===`darwin`&&e.darwin?e.darwin:t===`linux`&&e.linux?e.linux:e.default}#l(e){if(!this.#u(e))return e;let t=process.platform;return t===`win32`&&e.win32!==void 0?e.win32:t===`darwin`&&e.darwin!==void 0?e.darwin:t===`linux`&&e.linux!==void 0?e.linux:e.default}#u(e){return typeof e==`object`&&!!e&&!Array.isArray(e)&&`default`in e}#d(e,t){if(t.command===`sx`)throw new n(e);if(t.pipeline){let r=this.#s(t.pipeline);for(let t of r)if(t.command===`xling`&&t.args?.includes(`sx`))throw new n(e)}if(t.shell&&this.#i(t.shell).includes(`xling sx`))throw new n(e)}};export{i as t};
|