memorix 1.9.9 → 1.9.11
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/CHANGELOG.md +42 -0
- package/README.md +2 -0
- package/README.zh-CN.md +2 -0
- package/dist/cli/index.js +855 -231
- package/dist/index.js +284 -77
- package/dist/maintenance-runner.js +74 -20
- package/dist/media-audio-runner.js +74 -20
- package/dist/media-video-runner.js +74 -20
- package/dist/memcode/index.js +1532 -1002
- package/dist/memcode-runtime/CHANGELOG.md +42 -0
- package/dist/memcode-runtime/package.json +4 -4
- package/dist/sdk.js +283 -76
- package/dist/vector-backfill-runner.js +74 -20
- package/docs/CONFIGURATION.md +26 -0
- package/docs/DEVELOPMENT.md +3 -2
- package/docs/INTEGRATIONS.md +3 -1
- package/docs/README.md +2 -1
- package/docs/SETUP.md +1 -1
- package/docs/hooks-architecture.md +5 -0
- package/package.json +18 -11
- package/plugins/antigravity/memorix/plugin.json +1 -1
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/copilot/memorix/plugin.json +1 -1
- package/plugins/gemini/memorix/gemini-extension.json +1 -1
- package/plugins/hermes/memorix/plugin.yaml +1 -1
- package/plugins/omp/memorix/package.json +1 -1
- package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/pi/memorix/package.json +1 -1
- package/server.json +2 -2
- package/src/cli/commands/hooks-install.ts +2 -0
- package/src/cli/commands/init.ts +6 -2
- package/src/cli/commands/integrate.ts +2 -0
- package/src/cli/commands/setup.ts +1 -1
- package/src/cli/index.ts +2 -2
- package/src/cli/tui/ConfigureView.tsx +2 -0
- package/src/config/dotenv-loader.ts +1 -0
- package/src/config/resolved-config.ts +7 -3
- package/src/config/yaml-loader.ts +2 -2
- package/src/dashboard/server.ts +3 -0
- package/src/hooks/installers/index.ts +219 -31
- package/src/hooks/lifecycle.ts +4 -9
- package/src/hooks/normalizer.ts +6 -1
- package/src/hooks/types.ts +3 -1
- package/src/llm/provider.ts +2 -1
- package/src/memory/observations.ts +11 -0
- package/src/memory/session.ts +4 -13
- package/src/memory/visibility.ts +8 -2
- package/src/multimodal/image-loader.ts +6 -5
- package/src/server.ts +8 -4
- package/src/store/obs-store.ts +3 -0
- package/src/store/orama-store.ts +43 -6
- package/src/store/sqlite-store.ts +15 -0
package/dist/cli/index.js
CHANGED
|
@@ -3232,7 +3232,7 @@ ${import_picocolors.default.gray(m3)} ${s4}
|
|
|
3232
3232
|
|
|
3233
3233
|
// src/cli/version.ts
|
|
3234
3234
|
function getCliVersion() {
|
|
3235
|
-
return true ? "1.9.
|
|
3235
|
+
return true ? "1.9.11" : pkg.version;
|
|
3236
3236
|
}
|
|
3237
3237
|
var init_version = __esm({
|
|
3238
3238
|
"src/cli/version.ts"() {
|
|
@@ -13748,9 +13748,9 @@ function sharedAgentIds(record2) {
|
|
|
13748
13748
|
return [];
|
|
13749
13749
|
}
|
|
13750
13750
|
}
|
|
13751
|
-
function canReadObservation(record2, reader2) {
|
|
13751
|
+
function canReadObservation(record2, reader2, allowedProjectIds) {
|
|
13752
13752
|
if (!reader2) return true;
|
|
13753
|
-
const sameProject = reader2.projectId === record2.projectId;
|
|
13753
|
+
const sameProject = allowedProjectIds ? allowedProjectIds.includes(record2.projectId) : reader2.projectId === record2.projectId;
|
|
13754
13754
|
const visibility = resolveObservationVisibility(record2);
|
|
13755
13755
|
if (visibility === "project") return !reader2.projectId || sameProject;
|
|
13756
13756
|
if (!sameProject || !reader2.agentId) return false;
|
|
@@ -22144,15 +22144,16 @@ function getResolvedConfig(options = {}) {
|
|
|
22144
22144
|
const openRouterMemoryLlmApiKey = isOpenRouterMemoryLane(memoryLlmProvider, memoryLlmBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
22145
22145
|
const isAtlasCloud = memoryLlmProvider === "atlascloud";
|
|
22146
22146
|
const isRequesty = memoryLlmProvider === "requesty";
|
|
22147
|
-
const
|
|
22147
|
+
const isApiRoute = memoryLlmProvider === "apiroute";
|
|
22148
|
+
const usesPresetKeyOnly = isAtlasCloud || isRequesty || isApiRoute;
|
|
22148
22149
|
const memoryLlmApiKey = first(
|
|
22149
22150
|
process.env.MEMORIX_LLM_API_KEY,
|
|
22150
22151
|
process.env.MEMORIX_API_KEY,
|
|
22151
22152
|
toml.memory?.llm?.api_key,
|
|
22152
22153
|
yaml.llm?.apiKey,
|
|
22153
22154
|
legacy.llm?.apiKey,
|
|
22154
|
-
// Never borrow another provider's credentials for
|
|
22155
|
-
isAtlasCloud ? process.env.ATLASCLOUD_API_KEY : isRequesty ? process.env.REQUESTY_API_KEY : process.env.OPENAI_API_KEY,
|
|
22155
|
+
// Never borrow another provider's credentials for these gateway presets.
|
|
22156
|
+
isAtlasCloud ? process.env.ATLASCLOUD_API_KEY : isRequesty ? process.env.REQUESTY_API_KEY : isApiRoute ? process.env.API_ROUTE_API_KEY : process.env.OPENAI_API_KEY,
|
|
22156
22157
|
usesPresetKeyOnly ? void 0 : process.env.ANTHROPIC_API_KEY,
|
|
22157
22158
|
usesPresetKeyOnly ? void 0 : openRouterMemoryLlmApiKey
|
|
22158
22159
|
);
|
|
@@ -22335,6 +22336,7 @@ function getEnvSourceNames() {
|
|
|
22335
22336
|
"MEMORIX_CODEGRAPH_EXTERNAL_TIMEOUT_MS",
|
|
22336
22337
|
"OPENROUTER_API_KEY",
|
|
22337
22338
|
"REQUESTY_API_KEY",
|
|
22339
|
+
"API_ROUTE_API_KEY",
|
|
22338
22340
|
"ATLASCLOUD_API_KEY"
|
|
22339
22341
|
].filter((name) => process.env[name]);
|
|
22340
22342
|
}
|
|
@@ -25328,6 +25330,7 @@ var init_provider2 = __esm({
|
|
|
25328
25330
|
anthropic: { baseUrl: "https://api.anthropic.com/v1", model: "claude-3-5-haiku-latest" },
|
|
25329
25331
|
openrouter: { baseUrl: "https://openrouter.ai/api/v1", model: "openai/gpt-4.1-nano" },
|
|
25330
25332
|
requesty: { baseUrl: "https://router.requesty.ai/v1", model: "openai/gpt-4.1-nano" },
|
|
25333
|
+
apiroute: { baseUrl: "https://global.api-route.com/v1", model: "deepseek-v4.1-flash" },
|
|
25331
25334
|
atlascloud: { baseUrl: "https://api.atlascloud.ai/v1", model: "deepseek-ai/deepseek-v3.2" },
|
|
25332
25335
|
custom: { baseUrl: "http://localhost:11434/v1", model: "llama3" }
|
|
25333
25336
|
};
|
|
@@ -25822,6 +25825,19 @@ var init_sqlite_store = __esm({
|
|
|
25822
25825
|
async listProjectIds() {
|
|
25823
25826
|
return this.db.prepare("SELECT DISTINCT projectId FROM observations ORDER BY projectId").all().map((row) => row.projectId).filter((projectId) => Boolean(projectId));
|
|
25824
25827
|
}
|
|
25828
|
+
async migrateProjectIds(aliasIds, canonicalId) {
|
|
25829
|
+
const sourceIds = [...new Set(aliasIds.filter((projectId) => projectId && projectId !== canonicalId))];
|
|
25830
|
+
if (sourceIds.length === 0) return 0;
|
|
25831
|
+
return retrySqliteBusy(async () => {
|
|
25832
|
+
const placeholders = sourceIds.map(() => "?").join(", ");
|
|
25833
|
+
const result = this.db.prepare(
|
|
25834
|
+
`UPDATE observations SET projectId = ? WHERE projectId IN (${placeholders})`
|
|
25835
|
+
).run(canonicalId, ...sourceIds);
|
|
25836
|
+
const migrated = Number(result.changes ?? 0);
|
|
25837
|
+
if (migrated > 0) this.bumpGeneration();
|
|
25838
|
+
return migrated;
|
|
25839
|
+
}, "Migrate observation project IDs");
|
|
25840
|
+
}
|
|
25825
25841
|
async searchLexical(options) {
|
|
25826
25842
|
return searchObservationLexically(this.db, options).map((hit) => ({
|
|
25827
25843
|
observation: rowToObs(hit.row),
|
|
@@ -186704,6 +186720,16 @@ function getProjectObservations(projectId) {
|
|
|
186704
186720
|
async function migrateProjectIds(aliasIds, canonicalId) {
|
|
186705
186721
|
const nonCanonical = new Set(aliasIds.filter((id) => id !== canonicalId));
|
|
186706
186722
|
if (nonCanonical.size === 0) return 0;
|
|
186723
|
+
const store2 = projectDir ? getObservationStore() : null;
|
|
186724
|
+
if (store2?.migrateProjectIds) {
|
|
186725
|
+
const migrated2 = await store2.migrateProjectIds(aliasIds, canonicalId);
|
|
186726
|
+
if (migrated2 > 0 && corpusLoaded) {
|
|
186727
|
+
for (const observation of observations) {
|
|
186728
|
+
if (nonCanonical.has(observation.projectId)) observation.projectId = canonicalId;
|
|
186729
|
+
}
|
|
186730
|
+
}
|
|
186731
|
+
return migrated2;
|
|
186732
|
+
}
|
|
186707
186733
|
let migrated = 0;
|
|
186708
186734
|
const changed = [];
|
|
186709
186735
|
for (const obs of observations) {
|
|
@@ -186714,8 +186740,8 @@ async function migrateProjectIds(aliasIds, canonicalId) {
|
|
|
186714
186740
|
}
|
|
186715
186741
|
}
|
|
186716
186742
|
if (migrated > 0 && projectDir) {
|
|
186717
|
-
const
|
|
186718
|
-
await
|
|
186743
|
+
const store3 = getObservationStore();
|
|
186744
|
+
await store3.atomic(async (tx) => {
|
|
186719
186745
|
await Promise.all(changed.map((observation) => tx.update(observation)));
|
|
186720
186746
|
});
|
|
186721
186747
|
}
|
|
@@ -187668,6 +187694,7 @@ var orama_store_exports = {};
|
|
|
187668
187694
|
__export(orama_store_exports, {
|
|
187669
187695
|
_classifyQueryTier: () => classifyQueryTier,
|
|
187670
187696
|
batchGenerateEmbeddings: () => batchGenerateEmbeddings,
|
|
187697
|
+
createSearchTokenizer: () => createSearchTokenizer,
|
|
187671
187698
|
generateEmbedding: () => generateEmbedding,
|
|
187672
187699
|
generateEmbeddingInput: () => generateEmbeddingInput,
|
|
187673
187700
|
getActiveSemanticIndexProfile: () => getActiveSemanticIndexProfile,
|
|
@@ -187708,6 +187735,26 @@ function getOptionalObservationStore() {
|
|
|
187708
187735
|
return null;
|
|
187709
187736
|
}
|
|
187710
187737
|
}
|
|
187738
|
+
function createSearchTokenizer() {
|
|
187739
|
+
const defaultTokenizer = components_exports2.tokenizer.createTokenizer({ language: "english" });
|
|
187740
|
+
return {
|
|
187741
|
+
language: defaultTokenizer.language,
|
|
187742
|
+
normalizationCache: defaultTokenizer.normalizationCache,
|
|
187743
|
+
tokenize(raw, language, prop, withCache = true) {
|
|
187744
|
+
const defaultTokens = defaultTokenizer.tokenize(raw, language, prop, withCache);
|
|
187745
|
+
const cjkTokens = [];
|
|
187746
|
+
const normalized = raw.normalize("NFKC").toLowerCase();
|
|
187747
|
+
for (const match2 of normalized.matchAll(CJK_RUN)) {
|
|
187748
|
+
const characters = Array.from(match2[0]);
|
|
187749
|
+
cjkTokens.push(...characters);
|
|
187750
|
+
for (let index = 0; index + 1 < characters.length; index++) {
|
|
187751
|
+
cjkTokens.push(`${characters[index]}${characters[index + 1]}`);
|
|
187752
|
+
}
|
|
187753
|
+
}
|
|
187754
|
+
return [.../* @__PURE__ */ new Set([...defaultTokens, ...cjkTokens])];
|
|
187755
|
+
}
|
|
187756
|
+
};
|
|
187757
|
+
}
|
|
187711
187758
|
async function shouldUsePersistentSearch(projectIds, projectId) {
|
|
187712
187759
|
const store2 = getOptionalObservationStore();
|
|
187713
187760
|
if (!store2?.hasLexicalIndex?.()) return false;
|
|
@@ -187808,6 +187855,7 @@ async function searchPersistentSemantically(options, projectIds, limit2, queryVe
|
|
|
187808
187855
|
const lexical = await searchPersistentLexically(options, projectIds, limit2);
|
|
187809
187856
|
const store2 = getObservationStore();
|
|
187810
187857
|
const documents = /* @__PURE__ */ new Map();
|
|
187858
|
+
const vectorDocumentKeys = /* @__PURE__ */ new Map();
|
|
187811
187859
|
const addObservation = (observation) => {
|
|
187812
187860
|
const document2 = observationToSearchDocument(observation);
|
|
187813
187861
|
documents.set(makeEntryKey(document2.projectId, document2.observationId), document2);
|
|
@@ -187823,6 +187871,7 @@ async function searchPersistentSemantically(options, projectIds, limit2, queryVe
|
|
|
187823
187871
|
if (options.type && observation.type !== options.type) return null;
|
|
187824
187872
|
if (options.source && observation.source !== options.source) return null;
|
|
187825
187873
|
addObservation(observation);
|
|
187874
|
+
vectorDocumentKeys.set(hit.observationId, makeEntryKey(observation.projectId, observation.id));
|
|
187826
187875
|
return observation;
|
|
187827
187876
|
}));
|
|
187828
187877
|
const RRF_K = 60;
|
|
@@ -187832,7 +187881,7 @@ async function searchPersistentSemantically(options, projectIds, limit2, queryVe
|
|
|
187832
187881
|
scores.set(key, (scores.get(key) ?? 0) + 0.6 / (RRF_K + index + 1));
|
|
187833
187882
|
}
|
|
187834
187883
|
for (const [index, hit] of vectorHits.entries()) {
|
|
187835
|
-
const key = makeEntryKey(hit.projectId, hit.observationId);
|
|
187884
|
+
const key = vectorDocumentKeys.get(hit.observationId) ?? makeEntryKey(hit.projectId, hit.observationId);
|
|
187836
187885
|
if (!documents.has(key)) continue;
|
|
187837
187886
|
scores.set(key, (scores.get(key) ?? 0) + 0.4 / (RRF_K + index + 1));
|
|
187838
187887
|
}
|
|
@@ -187845,12 +187894,13 @@ async function searchPersistentSemantically(options, projectIds, limit2, queryVe
|
|
|
187845
187894
|
return {
|
|
187846
187895
|
count: vectorHits.length,
|
|
187847
187896
|
hits: vectorHits.map((hit, index) => {
|
|
187848
|
-
const key = makeEntryKey(hit.projectId, hit.observationId);
|
|
187897
|
+
const key = vectorDocumentKeys.get(hit.observationId) ?? makeEntryKey(hit.projectId, hit.observationId);
|
|
187849
187898
|
const document2 = documents.get(key);
|
|
187850
187899
|
return document2 ? { id: document2.id, score: 0.4 / (RRF_K + index + 1), document: document2 } : null;
|
|
187851
187900
|
}).filter((hit) => hit !== null).slice(0, limit2)
|
|
187852
187901
|
};
|
|
187853
187902
|
}
|
|
187903
|
+
if (hits.length === 0) return null;
|
|
187854
187904
|
return { count: hits.length, hits };
|
|
187855
187905
|
} catch {
|
|
187856
187906
|
return null;
|
|
@@ -187925,7 +187975,10 @@ async function initializeDb(options, generation) {
|
|
|
187925
187975
|
};
|
|
187926
187976
|
const dims = nextEmbeddingDimensions ?? 384;
|
|
187927
187977
|
const schema = nextEmbeddingEnabled ? { ...baseSchema, embedding: `vector[${dims}]` } : baseSchema;
|
|
187928
|
-
const nextDb = await create5({
|
|
187978
|
+
const nextDb = await create5({
|
|
187979
|
+
schema,
|
|
187980
|
+
components: { tokenizer: createSearchTokenizer() }
|
|
187981
|
+
});
|
|
187929
187982
|
if (generation !== dbGeneration) {
|
|
187930
187983
|
return getDb(options);
|
|
187931
187984
|
}
|
|
@@ -188359,7 +188412,7 @@ async function searchObservations(options) {
|
|
|
188359
188412
|
if (!projectIds) return true;
|
|
188360
188413
|
const doc = hit.document;
|
|
188361
188414
|
return projectIds.includes(doc.projectId);
|
|
188362
|
-
}).filter((hit) => canReadObservation(hit.document, options.reader)).filter((hit) => {
|
|
188415
|
+
}).filter((hit) => canReadObservation(hit.document, options.reader, projectIds ?? void 0)).filter((hit) => {
|
|
188363
188416
|
if (statusFilter === "all") return true;
|
|
188364
188417
|
const doc = hit.document;
|
|
188365
188418
|
return (doc.status || "active") === statusFilter;
|
|
@@ -188625,7 +188678,7 @@ async function searchObservations(options) {
|
|
|
188625
188678
|
let entries = intermediate.map(({ rawTime: _5, _isCommandLog: _c, ...rest }) => rest);
|
|
188626
188679
|
for (const hit of results.hits) {
|
|
188627
188680
|
const doc = hit.document;
|
|
188628
|
-
if (canReadObservation(doc, options.reader)) rememberObservationDoc(doc);
|
|
188681
|
+
if (canReadObservation(doc, options.reader, projectIds ?? void 0)) rememberObservationDoc(doc);
|
|
188629
188682
|
}
|
|
188630
188683
|
if (hasQuery && originalQuery) {
|
|
188631
188684
|
const queryLower = originalQuery.toLowerCase();
|
|
@@ -188783,7 +188836,7 @@ function formatTime(isoDate) {
|
|
|
188783
188836
|
return isoDate;
|
|
188784
188837
|
}
|
|
188785
188838
|
}
|
|
188786
|
-
var db, dbInitPromise, dbGeneration, embeddingEnabled, embeddingDimensions, indexEmbeddingProvider, deferredCachedVectorHydration, NON_CJK_HYBRID_SIMILARITY, lastSearchModeByProject, SEARCH_MODE_DEFAULT_KEY, MAX_SEARCH_MODE_KEYS, COMMAND_LOG_TITLE2, COMMAND_STYLE_TITLE, COMMAND_LIKE_QUERY2, COMMAND_INTENT_QUERY, NATURAL_LANGUAGE_MARKERS;
|
|
188839
|
+
var db, dbInitPromise, dbGeneration, embeddingEnabled, embeddingDimensions, indexEmbeddingProvider, deferredCachedVectorHydration, NON_CJK_HYBRID_SIMILARITY, CJK_RUN, lastSearchModeByProject, SEARCH_MODE_DEFAULT_KEY, MAX_SEARCH_MODE_KEYS, COMMAND_LOG_TITLE2, COMMAND_STYLE_TITLE, COMMAND_LIKE_QUERY2, COMMAND_INTENT_QUERY, NATURAL_LANGUAGE_MARKERS;
|
|
188787
188840
|
var init_orama_store = __esm({
|
|
188788
188841
|
"src/store/orama-store.ts"() {
|
|
188789
188842
|
"use strict";
|
|
@@ -188808,6 +188861,7 @@ var init_orama_store = __esm({
|
|
|
188808
188861
|
indexEmbeddingProvider = null;
|
|
188809
188862
|
deferredCachedVectorHydration = null;
|
|
188810
188863
|
NON_CJK_HYBRID_SIMILARITY = 0.45;
|
|
188864
|
+
CJK_RUN = /[\u3400-\u4dbf\u4e00-\u9fff\u3040-\u30ff\uac00-\ud7af]+/gu;
|
|
188811
188865
|
lastSearchModeByProject = /* @__PURE__ */ new Map();
|
|
188812
188866
|
SEARCH_MODE_DEFAULT_KEY = "__global__";
|
|
188813
188867
|
MAX_SEARCH_MODE_KEYS = 4096;
|
|
@@ -193112,6 +193166,8 @@ function buildInitTomlConfig(options) {
|
|
|
193112
193166
|
lines.push('# model = "openai/gpt-4o-mini"');
|
|
193113
193167
|
} else if (options.llmProvider === "requesty") {
|
|
193114
193168
|
lines.push('# model = "openai/gpt-4o-mini"');
|
|
193169
|
+
} else if (options.llmProvider === "apiroute") {
|
|
193170
|
+
lines.push('model = "deepseek-v4.1-flash"');
|
|
193115
193171
|
} else if (options.llmProvider === "atlascloud") {
|
|
193116
193172
|
lines.push('model = "deepseek-ai/deepseek-v3.2"');
|
|
193117
193173
|
}
|
|
@@ -193247,6 +193303,7 @@ var init_init = __esm({
|
|
|
193247
193303
|
{ value: "anthropic", label: "Anthropic", hint: "claude-3-haiku" },
|
|
193248
193304
|
{ value: "openrouter", label: "OpenRouter", hint: "multi-provider" },
|
|
193249
193305
|
{ value: "requesty", label: "Requesty", hint: "multi-provider" },
|
|
193306
|
+
{ value: "apiroute", label: "API Route", hint: "multi-provider" },
|
|
193250
193307
|
{ value: "atlascloud", label: "Atlas Cloud", hint: "DeepSeek V3.2" },
|
|
193251
193308
|
{ value: "custom", label: "Custom", hint: "OpenAI-compatible endpoint" }
|
|
193252
193309
|
]
|
|
@@ -193301,7 +193358,7 @@ var init_init = __esm({
|
|
|
193301
193358
|
];
|
|
193302
193359
|
if (llmProvider !== "none") {
|
|
193303
193360
|
envLines.push("# LLM API key");
|
|
193304
|
-
if (llmProvider === "openai" || llmProvider === "custom" || llmProvider === "atlascloud") {
|
|
193361
|
+
if (llmProvider === "openai" || llmProvider === "custom" || llmProvider === "atlascloud" || llmProvider === "apiroute") {
|
|
193305
193362
|
envLines.push("MEMORIX_LLM_API_KEY=sk-your-key-here");
|
|
193306
193363
|
} else if (llmProvider === "anthropic") {
|
|
193307
193364
|
envLines.push("MEMORIX_LLM_API_KEY=sk-ant-your-key-here");
|
|
@@ -193336,6 +193393,7 @@ var init_init = __esm({
|
|
|
193336
193393
|
envLines.push("# ANTHROPIC_API_KEY=sk-ant-...");
|
|
193337
193394
|
envLines.push("# OPENROUTER_API_KEY=sk-or-...");
|
|
193338
193395
|
envLines.push("# REQUESTY_API_KEY=rqsty-...");
|
|
193396
|
+
envLines.push("# API_ROUTE_API_KEY=sk-...");
|
|
193339
193397
|
envLines.push("");
|
|
193340
193398
|
mkdirSync3(targetDir, { recursive: true });
|
|
193341
193399
|
writeFileSync3(targetPath, tomlContent, "utf-8");
|
|
@@ -195224,6 +195282,26 @@ function generateClaudeConfig() {
|
|
|
195224
195282
|
}
|
|
195225
195283
|
};
|
|
195226
195284
|
}
|
|
195285
|
+
function generateQwenConfig() {
|
|
195286
|
+
const cmd = `${resolveHookCommand()} hook --agent qwen`;
|
|
195287
|
+
const hookEntry = {
|
|
195288
|
+
type: "command",
|
|
195289
|
+
command: cmd,
|
|
195290
|
+
timeout: 10
|
|
195291
|
+
};
|
|
195292
|
+
return {
|
|
195293
|
+
hooks: {
|
|
195294
|
+
SessionStart: [{ hooks: [hookEntry] }],
|
|
195295
|
+
SessionEnd: [{ hooks: [hookEntry] }],
|
|
195296
|
+
PostToolUse: [{ hooks: [hookEntry] }],
|
|
195297
|
+
PostToolUseFailure: [{ hooks: [hookEntry] }],
|
|
195298
|
+
UserPromptSubmit: [{ hooks: [hookEntry] }],
|
|
195299
|
+
PreCompact: [{ hooks: [hookEntry] }],
|
|
195300
|
+
PostCompact: [{ hooks: [hookEntry] }],
|
|
195301
|
+
Stop: [{ hooks: [hookEntry] }]
|
|
195302
|
+
}
|
|
195303
|
+
};
|
|
195304
|
+
}
|
|
195227
195305
|
function generateGrokConfig() {
|
|
195228
195306
|
const cmd = `${resolveHookCommand()} hook --agent grok`;
|
|
195229
195307
|
const hookEntry = {
|
|
@@ -195254,7 +195332,13 @@ function isMemorixGrokCommand(value) {
|
|
|
195254
195332
|
function isMemorixGrokHook(value) {
|
|
195255
195333
|
return isJsonRecord(value) && value.type === "command" && isMemorixGrokCommand(value.command);
|
|
195256
195334
|
}
|
|
195257
|
-
function
|
|
195335
|
+
function isMemorixQwenCommand(value) {
|
|
195336
|
+
return value === "memorix hook --agent qwen" || value === "memorix.cmd hook --agent qwen";
|
|
195337
|
+
}
|
|
195338
|
+
function isMemorixQwenHook(value) {
|
|
195339
|
+
return isJsonRecord(value) && value.type === "command" && isMemorixQwenCommand(value.command);
|
|
195340
|
+
}
|
|
195341
|
+
function mergeCommandHookConfig(existing, generated, isOwnedHook) {
|
|
195258
195342
|
const merged = { ...existing };
|
|
195259
195343
|
const existingHooks = isJsonRecord(existing.hooks) ? { ...existing.hooks } : {};
|
|
195260
195344
|
const generatedHooks = isJsonRecord(generated.hooks) ? generated.hooks : {};
|
|
@@ -195262,7 +195346,7 @@ function mergeGrokHookConfig(existing, generated) {
|
|
|
195262
195346
|
const currentGroups = Array.isArray(existingHooks[event]) ? existingHooks[event] : [];
|
|
195263
195347
|
const preservedGroups = currentGroups.flatMap((group) => {
|
|
195264
195348
|
if (!isJsonRecord(group) || !Array.isArray(group.hooks)) return [group];
|
|
195265
|
-
const preservedHooks = group.hooks.filter((hook) => !
|
|
195349
|
+
const preservedHooks = group.hooks.filter((hook) => !isOwnedHook(hook));
|
|
195266
195350
|
if (preservedHooks.length === 0) return [];
|
|
195267
195351
|
return [{ ...group, hooks: preservedHooks }];
|
|
195268
195352
|
});
|
|
@@ -195271,7 +195355,13 @@ function mergeGrokHookConfig(existing, generated) {
|
|
|
195271
195355
|
merged.hooks = existingHooks;
|
|
195272
195356
|
return merged;
|
|
195273
195357
|
}
|
|
195274
|
-
function
|
|
195358
|
+
function mergeGrokHookConfig(existing, generated) {
|
|
195359
|
+
return mergeCommandHookConfig(existing, generated, isMemorixGrokHook);
|
|
195360
|
+
}
|
|
195361
|
+
function mergeQwenHookConfig(existing, generated) {
|
|
195362
|
+
return mergeCommandHookConfig(existing, generated, isMemorixQwenHook);
|
|
195363
|
+
}
|
|
195364
|
+
function removeCommandHooks(config2, isOwnedHook) {
|
|
195275
195365
|
const cleaned = { ...config2 };
|
|
195276
195366
|
const hooks = isJsonRecord(config2.hooks) ? { ...config2.hooks } : null;
|
|
195277
195367
|
if (!hooks) return cleaned;
|
|
@@ -195279,7 +195369,7 @@ function removeMemorixGrokHooks(config2) {
|
|
|
195279
195369
|
if (!Array.isArray(groups)) continue;
|
|
195280
195370
|
const preservedGroups = groups.flatMap((group) => {
|
|
195281
195371
|
if (!isJsonRecord(group) || !Array.isArray(group.hooks)) return [group];
|
|
195282
|
-
const preservedHooks = group.hooks.filter((hook) => !
|
|
195372
|
+
const preservedHooks = group.hooks.filter((hook) => !isOwnedHook(hook));
|
|
195283
195373
|
if (preservedHooks.length === 0) return [];
|
|
195284
195374
|
return [{ ...group, hooks: preservedHooks }];
|
|
195285
195375
|
});
|
|
@@ -195290,6 +195380,12 @@ function removeMemorixGrokHooks(config2) {
|
|
|
195290
195380
|
else delete cleaned.hooks;
|
|
195291
195381
|
return cleaned;
|
|
195292
195382
|
}
|
|
195383
|
+
function removeMemorixGrokHooks(config2) {
|
|
195384
|
+
return removeCommandHooks(config2, isMemorixGrokHook);
|
|
195385
|
+
}
|
|
195386
|
+
function removeMemorixQwenHooks(config2) {
|
|
195387
|
+
return removeCommandHooks(config2, isMemorixQwenHook);
|
|
195388
|
+
}
|
|
195293
195389
|
async function readGrokHookConfig(configPath) {
|
|
195294
195390
|
let content;
|
|
195295
195391
|
try {
|
|
@@ -195308,6 +195404,24 @@ async function readGrokHookConfig(configPath) {
|
|
|
195308
195404
|
throw new Error(`Cannot safely update Grok hook config ${configPath}: ${reason}`);
|
|
195309
195405
|
}
|
|
195310
195406
|
}
|
|
195407
|
+
async function readQwenHookConfig(configPath) {
|
|
195408
|
+
let content;
|
|
195409
|
+
try {
|
|
195410
|
+
content = await fs19.readFile(configPath, "utf-8");
|
|
195411
|
+
} catch (error40) {
|
|
195412
|
+
if (error40.code === "ENOENT") return {};
|
|
195413
|
+
throw error40;
|
|
195414
|
+
}
|
|
195415
|
+
if (!content.trim()) return {};
|
|
195416
|
+
try {
|
|
195417
|
+
const parsed = JSON.parse(content);
|
|
195418
|
+
if (!isJsonRecord(parsed)) throw new Error("top-level value must be an object");
|
|
195419
|
+
return parsed;
|
|
195420
|
+
} catch (error40) {
|
|
195421
|
+
const reason = error40 instanceof Error ? error40.message : String(error40);
|
|
195422
|
+
throw new Error(`Cannot safely update Qwen hook config ${configPath}: ${reason}`);
|
|
195423
|
+
}
|
|
195424
|
+
}
|
|
195311
195425
|
function generateCopilotConfig() {
|
|
195312
195426
|
const cmd = `${resolveHookCommand()} hook`;
|
|
195313
195427
|
const hasPwsh = detectPwsh();
|
|
@@ -195509,6 +195623,8 @@ function generateOpenCodePlugin() {
|
|
|
195509
195623
|
*/
|
|
195510
195624
|
import { spawnSync } from 'node:child_process';
|
|
195511
195625
|
|
|
195626
|
+
const HOOK_TIMEOUT_MS = 30_000;
|
|
195627
|
+
|
|
195512
195628
|
export const MemorixPlugin = async ({ project, client, $, directory, worktree }) => {
|
|
195513
195629
|
// Generate a stable session ID for this plugin lifetime
|
|
195514
195630
|
const sessionId = \`opencode-\${Date.now().toString(36)}-\${Math.random().toString(36).slice(2, 8)}\`;
|
|
@@ -195534,14 +195650,14 @@ export const MemorixPlugin = async ({ project, client, $, directory, worktree })
|
|
|
195534
195650
|
* - spawnSync is simpler: no stream lifecycle, no writer.close() bugs
|
|
195535
195651
|
* - stdin pipe via input option is reliable cross-platform
|
|
195536
195652
|
*/
|
|
195537
|
-
function runHook(payload) {
|
|
195538
|
-
payload.session_id =
|
|
195653
|
+
function runHook(payload, activeSessionId = sessionId) {
|
|
195654
|
+
payload.session_id = activeSessionId;
|
|
195539
195655
|
const data = JSON.stringify(payload);
|
|
195540
195656
|
const eventName = payload.hook_event_name || 'unknown';
|
|
195541
195657
|
try {
|
|
195542
195658
|
const result = spawnSync(hookCommand, ['hook'], {
|
|
195543
195659
|
input: data,
|
|
195544
|
-
timeout:
|
|
195660
|
+
timeout: HOOK_TIMEOUT_MS,
|
|
195545
195661
|
encoding: 'utf-8',
|
|
195546
195662
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
195547
195663
|
shell: process.platform === 'win32',
|
|
@@ -195586,7 +195702,87 @@ export const MemorixPlugin = async ({ project, client, $, directory, worktree })
|
|
|
195586
195702
|
.trim();
|
|
195587
195703
|
}
|
|
195588
195704
|
|
|
195705
|
+
function flushAssistantResponse(activeSessionId = sessionId) {
|
|
195706
|
+
if (!pendingAssistantResponse?.text) return;
|
|
195707
|
+
const deliveryKey = pendingAssistantResponse.id
|
|
195708
|
+
? \`\${pendingAssistantResponse.id}:\${pendingAssistantResponse.text}\`
|
|
195709
|
+
: pendingAssistantResponse.text;
|
|
195710
|
+
if (deliveryKey === lastDeliveredAssistantKey) return;
|
|
195711
|
+
runHook({
|
|
195712
|
+
agent: 'opencode',
|
|
195713
|
+
hook_event_name: 'message.updated',
|
|
195714
|
+
ai_response: pendingAssistantResponse.text,
|
|
195715
|
+
message_id: pendingAssistantResponse.id,
|
|
195716
|
+
cwd: directory,
|
|
195717
|
+
}, activeSessionId);
|
|
195718
|
+
lastDeliveredAssistantKey = deliveryKey;
|
|
195719
|
+
}
|
|
195720
|
+
|
|
195721
|
+
function eventSessionId(event) {
|
|
195722
|
+
const properties = event?.properties ?? {};
|
|
195723
|
+
const value = properties.sessionID ?? properties.sessionId ?? properties.info?.id;
|
|
195724
|
+
return typeof value === 'string' && value ? value : sessionId;
|
|
195725
|
+
}
|
|
195726
|
+
|
|
195727
|
+
async function handleEvent({ event }) {
|
|
195728
|
+
const properties = event?.properties ?? {};
|
|
195729
|
+
const activeSessionId = eventSessionId(event);
|
|
195730
|
+
switch (event?.type) {
|
|
195731
|
+
case 'session.created':
|
|
195732
|
+
runHook({
|
|
195733
|
+
agent: 'opencode',
|
|
195734
|
+
hook_event_name: 'session.created',
|
|
195735
|
+
cwd: directory,
|
|
195736
|
+
}, activeSessionId);
|
|
195737
|
+
break;
|
|
195738
|
+
case 'session.idle':
|
|
195739
|
+
flushAssistantResponse(activeSessionId);
|
|
195740
|
+
runHook({
|
|
195741
|
+
agent: 'opencode',
|
|
195742
|
+
hook_event_name: 'session.idle',
|
|
195743
|
+
cwd: directory,
|
|
195744
|
+
}, activeSessionId);
|
|
195745
|
+
break;
|
|
195746
|
+
case 'file.edited':
|
|
195747
|
+
runHook({
|
|
195748
|
+
agent: 'opencode',
|
|
195749
|
+
hook_event_name: 'file.edited',
|
|
195750
|
+
file_path: properties.file ?? properties.path ?? '',
|
|
195751
|
+
cwd: directory,
|
|
195752
|
+
}, activeSessionId);
|
|
195753
|
+
break;
|
|
195754
|
+
case 'command.executed':
|
|
195755
|
+
runHook({
|
|
195756
|
+
agent: 'opencode',
|
|
195757
|
+
hook_event_name: 'command.executed',
|
|
195758
|
+
command: properties.name ?? properties.command ?? '',
|
|
195759
|
+
cwd: directory,
|
|
195760
|
+
}, activeSessionId);
|
|
195761
|
+
break;
|
|
195762
|
+
case 'message.updated': {
|
|
195763
|
+
const message = properties.info ?? properties.message ?? properties;
|
|
195764
|
+
if (message?.role !== 'assistant') break;
|
|
195765
|
+
const text = extractMessageText(message);
|
|
195766
|
+
if (!text) break;
|
|
195767
|
+
pendingAssistantResponse = { id: message.id, text };
|
|
195768
|
+
break;
|
|
195769
|
+
}
|
|
195770
|
+
case 'session.compacted':
|
|
195771
|
+
runHook({
|
|
195772
|
+
agent: 'opencode',
|
|
195773
|
+
hook_event_name: 'session.compacted',
|
|
195774
|
+
cwd: directory,
|
|
195775
|
+
}, activeSessionId);
|
|
195776
|
+
break;
|
|
195777
|
+
default:
|
|
195778
|
+
break;
|
|
195779
|
+
}
|
|
195780
|
+
}
|
|
195781
|
+
|
|
195589
195782
|
return {
|
|
195783
|
+
// OpenCode 1.x delivers lifecycle/file/command/message events through this
|
|
195784
|
+
// generic hook. The named keys below remain for older compatible hosts.
|
|
195785
|
+
event: handleEvent,
|
|
195590
195786
|
/** Session created \u2014 record session start */
|
|
195591
195787
|
'session.created': async ({ session }) => {
|
|
195592
195788
|
runHook({
|
|
@@ -195598,21 +195794,7 @@ export const MemorixPlugin = async ({ project, client, $, directory, worktree })
|
|
|
195598
195794
|
|
|
195599
195795
|
/** Session idle \u2014 record session end */
|
|
195600
195796
|
'session.idle': async ({ session }) => {
|
|
195601
|
-
|
|
195602
|
-
const deliveryKey = pendingAssistantResponse.id
|
|
195603
|
-
? \`\${pendingAssistantResponse.id}:\${pendingAssistantResponse.text}\`
|
|
195604
|
-
: pendingAssistantResponse.text;
|
|
195605
|
-
if (deliveryKey !== lastDeliveredAssistantKey) {
|
|
195606
|
-
runHook({
|
|
195607
|
-
agent: 'opencode',
|
|
195608
|
-
hook_event_name: 'message.updated',
|
|
195609
|
-
ai_response: pendingAssistantResponse.text,
|
|
195610
|
-
message_id: pendingAssistantResponse.id,
|
|
195611
|
-
cwd: directory,
|
|
195612
|
-
});
|
|
195613
|
-
lastDeliveredAssistantKey = deliveryKey;
|
|
195614
|
-
}
|
|
195615
|
-
}
|
|
195797
|
+
flushAssistantResponse();
|
|
195616
195798
|
runHook({
|
|
195617
195799
|
agent: 'opencode',
|
|
195618
195800
|
hook_event_name: 'session.idle',
|
|
@@ -195720,7 +195902,7 @@ function v2RunHook(payload, directory, sessionId) {
|
|
|
195720
195902
|
try {
|
|
195721
195903
|
const result = spawnSync(v2HookCommand, ['hook'], {
|
|
195722
195904
|
input: JSON.stringify(nextPayload),
|
|
195723
|
-
timeout:
|
|
195905
|
+
timeout: HOOK_TIMEOUT_MS,
|
|
195724
195906
|
encoding: 'utf-8',
|
|
195725
195907
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
195726
195908
|
shell: process.platform === 'win32',
|
|
@@ -195844,7 +196026,7 @@ function setup(ctx) {
|
|
|
195844
196026
|
return () => controller.abort();
|
|
195845
196027
|
}
|
|
195846
196028
|
|
|
195847
|
-
export default { id: 'memorix', setup };
|
|
196029
|
+
export default { id: 'memorix', server: MemorixPlugin, setup };
|
|
195848
196030
|
`;
|
|
195849
196031
|
}
|
|
195850
196032
|
async function installOpenCodeSkills(projectRoot, global2 = false) {
|
|
@@ -195854,6 +196036,8 @@ function getProjectConfigPath(agent, projectRoot) {
|
|
|
195854
196036
|
switch (agent) {
|
|
195855
196037
|
case "claude":
|
|
195856
196038
|
return path31.join(projectRoot, ".claude", "settings.local.json");
|
|
196039
|
+
case "qwen":
|
|
196040
|
+
return path31.join(projectRoot, ".qwen", "settings.json");
|
|
195857
196041
|
case "copilot":
|
|
195858
196042
|
return path31.join(projectRoot, ".github", "hooks", "memorix.json");
|
|
195859
196043
|
case "windsurf":
|
|
@@ -195895,6 +196079,8 @@ function getGlobalConfigPath(agent) {
|
|
|
195895
196079
|
switch (agent) {
|
|
195896
196080
|
case "claude":
|
|
195897
196081
|
return path31.join(home, ".claude", "settings.json");
|
|
196082
|
+
case "qwen":
|
|
196083
|
+
return path31.join(home, ".qwen", "settings.json");
|
|
195898
196084
|
case "copilot":
|
|
195899
196085
|
return "";
|
|
195900
196086
|
case "windsurf":
|
|
@@ -195936,6 +196122,8 @@ function getAgentRulesPath(agent, root, global2 = false) {
|
|
|
195936
196122
|
return path31.join(root, ".cursor", "rules", "memorix.mdc");
|
|
195937
196123
|
case "claude":
|
|
195938
196124
|
return path31.join(root, ".claude", "CLAUDE.md");
|
|
196125
|
+
case "qwen":
|
|
196126
|
+
return path31.join(root, ".qwen", "QWEN.md");
|
|
195939
196127
|
case "codex":
|
|
195940
196128
|
return path31.join(root, ".codex", "AGENTS.md");
|
|
195941
196129
|
case "kiro":
|
|
@@ -195964,6 +196152,8 @@ function getAgentRulesPath(agent, root, global2 = false) {
|
|
|
195964
196152
|
return path31.join(root, ".cursor", "rules", "memorix.mdc");
|
|
195965
196153
|
case "claude":
|
|
195966
196154
|
return path31.join(root, "CLAUDE.md");
|
|
196155
|
+
case "qwen":
|
|
196156
|
+
return path31.join(root, "QWEN.md");
|
|
195967
196157
|
case "copilot":
|
|
195968
196158
|
return path31.join(root, ".github", "copilot-instructions.md");
|
|
195969
196159
|
case "codex":
|
|
@@ -196040,6 +196230,12 @@ async function detectInstalledAgents() {
|
|
|
196040
196230
|
agents.push("grok");
|
|
196041
196231
|
} catch {
|
|
196042
196232
|
}
|
|
196233
|
+
const qwenDir = path31.join(home, ".qwen");
|
|
196234
|
+
try {
|
|
196235
|
+
await fs19.access(qwenDir);
|
|
196236
|
+
agents.push("qwen");
|
|
196237
|
+
} catch {
|
|
196238
|
+
}
|
|
196043
196239
|
const codexDir = path31.join(home, ".codex");
|
|
196044
196240
|
try {
|
|
196045
196241
|
await fs19.access(codexDir);
|
|
@@ -196123,10 +196319,10 @@ async function installHooks(agent, projectRoot, global2 = false) {
|
|
|
196123
196319
|
const { access: access5, unlink: unlink3 } = await import("fs/promises");
|
|
196124
196320
|
await access5(entry.path);
|
|
196125
196321
|
const basename7 = path31.basename(entry.path);
|
|
196126
|
-
if (basename7 === "AGENTS.md" || basename7 === "GEMINI.md" || basename7 === "CONTEXT.md") {
|
|
196322
|
+
if (basename7 === "AGENTS.md" || basename7 === "GEMINI.md" || basename7 === "QWEN.md" || basename7 === "CONTEXT.md") {
|
|
196127
196323
|
continue;
|
|
196128
196324
|
}
|
|
196129
|
-
if (agent === "grok" && path31.resolve(entry.path) === path31.resolve(configPath)) {
|
|
196325
|
+
if ((agent === "grok" || agent === "qwen") && path31.resolve(entry.path) === path31.resolve(configPath)) {
|
|
196130
196326
|
continue;
|
|
196131
196327
|
}
|
|
196132
196328
|
await unlink3(entry.path);
|
|
@@ -196141,6 +196337,9 @@ async function installHooks(agent, projectRoot, global2 = false) {
|
|
|
196141
196337
|
case "claude":
|
|
196142
196338
|
generated = generateClaudeConfig();
|
|
196143
196339
|
break;
|
|
196340
|
+
case "qwen":
|
|
196341
|
+
generated = generateQwenConfig();
|
|
196342
|
+
break;
|
|
196144
196343
|
case "grok":
|
|
196145
196344
|
generated = generateGrokConfig();
|
|
196146
196345
|
break;
|
|
@@ -196247,6 +196446,15 @@ async function installHooks(agent, projectRoot, global2 = false) {
|
|
|
196247
196446
|
await recordFile2(projectRoot, "hook", configPath, agent);
|
|
196248
196447
|
} catch {
|
|
196249
196448
|
}
|
|
196449
|
+
} else if (agent === "qwen") {
|
|
196450
|
+
const existing = await readQwenHookConfig(configPath);
|
|
196451
|
+
const merged = mergeQwenHookConfig(existing, generated);
|
|
196452
|
+
await fs19.writeFile(configPath, JSON.stringify(merged, null, 2), "utf-8");
|
|
196453
|
+
try {
|
|
196454
|
+
const { recordFile: recordFile2 } = await Promise.resolve().then(() => (init_audit(), audit_exports));
|
|
196455
|
+
await recordFile2(projectRoot, "hook", configPath, agent);
|
|
196456
|
+
} catch {
|
|
196457
|
+
}
|
|
196250
196458
|
} else if (agent === "kiro") {
|
|
196251
196459
|
const hookFiles = generateKiroHookFiles();
|
|
196252
196460
|
const hooksDir = path31.join(path31.dirname(configPath));
|
|
@@ -196310,6 +196518,9 @@ async function installHooks(agent, projectRoot, global2 = false) {
|
|
|
196310
196518
|
case "claude":
|
|
196311
196519
|
events.push("session_start", "post_tool", "user_prompt", "pre_compact", "session_end");
|
|
196312
196520
|
break;
|
|
196521
|
+
case "qwen":
|
|
196522
|
+
events.push("session_start", "session_end", "user_prompt", "post_tool", "pre_compact", "post_compact");
|
|
196523
|
+
break;
|
|
196313
196524
|
case "copilot":
|
|
196314
196525
|
events.push("session_start", "session_end", "user_prompt", "post_tool");
|
|
196315
196526
|
break;
|
|
@@ -196351,7 +196562,7 @@ async function installAgentRules(agent, projectRoot, global2 = false) {
|
|
|
196351
196562
|
const rulesPath = getAgentRulesPath(agent, rulesRoot, global2);
|
|
196352
196563
|
try {
|
|
196353
196564
|
await fs19.mkdir(path31.dirname(rulesPath), { recursive: true });
|
|
196354
|
-
if (agent === "claude" || agent === "codex" || agent === "opencode" || agent === "antigravity" || agent === "gemini-cli" || agent === "dsh" || agent === "grok") {
|
|
196565
|
+
if (agent === "claude" || agent === "qwen" || agent === "codex" || agent === "opencode" || agent === "antigravity" || agent === "gemini-cli" || agent === "dsh" || agent === "grok") {
|
|
196355
196566
|
try {
|
|
196356
196567
|
const existing = await fs19.readFile(rulesPath, "utf-8");
|
|
196357
196568
|
await fs19.writeFile(rulesPath, mergeMemorixRulesContent(existing, rulesContent), "utf-8");
|
|
@@ -196529,6 +196740,15 @@ async function uninstallHooks(agent, projectRoot, global2 = false) {
|
|
|
196529
196740
|
await fs19.writeFile(configPath, JSON.stringify(cleaned, null, 2), "utf-8");
|
|
196530
196741
|
}
|
|
196531
196742
|
success2 = true;
|
|
196743
|
+
} else if (agent === "qwen") {
|
|
196744
|
+
const config2 = await readQwenHookConfig(configPath);
|
|
196745
|
+
const cleaned = removeMemorixQwenHooks(config2);
|
|
196746
|
+
if (Object.keys(cleaned).length === 0) {
|
|
196747
|
+
await fs19.unlink(configPath);
|
|
196748
|
+
} else {
|
|
196749
|
+
await fs19.writeFile(configPath, JSON.stringify(cleaned, null, 2), "utf-8");
|
|
196750
|
+
}
|
|
196751
|
+
success2 = true;
|
|
196532
196752
|
} else if (agent === "kiro" || agent === "opencode") {
|
|
196533
196753
|
await fs19.unlink(configPath);
|
|
196534
196754
|
success2 = true;
|
|
@@ -196552,13 +196772,13 @@ async function uninstallHooks(agent, projectRoot, global2 = false) {
|
|
|
196552
196772
|
const agentFiles = prevFiles.filter((e5) => e5.agent === agent);
|
|
196553
196773
|
for (const entry of agentFiles) {
|
|
196554
196774
|
try {
|
|
196555
|
-
if (agent === "grok" && path31.resolve(entry.path) === path31.resolve(configPath)) {
|
|
196775
|
+
if ((agent === "grok" || agent === "qwen") && path31.resolve(entry.path) === path31.resolve(configPath)) {
|
|
196556
196776
|
await removeFile2(projectRoot, entry.path);
|
|
196557
196777
|
auditCleaned = true;
|
|
196558
196778
|
continue;
|
|
196559
196779
|
}
|
|
196560
196780
|
const basename7 = path31.basename(entry.path);
|
|
196561
|
-
if (basename7 === "AGENTS.md" || basename7 === "GEMINI.md" || basename7 === "CONTEXT.md") {
|
|
196781
|
+
if (basename7 === "AGENTS.md" || basename7 === "GEMINI.md" || basename7 === "QWEN.md" || basename7 === "CONTEXT.md") {
|
|
196562
196782
|
try {
|
|
196563
196783
|
const content = await fs19.readFile(entry.path, "utf-8");
|
|
196564
196784
|
const memorixStart = content.indexOf("# Memorix");
|
|
@@ -196617,7 +196837,7 @@ async function uninstallHooks(agent, projectRoot, global2 = false) {
|
|
|
196617
196837
|
}
|
|
196618
196838
|
async function getHookStatus(projectRoot) {
|
|
196619
196839
|
const results = [];
|
|
196620
|
-
const agents = ["claude", "copilot", "windsurf", "cursor", "kiro", "codex", "antigravity", "gemini-cli", "opencode", "pi", "trae", "grok"];
|
|
196840
|
+
const agents = ["claude", "qwen", "copilot", "windsurf", "cursor", "kiro", "codex", "antigravity", "gemini-cli", "opencode", "pi", "trae", "grok"];
|
|
196621
196841
|
for (const agent of agents) {
|
|
196622
196842
|
const projectPath = getProjectConfigPath(agent, projectRoot);
|
|
196623
196843
|
const globalPath = getGlobalConfigPath(agent);
|
|
@@ -196670,7 +196890,7 @@ var init_installers = __esm({
|
|
|
196670
196890
|
"use strict";
|
|
196671
196891
|
init_esm_shims();
|
|
196672
196892
|
init_official_skills();
|
|
196673
|
-
OPENCODE_PLUGIN_VERSION =
|
|
196893
|
+
OPENCODE_PLUGIN_VERSION = 9;
|
|
196674
196894
|
AGENT_SKILL_DIRS = {
|
|
196675
196895
|
cursor: { project: path31.join(".cursor", "skills"), global: path31.join(".cursor", "skills") },
|
|
196676
196896
|
windsurf: { project: path31.join(".windsurf", "skills"), global: path31.join(".windsurf", "skills") },
|
|
@@ -198379,6 +198599,7 @@ async function installSingleAgent(installHooks2, agent, targetRoot, global2) {
|
|
|
198379
198599
|
function getAgentLabel(agent) {
|
|
198380
198600
|
const labels = {
|
|
198381
198601
|
claude: "Claude Code",
|
|
198602
|
+
qwen: "Qwen Code",
|
|
198382
198603
|
windsurf: "Windsurf",
|
|
198383
198604
|
cursor: "Cursor",
|
|
198384
198605
|
copilot: "GitHub Copilot",
|
|
@@ -198397,6 +198618,7 @@ function getAgentLabel(agent) {
|
|
|
198397
198618
|
function getAgentHint(agent) {
|
|
198398
198619
|
const hints = {
|
|
198399
198620
|
claude: "settings + instructions",
|
|
198621
|
+
qwen: "settings.json hooks + QWEN.md guidance",
|
|
198400
198622
|
windsurf: "hooks + rules",
|
|
198401
198623
|
cursor: "hooks + rules",
|
|
198402
198624
|
copilot: "hooks + instructions",
|
|
@@ -201557,7 +201779,7 @@ async function getSessionContext(projectDir2, projectId, limit2 = 3, reader2) {
|
|
|
201557
201779
|
lines.push("## Key Project Memories");
|
|
201558
201780
|
lines.push("*Durable working context \u2014 explicit decisions, gotchas, and discoveries.*");
|
|
201559
201781
|
for (const obs of l2Obs) {
|
|
201560
|
-
const emoji3 =
|
|
201782
|
+
const emoji3 = OBSERVATION_ICONS[obs.type] ?? "[PIN]";
|
|
201561
201783
|
const fact = obs.facts?.[0] ? ` \u2014 ${redactCredentials(obs.facts[0])}` : "";
|
|
201562
201784
|
lines.push(`${emoji3} ${redactCredentials(obs.title)}${fact}`);
|
|
201563
201785
|
}
|
|
@@ -201605,11 +201827,12 @@ async function getActiveSession(projectDir2, projectId) {
|
|
|
201605
201827
|
const sessions = await loadAliasActiveSessions(aliasSet);
|
|
201606
201828
|
return sessions.sort((a4, b4) => new Date(b4.startedAt).getTime() - new Date(a4.startedAt).getTime())[0] ?? null;
|
|
201607
201829
|
}
|
|
201608
|
-
var PRIORITY_TYPES, RESUME_TYPES,
|
|
201830
|
+
var PRIORITY_TYPES, RESUME_TYPES, TYPE_WEIGHTS, NOISE_PATTERNS, COMMAND_TRACE_PATTERNS, SYSTEM_SELF_PATTERNS, SESSION_RESUME_OBSERVATION_LIMIT, SESSION_CONTEXT_OBSERVATION_LIMIT, AUTO_RESUME_SUMMARY_LIMIT, AUTO_RESUME_TITLE_LIMIT;
|
|
201609
201831
|
var init_session = __esm({
|
|
201610
201832
|
"src/memory/session.ts"() {
|
|
201611
201833
|
"use strict";
|
|
201612
201834
|
init_esm_shims();
|
|
201835
|
+
init_types2();
|
|
201613
201836
|
init_admission();
|
|
201614
201837
|
init_disclosure_policy();
|
|
201615
201838
|
init_aliases();
|
|
@@ -201637,18 +201860,6 @@ var init_session = __esm({
|
|
|
201637
201860
|
"what-changed",
|
|
201638
201861
|
"reasoning"
|
|
201639
201862
|
]);
|
|
201640
|
-
TYPE_EMOJI = {
|
|
201641
|
-
"gotcha": "[DISCOVERY]",
|
|
201642
|
-
"decision": "[WHY]",
|
|
201643
|
-
"problem-solution": "[FIX]",
|
|
201644
|
-
"trade-off": "[TRADEOFF]",
|
|
201645
|
-
"discovery": "[DISCOVERY]",
|
|
201646
|
-
"how-it-works": "[INFO]",
|
|
201647
|
-
"what-changed": "[CHANGE]",
|
|
201648
|
-
"why-it-exists": "[DECISION]",
|
|
201649
|
-
"session-request": "[SESSION]",
|
|
201650
|
-
"probe": "[PROBE]"
|
|
201651
|
-
};
|
|
201652
201863
|
TYPE_WEIGHTS = {
|
|
201653
201864
|
"gotcha": 6,
|
|
201654
201865
|
"decision": 5.5,
|
|
@@ -209197,7 +209408,7 @@ var init_tool_profile = __esm({
|
|
|
209197
209408
|
function getMcpServerInfo() {
|
|
209198
209409
|
return {
|
|
209199
209410
|
name: "memorix",
|
|
209200
|
-
version: true ? "1.9.
|
|
209411
|
+
version: true ? "1.9.11" : "1.0.1"
|
|
209201
209412
|
};
|
|
209202
209413
|
}
|
|
209203
209414
|
function createMcpDiscoverResult(capabilities, serverInfo) {
|
|
@@ -211650,6 +211861,9 @@ var init_protocol = __esm({
|
|
|
211650
211861
|
this.setRequestHandler(GetTaskPayloadRequestSchema, async (request, extra) => {
|
|
211651
211862
|
const handleTaskResult = async () => {
|
|
211652
211863
|
const taskId = request.params.taskId;
|
|
211864
|
+
if (!await this._taskStore.getTask(taskId, extra.sessionId)) {
|
|
211865
|
+
throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
|
|
211866
|
+
}
|
|
211653
211867
|
if (this._taskMessageQueue) {
|
|
211654
211868
|
let queuedMessage;
|
|
211655
211869
|
while (queuedMessage = await this._taskMessageQueue.dequeue(taskId, extra.sessionId)) {
|
|
@@ -211680,12 +211894,12 @@ var init_protocol = __esm({
|
|
|
211680
211894
|
throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
|
|
211681
211895
|
}
|
|
211682
211896
|
if (!isTerminal(task.status)) {
|
|
211683
|
-
await this._waitForTaskUpdate(taskId, extra.signal);
|
|
211897
|
+
await this._waitForTaskUpdate(taskId, extra.signal, extra.sessionId);
|
|
211684
211898
|
return await handleTaskResult();
|
|
211685
211899
|
}
|
|
211686
211900
|
if (isTerminal(task.status)) {
|
|
211687
211901
|
const result = await this._taskStore.getTaskResult(taskId, extra.sessionId);
|
|
211688
|
-
this._clearTaskQueue(taskId);
|
|
211902
|
+
this._clearTaskQueue(taskId, extra.sessionId);
|
|
211689
211903
|
return {
|
|
211690
211904
|
...result,
|
|
211691
211905
|
_meta: {
|
|
@@ -211722,7 +211936,7 @@ var init_protocol = __esm({
|
|
|
211722
211936
|
throw new McpError(ErrorCode.InvalidParams, `Cannot cancel task in terminal status: ${task.status}`);
|
|
211723
211937
|
}
|
|
211724
211938
|
await this._taskStore.updateTaskStatus(request.params.taskId, "cancelled", "Client cancelled task execution.", extra.sessionId);
|
|
211725
|
-
this._clearTaskQueue(request.params.taskId);
|
|
211939
|
+
this._clearTaskQueue(request.params.taskId, extra.sessionId);
|
|
211726
211940
|
const cancelledTask = await this._taskStore.getTask(request.params.taskId, extra.sessionId);
|
|
211727
211941
|
if (!cancelledTask) {
|
|
211728
211942
|
throw new McpError(ErrorCode.InvalidParams, `Task not found after cancellation: ${request.params.taskId}`);
|
|
@@ -211850,6 +212064,19 @@ var init_protocol = __esm({
|
|
|
211850
212064
|
const handler = this._requestHandlers.get(request.method) ?? this.fallbackRequestHandler;
|
|
211851
212065
|
const capturedTransport = this._transport;
|
|
211852
212066
|
const relatedTaskId = request.params?._meta?.[RELATED_TASK_META_KEY]?.taskId;
|
|
212067
|
+
const sessionId = capturedTransport?.sessionId;
|
|
212068
|
+
const store2 = this._taskStore;
|
|
212069
|
+
let relatedTaskFound = true;
|
|
212070
|
+
let relatedTaskLookup;
|
|
212071
|
+
if (relatedTaskId && store2 && this._taskMessageQueue && sessionId !== void 0) {
|
|
212072
|
+
relatedTaskFound = false;
|
|
212073
|
+
relatedTaskLookup = (async () => {
|
|
212074
|
+
if (!await store2.getTask(relatedTaskId, sessionId)) {
|
|
212075
|
+
throw new McpError(ErrorCode.InvalidParams, `Task not found: ${relatedTaskId}`);
|
|
212076
|
+
}
|
|
212077
|
+
relatedTaskFound = true;
|
|
212078
|
+
})();
|
|
212079
|
+
}
|
|
211853
212080
|
if (handler === void 0) {
|
|
211854
212081
|
const errorResponse = {
|
|
211855
212082
|
jsonrpc: "2.0",
|
|
@@ -211859,7 +212086,10 @@ var init_protocol = __esm({
|
|
|
211859
212086
|
message: "Method not found"
|
|
211860
212087
|
}
|
|
211861
212088
|
};
|
|
211862
|
-
if (relatedTaskId &&
|
|
212089
|
+
if (relatedTaskId && relatedTaskLookup) {
|
|
212090
|
+
const queuedError = { type: "error", message: errorResponse, timestamp: Date.now() };
|
|
212091
|
+
relatedTaskLookup.then(() => this._enqueueTaskMessage(relatedTaskId, queuedError, sessionId), () => capturedTransport?.send(errorResponse)).catch((error40) => this._onerror(new Error(`Failed to send an error response: ${error40}`)));
|
|
212092
|
+
} else if (relatedTaskId && this._taskMessageQueue) {
|
|
211863
212093
|
this._enqueueTaskMessage(relatedTaskId, {
|
|
211864
212094
|
type: "error",
|
|
211865
212095
|
message: errorResponse,
|
|
@@ -211910,7 +212140,10 @@ var init_protocol = __esm({
|
|
|
211910
212140
|
closeSSEStream: extra?.closeSSEStream,
|
|
211911
212141
|
closeStandaloneSSEStream: extra?.closeStandaloneSSEStream
|
|
211912
212142
|
};
|
|
211913
|
-
Promise.resolve().then(() => {
|
|
212143
|
+
(relatedTaskLookup ?? Promise.resolve()).then(() => {
|
|
212144
|
+
if (relatedTaskLookup && abortController.signal.aborted) {
|
|
212145
|
+
throw new McpError(ErrorCode.ConnectionClosed, "Request was cancelled");
|
|
212146
|
+
}
|
|
211914
212147
|
if (taskCreationParams) {
|
|
211915
212148
|
this.assertTaskHandlerCapability(request.method);
|
|
211916
212149
|
}
|
|
@@ -211945,7 +212178,7 @@ var init_protocol = __esm({
|
|
|
211945
212178
|
...error40["data"] !== void 0 && { data: error40["data"] }
|
|
211946
212179
|
}
|
|
211947
212180
|
};
|
|
211948
|
-
if (relatedTaskId && this._taskMessageQueue) {
|
|
212181
|
+
if (relatedTaskId && this._taskMessageQueue && relatedTaskFound) {
|
|
211949
212182
|
await this._enqueueTaskMessage(relatedTaskId, {
|
|
211950
212183
|
type: "error",
|
|
211951
212184
|
message: errorResponse,
|
|
@@ -212425,7 +212658,7 @@ var init_protocol = __esm({
|
|
|
212425
212658
|
throw new Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured");
|
|
212426
212659
|
}
|
|
212427
212660
|
const maxQueueSize = this._options?.maxTaskQueueSize;
|
|
212428
|
-
await this._taskMessageQueue.enqueue(taskId, message, sessionId, maxQueueSize);
|
|
212661
|
+
await this._taskMessageQueue.enqueue(taskId, message, sessionId ?? this._transport?.sessionId, maxQueueSize);
|
|
212429
212662
|
}
|
|
212430
212663
|
/**
|
|
212431
212664
|
* Clears the message queue for a task and rejects any pending request resolvers.
|
|
@@ -212454,12 +212687,13 @@ var init_protocol = __esm({
|
|
|
212454
212687
|
* Uses polling to check for updates at the task's configured poll interval.
|
|
212455
212688
|
* @param taskId The task ID to wait for
|
|
212456
212689
|
* @param signal Abort signal to cancel the wait
|
|
212690
|
+
* @param sessionId Session of the request that waits, passed to the task store
|
|
212457
212691
|
* @returns Promise that resolves when an update occurs or rejects if aborted
|
|
212458
212692
|
*/
|
|
212459
|
-
async _waitForTaskUpdate(taskId, signal) {
|
|
212693
|
+
async _waitForTaskUpdate(taskId, signal, sessionId) {
|
|
212460
212694
|
let interval = this._options?.defaultTaskPollInterval ?? 1e3;
|
|
212461
212695
|
try {
|
|
212462
|
-
const task = await this._taskStore?.getTask(taskId);
|
|
212696
|
+
const task = await this._taskStore?.getTask(taskId, sessionId);
|
|
212463
212697
|
if (task?.pollInterval) {
|
|
212464
212698
|
interval = task.pollInterval;
|
|
212465
212699
|
}
|
|
@@ -215644,9 +215878,28 @@ var require_utils = __commonJS({
|
|
|
215644
215878
|
init_esm_shims();
|
|
215645
215879
|
var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
|
|
215646
215880
|
var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
|
|
215881
|
+
var isPort = RegExp.prototype.test.bind(/^\d*$/u);
|
|
215647
215882
|
var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
|
|
215648
215883
|
var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
|
|
215649
|
-
var isPathCharacter = RegExp.prototype.test.bind(/^[
|
|
215884
|
+
var isPathCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/]$/u);
|
|
215885
|
+
var isQueryFragmentCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/?]$/u);
|
|
215886
|
+
var isUserinfoCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:]$/u);
|
|
215887
|
+
var BYTE_HEX = new Array(256);
|
|
215888
|
+
{
|
|
215889
|
+
const HEX_DIGITS = "0123456789ABCDEF";
|
|
215890
|
+
for (let i4 = 0; i4 < 256; i4++) {
|
|
215891
|
+
BYTE_HEX[i4] = "%" + HEX_DIGITS[i4 >> 4] + HEX_DIGITS[i4 & 15];
|
|
215892
|
+
}
|
|
215893
|
+
}
|
|
215894
|
+
function percentEncodeNonAscii(cp) {
|
|
215895
|
+
if (cp < 2048) {
|
|
215896
|
+
return BYTE_HEX[192 | cp >> 6] + BYTE_HEX[128 | cp & 63];
|
|
215897
|
+
}
|
|
215898
|
+
if (cp < 65536) {
|
|
215899
|
+
return BYTE_HEX[224 | cp >> 12] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
|
|
215900
|
+
}
|
|
215901
|
+
return BYTE_HEX[240 | cp >> 18] + BYTE_HEX[128 | cp >> 12 & 63] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
|
|
215902
|
+
}
|
|
215650
215903
|
function stringArrayToHexStripped(input) {
|
|
215651
215904
|
let acc = "";
|
|
215652
215905
|
let code = 0;
|
|
@@ -215671,91 +215924,105 @@ var require_utils = __commonJS({
|
|
|
215671
215924
|
}
|
|
215672
215925
|
return acc;
|
|
215673
215926
|
}
|
|
215927
|
+
var isHextet = RegExp.prototype.test.bind(/^[\dA-Fa-f]{1,4}$/);
|
|
215928
|
+
var isIPvFuture = RegExp.prototype.test.bind(/^[vV][\dA-Fa-f]+\.[A-Za-z\d\-._~!$&'()*+,;=:]+$/);
|
|
215929
|
+
var isZoneCharacter = RegExp.prototype.test.bind(/^[A-Za-z\d\-._~]$/);
|
|
215674
215930
|
var nonSimpleDomain = RegExp.prototype.test.bind(/[^!"$&'()*+,\-.;=_`a-z{}~]/u);
|
|
215675
|
-
function
|
|
215676
|
-
|
|
215677
|
-
|
|
215678
|
-
|
|
215679
|
-
|
|
215680
|
-
|
|
215681
|
-
|
|
215682
|
-
if (hex !== "") {
|
|
215683
|
-
address.push(hex);
|
|
215684
|
-
} else {
|
|
215685
|
-
output.error = true;
|
|
215686
|
-
return false;
|
|
215931
|
+
function isZoneIdentifier(zone) {
|
|
215932
|
+
if (zone.length === 0) return false;
|
|
215933
|
+
for (let i4 = 0; i4 < zone.length; i4++) {
|
|
215934
|
+
if (isZoneCharacter(zone[i4])) continue;
|
|
215935
|
+
if (zone[i4] === "%" && i4 + 2 < zone.length && isHexPair(zone.slice(i4 + 1, i4 + 3))) {
|
|
215936
|
+
i4 += 2;
|
|
215937
|
+
continue;
|
|
215687
215938
|
}
|
|
215688
|
-
|
|
215939
|
+
return false;
|
|
215689
215940
|
}
|
|
215690
215941
|
return true;
|
|
215691
215942
|
}
|
|
215692
|
-
function
|
|
215693
|
-
let
|
|
215694
|
-
|
|
215695
|
-
|
|
215696
|
-
|
|
215697
|
-
let
|
|
215698
|
-
|
|
215699
|
-
|
|
215700
|
-
|
|
215701
|
-
|
|
215702
|
-
|
|
215703
|
-
|
|
215704
|
-
}
|
|
215705
|
-
if (cursor === ":") {
|
|
215706
|
-
if (endipv6Encountered === true) {
|
|
215707
|
-
endIpv6 = true;
|
|
215943
|
+
function compressIPv6ZeroRun(hextets) {
|
|
215944
|
+
let bestStart = -1;
|
|
215945
|
+
let bestLength = 0;
|
|
215946
|
+
let runStart = -1;
|
|
215947
|
+
let runLength = 0;
|
|
215948
|
+
for (let i4 = 0; i4 < hextets.length; i4++) {
|
|
215949
|
+
if (hextets[i4] === "0") {
|
|
215950
|
+
if (runStart === -1) runStart = i4;
|
|
215951
|
+
runLength++;
|
|
215952
|
+
if (runLength > bestLength) {
|
|
215953
|
+
bestLength = runLength;
|
|
215954
|
+
bestStart = runStart;
|
|
215708
215955
|
}
|
|
215709
|
-
if (!consume(buffer, address, output)) {
|
|
215710
|
-
break;
|
|
215711
|
-
}
|
|
215712
|
-
if (++tokenCount > 7) {
|
|
215713
|
-
output.error = true;
|
|
215714
|
-
break;
|
|
215715
|
-
}
|
|
215716
|
-
if (i4 > 0 && input[i4 - 1] === ":") {
|
|
215717
|
-
endipv6Encountered = true;
|
|
215718
|
-
}
|
|
215719
|
-
address.push(":");
|
|
215720
|
-
continue;
|
|
215721
|
-
} else if (cursor === "%") {
|
|
215722
|
-
if (!consume(buffer, address, output)) {
|
|
215723
|
-
break;
|
|
215724
|
-
}
|
|
215725
|
-
consume = consumeIsZone;
|
|
215726
215956
|
} else {
|
|
215727
|
-
|
|
215957
|
+
runStart = -1;
|
|
215958
|
+
runLength = 0;
|
|
215959
|
+
}
|
|
215960
|
+
}
|
|
215961
|
+
if (bestLength < 2) return hextets.join(":");
|
|
215962
|
+
const head = hextets.slice(0, bestStart).join(":");
|
|
215963
|
+
const tail = hextets.slice(bestStart + bestLength).join(":");
|
|
215964
|
+
return head + "::" + tail;
|
|
215965
|
+
}
|
|
215966
|
+
function normalizeIPv6Address(input) {
|
|
215967
|
+
const compression = input.indexOf("::");
|
|
215968
|
+
if (compression !== -1 && input.indexOf("::", compression + 1) !== -1) return void 0;
|
|
215969
|
+
const left = compression === -1 ? input.split(":") : input.slice(0, compression).split(":");
|
|
215970
|
+
const right = compression === -1 ? [] : input.slice(compression + 2).split(":");
|
|
215971
|
+
if (compression !== -1) {
|
|
215972
|
+
if (left.length === 1 && left[0] === "") left.length = 0;
|
|
215973
|
+
if (right.length === 1 && right[0] === "") right.length = 0;
|
|
215974
|
+
}
|
|
215975
|
+
const parts = left.concat(right);
|
|
215976
|
+
let hextetCount = 0;
|
|
215977
|
+
for (let i4 = 0; i4 < parts.length; i4++) {
|
|
215978
|
+
const part = parts[i4];
|
|
215979
|
+
if (part === "") return void 0;
|
|
215980
|
+
if (part.indexOf(".") !== -1) {
|
|
215981
|
+
if (i4 !== parts.length - 1 || compression !== -1 && right.length === 0 || !isIPv4(part)) return void 0;
|
|
215982
|
+
hextetCount += 2;
|
|
215728
215983
|
continue;
|
|
215729
215984
|
}
|
|
215985
|
+
if (!isHextet(part)) return void 0;
|
|
215986
|
+
parts[i4] = parseInt(part, 16).toString(16);
|
|
215987
|
+
hextetCount++;
|
|
215730
215988
|
}
|
|
215731
|
-
if (
|
|
215732
|
-
if (
|
|
215733
|
-
|
|
215734
|
-
} else if (endIpv6) {
|
|
215735
|
-
address.push(buffer.join(""));
|
|
215736
|
-
} else {
|
|
215737
|
-
address.push(stringArrayToHexStripped(buffer));
|
|
215738
|
-
}
|
|
215989
|
+
if (compression === -1) {
|
|
215990
|
+
if (hextetCount !== 8) return void 0;
|
|
215991
|
+
return compressIPv6ZeroRun(parts);
|
|
215739
215992
|
}
|
|
215740
|
-
|
|
215741
|
-
|
|
215993
|
+
if (hextetCount >= 8) return void 0;
|
|
215994
|
+
const expanded = parts.slice(0, left.length);
|
|
215995
|
+
for (let i4 = hextetCount; i4 < 8; i4++) expanded.push("0");
|
|
215996
|
+
for (let i4 = left.length; i4 < parts.length; i4++) expanded.push(parts[i4]);
|
|
215997
|
+
return compressIPv6ZeroRun(expanded);
|
|
215742
215998
|
}
|
|
215743
215999
|
function normalizeIPv6(host) {
|
|
215744
|
-
|
|
215745
|
-
|
|
215746
|
-
}
|
|
215747
|
-
|
|
215748
|
-
if (
|
|
215749
|
-
|
|
215750
|
-
|
|
215751
|
-
|
|
215752
|
-
|
|
215753
|
-
|
|
215754
|
-
|
|
215755
|
-
|
|
215756
|
-
|
|
215757
|
-
|
|
215758
|
-
|
|
216000
|
+
const bracketed = host[0] === "[" && host[host.length - 1] === "]";
|
|
216001
|
+
const hasBracket = host[0] === "[" || host[host.length - 1] === "]";
|
|
216002
|
+
if (hasBracket && !bracketed) return { host, isIPV6: false, error: true };
|
|
216003
|
+
let input = bracketed ? host.slice(1, -1) : host;
|
|
216004
|
+
if (bracketed && isIPvFuture(input)) {
|
|
216005
|
+
input = input.toLowerCase();
|
|
216006
|
+
return { host: `[${input}]`, escapedHost: input, isIPV6: false, isIPVFuture: true };
|
|
216007
|
+
}
|
|
216008
|
+
if (findToken(input, ":") < 2) {
|
|
216009
|
+
return { host, isIPV6: false, error: bracketed };
|
|
216010
|
+
}
|
|
216011
|
+
let zoneIdentifier = "";
|
|
216012
|
+
const zoneSeparator = input.indexOf("%");
|
|
216013
|
+
if (zoneSeparator !== -1) {
|
|
216014
|
+
const separatorLength = input.slice(zoneSeparator, zoneSeparator + 3).toLowerCase() === "%25" ? 3 : 1;
|
|
216015
|
+
zoneIdentifier = input.slice(zoneSeparator + separatorLength);
|
|
216016
|
+
if (!isZoneIdentifier(zoneIdentifier)) return { host, isIPV6: false, error: true };
|
|
216017
|
+
input = input.slice(0, zoneSeparator);
|
|
216018
|
+
}
|
|
216019
|
+
const address = normalizeIPv6Address(input);
|
|
216020
|
+
if (address === void 0) return { host, isIPV6: false, error: true };
|
|
216021
|
+
return {
|
|
216022
|
+
host: address + (zoneIdentifier ? "%" + zoneIdentifier : ""),
|
|
216023
|
+
escapedHost: address + (zoneIdentifier ? "%25" + zoneIdentifier : ""),
|
|
216024
|
+
isIPV6: true
|
|
216025
|
+
};
|
|
215759
216026
|
}
|
|
215760
216027
|
function findToken(str2, token) {
|
|
215761
216028
|
let ind = 0;
|
|
@@ -215874,7 +216141,8 @@ var require_utils = __commonJS({
|
|
|
215874
216141
|
function normalizePathEncoding(input) {
|
|
215875
216142
|
let output = "";
|
|
215876
216143
|
for (let i4 = 0; i4 < input.length; i4++) {
|
|
215877
|
-
|
|
216144
|
+
const ch2 = input[i4];
|
|
216145
|
+
if (ch2 === "%" && i4 + 2 < input.length) {
|
|
215878
216146
|
const hex = input.slice(i4 + 1, i4 + 3);
|
|
215879
216147
|
if (isHexPair(hex)) {
|
|
215880
216148
|
const normalizedHex = hex.toUpperCase();
|
|
@@ -215888,10 +216156,152 @@ var require_utils = __commonJS({
|
|
|
215888
216156
|
continue;
|
|
215889
216157
|
}
|
|
215890
216158
|
}
|
|
215891
|
-
if (isPathCharacter(
|
|
215892
|
-
output +=
|
|
216159
|
+
if (isPathCharacter(ch2)) {
|
|
216160
|
+
output += ch2;
|
|
216161
|
+
} else {
|
|
216162
|
+
const code = input.charCodeAt(i4);
|
|
216163
|
+
if (code < 128) {
|
|
216164
|
+
output += isEscapeSafe(code) ? ch2 : BYTE_HEX[code];
|
|
216165
|
+
} else if (code < 55296 || code > 57343) {
|
|
216166
|
+
output += percentEncodeNonAscii(code);
|
|
216167
|
+
} else if (code <= 56319 && i4 + 1 < input.length) {
|
|
216168
|
+
const low = input.charCodeAt(i4 + 1);
|
|
216169
|
+
if (low >= 56320 && low <= 57343) {
|
|
216170
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
216171
|
+
i4++;
|
|
216172
|
+
} else {
|
|
216173
|
+
output += percentEncodeNonAscii(65533);
|
|
216174
|
+
}
|
|
216175
|
+
} else {
|
|
216176
|
+
output += percentEncodeNonAscii(65533);
|
|
216177
|
+
}
|
|
216178
|
+
}
|
|
216179
|
+
}
|
|
216180
|
+
return output;
|
|
216181
|
+
}
|
|
216182
|
+
function serializePathEncoding(input, pathNoScheme = false) {
|
|
216183
|
+
let output = "";
|
|
216184
|
+
let firstSegment = pathNoScheme && input[0] !== "/";
|
|
216185
|
+
for (let i4 = 0; i4 < input.length; i4++) {
|
|
216186
|
+
const ch2 = input[i4];
|
|
216187
|
+
if (ch2 === "%" && i4 + 2 < input.length) {
|
|
216188
|
+
const hex = input.slice(i4 + 1, i4 + 3);
|
|
216189
|
+
if (isHexPair(hex)) {
|
|
216190
|
+
output += "%" + hex.toUpperCase();
|
|
216191
|
+
i4 += 2;
|
|
216192
|
+
continue;
|
|
216193
|
+
}
|
|
216194
|
+
}
|
|
216195
|
+
if (ch2 === "/") {
|
|
216196
|
+
firstSegment = false;
|
|
216197
|
+
}
|
|
216198
|
+
if (isPathCharacter(ch2) && (ch2 !== ":" || !firstSegment)) {
|
|
216199
|
+
output += ch2;
|
|
216200
|
+
} else {
|
|
216201
|
+
const code = input.charCodeAt(i4);
|
|
216202
|
+
if (code < 128) {
|
|
216203
|
+
output += BYTE_HEX[code];
|
|
216204
|
+
} else if (code < 55296 || code > 57343) {
|
|
216205
|
+
output += percentEncodeNonAscii(code);
|
|
216206
|
+
} else if (code <= 56319 && i4 + 1 < input.length) {
|
|
216207
|
+
const low = input.charCodeAt(i4 + 1);
|
|
216208
|
+
if (low >= 56320 && low <= 57343) {
|
|
216209
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
216210
|
+
i4++;
|
|
216211
|
+
} else {
|
|
216212
|
+
output += percentEncodeNonAscii(65533);
|
|
216213
|
+
}
|
|
216214
|
+
} else {
|
|
216215
|
+
output += percentEncodeNonAscii(65533);
|
|
216216
|
+
}
|
|
216217
|
+
}
|
|
216218
|
+
}
|
|
216219
|
+
return output;
|
|
216220
|
+
}
|
|
216221
|
+
function encodeComponent(input, isAllowed) {
|
|
216222
|
+
let output = "";
|
|
216223
|
+
for (let i4 = 0; i4 < input.length; i4++) {
|
|
216224
|
+
const ch2 = input[i4];
|
|
216225
|
+
if (ch2 === "%" && i4 + 2 < input.length) {
|
|
216226
|
+
const hex = input.slice(i4 + 1, i4 + 3);
|
|
216227
|
+
if (isHexPair(hex)) {
|
|
216228
|
+
output += "%" + hex.toUpperCase();
|
|
216229
|
+
i4 += 2;
|
|
216230
|
+
continue;
|
|
216231
|
+
}
|
|
216232
|
+
}
|
|
216233
|
+
if (isAllowed(ch2)) {
|
|
216234
|
+
output += ch2;
|
|
216235
|
+
} else {
|
|
216236
|
+
const code = input.charCodeAt(i4);
|
|
216237
|
+
if (code < 128) {
|
|
216238
|
+
output += BYTE_HEX[code];
|
|
216239
|
+
} else if (code < 55296 || code > 57343) {
|
|
216240
|
+
output += percentEncodeNonAscii(code);
|
|
216241
|
+
} else if (code <= 56319 && i4 + 1 < input.length) {
|
|
216242
|
+
const low = input.charCodeAt(i4 + 1);
|
|
216243
|
+
if (low >= 56320 && low <= 57343) {
|
|
216244
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
216245
|
+
i4++;
|
|
216246
|
+
} else {
|
|
216247
|
+
output += percentEncodeNonAscii(65533);
|
|
216248
|
+
}
|
|
216249
|
+
} else {
|
|
216250
|
+
output += percentEncodeNonAscii(65533);
|
|
216251
|
+
}
|
|
216252
|
+
}
|
|
216253
|
+
}
|
|
216254
|
+
return output;
|
|
216255
|
+
}
|
|
216256
|
+
function encodeUserinfo(input) {
|
|
216257
|
+
return encodeComponent(input, isUserinfoCharacter);
|
|
216258
|
+
}
|
|
216259
|
+
function encodeQuery(input) {
|
|
216260
|
+
return encodeComponent(input, isQueryFragmentCharacter);
|
|
216261
|
+
}
|
|
216262
|
+
function encodeFragment(input) {
|
|
216263
|
+
return encodeComponent(input, isQueryFragmentCharacter);
|
|
216264
|
+
}
|
|
216265
|
+
function isEscapeSafe(cp) {
|
|
216266
|
+
return cp >= 48 && cp <= 57 || cp >= 65 && cp <= 90 || cp >= 97 && cp <= 122 || cp === 42 || cp === 43 || cp === 45 || cp === 46 || cp === 47 || cp === 64 || cp === 95;
|
|
216267
|
+
}
|
|
216268
|
+
function normalizeQueryFragmentEncoding(input) {
|
|
216269
|
+
let output = "";
|
|
216270
|
+
for (let i4 = 0; i4 < input.length; i4++) {
|
|
216271
|
+
const ch2 = input[i4];
|
|
216272
|
+
if (ch2 === "%" && i4 + 2 < input.length) {
|
|
216273
|
+
const hex = input.slice(i4 + 1, i4 + 3);
|
|
216274
|
+
if (isHexPair(hex)) {
|
|
216275
|
+
const normalizedHex = hex.toUpperCase();
|
|
216276
|
+
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
|
|
216277
|
+
if (isUnreserved(decoded)) {
|
|
216278
|
+
output += decoded;
|
|
216279
|
+
} else {
|
|
216280
|
+
output += "%" + normalizedHex;
|
|
216281
|
+
}
|
|
216282
|
+
i4 += 2;
|
|
216283
|
+
continue;
|
|
216284
|
+
}
|
|
216285
|
+
}
|
|
216286
|
+
if (isQueryFragmentCharacter(ch2)) {
|
|
216287
|
+
output += ch2;
|
|
215893
216288
|
} else {
|
|
215894
|
-
|
|
216289
|
+
const code = input.charCodeAt(i4);
|
|
216290
|
+
if (code < 128) {
|
|
216291
|
+
output += isEscapeSafe(code) ? ch2 : BYTE_HEX[code];
|
|
216292
|
+
} else if (code < 55296 || code > 57343) {
|
|
216293
|
+
output += percentEncodeNonAscii(code);
|
|
216294
|
+
} else if (code <= 56319 && i4 + 1 < input.length) {
|
|
216295
|
+
const low = input.charCodeAt(i4 + 1);
|
|
216296
|
+
if (low >= 56320 && low <= 57343) {
|
|
216297
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
216298
|
+
i4++;
|
|
216299
|
+
} else {
|
|
216300
|
+
output += percentEncodeNonAscii(65533);
|
|
216301
|
+
}
|
|
216302
|
+
} else {
|
|
216303
|
+
output += percentEncodeNonAscii(65533);
|
|
216304
|
+
}
|
|
215895
216305
|
}
|
|
215896
216306
|
}
|
|
215897
216307
|
return output;
|
|
@@ -215914,14 +216324,18 @@ var require_utils = __commonJS({
|
|
|
215914
216324
|
function recomposeAuthority(component) {
|
|
215915
216325
|
const uriTokens = [];
|
|
215916
216326
|
if (component.userinfo !== void 0) {
|
|
215917
|
-
uriTokens.push(component.userinfo);
|
|
216327
|
+
uriTokens.push(encodeUserinfo(component.userinfo));
|
|
215918
216328
|
uriTokens.push("@");
|
|
215919
216329
|
}
|
|
215920
216330
|
if (component.host !== void 0) {
|
|
215921
|
-
let host =
|
|
216331
|
+
let host = component.host;
|
|
215922
216332
|
if (!isIPv4(host)) {
|
|
215923
|
-
|
|
215924
|
-
if (ipV6res.isIPV6
|
|
216333
|
+
let ipV6res = normalizeIPv6(host);
|
|
216334
|
+
if (ipV6res.isIPV6 !== true && ipV6res.isIPVFuture !== true) {
|
|
216335
|
+
host = normalizePercentEncoding(host, true);
|
|
216336
|
+
ipV6res = normalizeIPv6(host);
|
|
216337
|
+
}
|
|
216338
|
+
if (ipV6res.isIPV6 === true || ipV6res.isIPVFuture === true) {
|
|
215925
216339
|
host = `[${ipV6res.escapedHost}]`;
|
|
215926
216340
|
} else {
|
|
215927
216341
|
host = reescapeHostDelimiters(host, false);
|
|
@@ -215930,8 +216344,12 @@ var require_utils = __commonJS({
|
|
|
215930
216344
|
uriTokens.push(host);
|
|
215931
216345
|
}
|
|
215932
216346
|
if (typeof component.port === "number" || typeof component.port === "string") {
|
|
216347
|
+
const port = String(component.port);
|
|
216348
|
+
if (!isPort(port)) {
|
|
216349
|
+
throw new TypeError("URI port is malformed.");
|
|
216350
|
+
}
|
|
215933
216351
|
uriTokens.push(":");
|
|
215934
|
-
uriTokens.push(
|
|
216352
|
+
uriTokens.push(port);
|
|
215935
216353
|
}
|
|
215936
216354
|
return uriTokens.length ? uriTokens.join("") : void 0;
|
|
215937
216355
|
}
|
|
@@ -215941,6 +216359,11 @@ var require_utils = __commonJS({
|
|
|
215941
216359
|
reescapeHostDelimiters,
|
|
215942
216360
|
normalizePercentEncoding,
|
|
215943
216361
|
normalizePathEncoding,
|
|
216362
|
+
serializePathEncoding,
|
|
216363
|
+
normalizeQueryFragmentEncoding,
|
|
216364
|
+
encodeUserinfo,
|
|
216365
|
+
encodeQuery,
|
|
216366
|
+
encodeFragment,
|
|
215944
216367
|
escapePreservingEscapes,
|
|
215945
216368
|
removeDotSegments,
|
|
215946
216369
|
isIPv4,
|
|
@@ -215957,7 +216380,7 @@ var require_schemes = __commonJS({
|
|
|
215957
216380
|
"use strict";
|
|
215958
216381
|
init_esm_shims();
|
|
215959
216382
|
var { isUUID } = require_utils();
|
|
215960
|
-
var URN_REG =
|
|
216383
|
+
var URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
|
|
215961
216384
|
var supportedSchemeNames = (
|
|
215962
216385
|
/** @type {const} */
|
|
215963
216386
|
[
|
|
@@ -216018,9 +216441,10 @@ var require_schemes = __commonJS({
|
|
|
216018
216441
|
wsComponent.secure = void 0;
|
|
216019
216442
|
}
|
|
216020
216443
|
if (wsComponent.resourceName) {
|
|
216021
|
-
const
|
|
216444
|
+
const queryIndex = wsComponent.resourceName.indexOf("?");
|
|
216445
|
+
const path50 = queryIndex === -1 ? wsComponent.resourceName : wsComponent.resourceName.slice(0, queryIndex);
|
|
216022
216446
|
wsComponent.path = path50 && path50 !== "/" ? path50 : void 0;
|
|
216023
|
-
wsComponent.query =
|
|
216447
|
+
wsComponent.query = queryIndex === -1 ? void 0 : wsComponent.resourceName.slice(queryIndex + 1);
|
|
216024
216448
|
wsComponent.resourceName = void 0;
|
|
216025
216449
|
}
|
|
216026
216450
|
wsComponent.fragment = void 0;
|
|
@@ -216032,7 +216456,7 @@ var require_schemes = __commonJS({
|
|
|
216032
216456
|
return urnComponent;
|
|
216033
216457
|
}
|
|
216034
216458
|
const matches = urnComponent.path.match(URN_REG);
|
|
216035
|
-
if (matches) {
|
|
216459
|
+
if (matches && matches[0] === urnComponent.path) {
|
|
216036
216460
|
const scheme = options.scheme || urnComponent.scheme || "urn";
|
|
216037
216461
|
urnComponent.nid = matches[1].toLowerCase();
|
|
216038
216462
|
urnComponent.nss = matches[2];
|
|
@@ -216167,8 +216591,17 @@ var require_fast_uri = __commonJS({
|
|
|
216167
216591
|
"node_modules/fast-uri/index.js"(exports, module) {
|
|
216168
216592
|
"use strict";
|
|
216169
216593
|
init_esm_shims();
|
|
216170
|
-
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding,
|
|
216594
|
+
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
|
|
216171
216595
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
216596
|
+
var VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
|
|
216597
|
+
var MALFORMED_SCHEME_ERROR = "URI scheme is malformed.";
|
|
216598
|
+
function decodeValidScheme(scheme) {
|
|
216599
|
+
const decodedScheme = unescape(String(scheme));
|
|
216600
|
+
if (!VALID_SCHEME.test(decodedScheme)) {
|
|
216601
|
+
throw new TypeError(MALFORMED_SCHEME_ERROR);
|
|
216602
|
+
}
|
|
216603
|
+
return decodedScheme;
|
|
216604
|
+
}
|
|
216172
216605
|
function normalize(uri, options) {
|
|
216173
216606
|
if (typeof uri === "string") {
|
|
216174
216607
|
uri = /** @type {T} */
|
|
@@ -216181,12 +216614,34 @@ var require_fast_uri = __commonJS({
|
|
|
216181
216614
|
}
|
|
216182
216615
|
function resolve9(baseURI, relativeURI, options) {
|
|
216183
216616
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
216184
|
-
const {
|
|
216185
|
-
|
|
216186
|
-
|
|
216617
|
+
const {
|
|
216618
|
+
parsed: baseParsed,
|
|
216619
|
+
malformedAuthorityOrPort: baseMalformed,
|
|
216620
|
+
malformedPercentEncoding: baseMalformedPercentEncoding,
|
|
216621
|
+
malformedSchemeSpecific: baseMalformedSchemeSpecific,
|
|
216622
|
+
malformedHost: baseMalformedHost,
|
|
216623
|
+
malformedScheme: baseMalformedScheme
|
|
216624
|
+
} = parseWithStatus(baseURI, schemelessOptions);
|
|
216625
|
+
const {
|
|
216626
|
+
parsed: relativeParsed,
|
|
216627
|
+
malformedAuthorityOrPort: relativeMalformed,
|
|
216628
|
+
malformedPercentEncoding: relativeMalformedPercentEncoding,
|
|
216629
|
+
malformedSchemeSpecific: relativeMalformedSchemeSpecific,
|
|
216630
|
+
malformedHost: relativeMalformedHost,
|
|
216631
|
+
malformedScheme: relativeMalformedScheme
|
|
216632
|
+
} = parseWithStatus(relativeURI, schemelessOptions);
|
|
216633
|
+
if (baseMalformed || relativeMalformed || baseMalformedPercentEncoding || relativeMalformedPercentEncoding || baseMalformedSchemeSpecific || relativeMalformedSchemeSpecific || baseMalformedHost || relativeMalformedHost || baseMalformedScheme || relativeMalformedScheme) {
|
|
216187
216634
|
throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
|
|
216188
216635
|
}
|
|
216189
216636
|
const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
|
|
216637
|
+
const resolvedSchemeHandler = getSchemeHandler(options && options.scheme || resolved.scheme);
|
|
216638
|
+
const resolvedHost = resolved.host;
|
|
216639
|
+
const resolvedHostIsIP = resolvedHost !== void 0 && resolvedHost !== "" && (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6);
|
|
216640
|
+
canonicalizeHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP);
|
|
216641
|
+
const encodedASCIIHost = resolvedHost && resolvedHost.indexOf("%") !== -1 && !new RegExp("\\P{ASCII}", "u").test(resolvedHost);
|
|
216642
|
+
if (resolved.error && !encodedASCIIHost) {
|
|
216643
|
+
throw new Error(resolved.error);
|
|
216644
|
+
}
|
|
216190
216645
|
schemelessOptions.skipEscape = true;
|
|
216191
216646
|
return serialize(resolved, schemelessOptions);
|
|
216192
216647
|
}
|
|
@@ -216246,7 +216701,7 @@ var require_fast_uri = __commonJS({
|
|
|
216246
216701
|
function equal(uriA, uriB, options) {
|
|
216247
216702
|
const normalizedA = normalizeComparableURI(uriA, options);
|
|
216248
216703
|
const normalizedB = normalizeComparableURI(uriB, options);
|
|
216249
|
-
return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA
|
|
216704
|
+
return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA === normalizedB;
|
|
216250
216705
|
}
|
|
216251
216706
|
function serialize(cmpts, opts) {
|
|
216252
216707
|
const component = {
|
|
@@ -216267,19 +216722,22 @@ var require_fast_uri = __commonJS({
|
|
|
216267
216722
|
};
|
|
216268
216723
|
const options = Object.assign({}, opts);
|
|
216269
216724
|
const uriTokens = [];
|
|
216725
|
+
if (component.scheme) {
|
|
216726
|
+
component.scheme = decodeValidScheme(component.scheme);
|
|
216727
|
+
}
|
|
216270
216728
|
const schemeHandler = getSchemeHandler(options.scheme || component.scheme);
|
|
216271
216729
|
if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
|
|
216730
|
+
const hasAuthority = component.userinfo !== void 0 || component.host !== void 0 || component.port !== void 0;
|
|
216731
|
+
const pathNoScheme = !options.skipEscape && component.scheme === void 0 && !hasAuthority;
|
|
216272
216732
|
if (component.path !== void 0) {
|
|
216273
216733
|
if (!options.skipEscape) {
|
|
216274
|
-
component.path =
|
|
216275
|
-
if (component.scheme !== void 0) {
|
|
216276
|
-
component.path = component.path.split("%3A").join(":");
|
|
216277
|
-
}
|
|
216734
|
+
component.path = serializePathEncoding(component.path, pathNoScheme);
|
|
216278
216735
|
} else {
|
|
216279
216736
|
component.path = normalizePercentEncoding(component.path);
|
|
216280
216737
|
}
|
|
216281
216738
|
}
|
|
216282
216739
|
if (options.reference !== "suffix" && component.scheme) {
|
|
216740
|
+
component.scheme = decodeValidScheme(component.scheme);
|
|
216283
216741
|
uriTokens.push(component.scheme, ":");
|
|
216284
216742
|
}
|
|
216285
216743
|
const authority = recomposeAuthority(component);
|
|
@@ -216297,16 +216755,19 @@ var require_fast_uri = __commonJS({
|
|
|
216297
216755
|
if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
|
|
216298
216756
|
s4 = removeDotSegments(s4);
|
|
216299
216757
|
}
|
|
216758
|
+
if (pathNoScheme) {
|
|
216759
|
+
s4 = serializePathEncoding(s4, true);
|
|
216760
|
+
}
|
|
216300
216761
|
if (authority === void 0 && s4[0] === "/" && s4[1] === "/") {
|
|
216301
216762
|
s4 = "/%2F" + s4.slice(2);
|
|
216302
216763
|
}
|
|
216303
216764
|
uriTokens.push(s4);
|
|
216304
216765
|
}
|
|
216305
216766
|
if (component.query !== void 0) {
|
|
216306
|
-
uriTokens.push("?", component.query);
|
|
216767
|
+
uriTokens.push("?", encodeQuery(component.query));
|
|
216307
216768
|
}
|
|
216308
216769
|
if (component.fragment !== void 0) {
|
|
216309
|
-
uriTokens.push("#", component.fragment);
|
|
216770
|
+
uriTokens.push("#", encodeFragment(component.fragment));
|
|
216310
216771
|
}
|
|
216311
216772
|
return uriTokens.join("");
|
|
216312
216773
|
}
|
|
@@ -216322,6 +216783,35 @@ var require_fast_uri = __commonJS({
|
|
|
216322
216783
|
}
|
|
216323
216784
|
return void 0;
|
|
216324
216785
|
}
|
|
216786
|
+
function hasMalformedPercentEncoding(component) {
|
|
216787
|
+
if (component === void 0) return false;
|
|
216788
|
+
let percent = component.indexOf("%");
|
|
216789
|
+
while (percent !== -1) {
|
|
216790
|
+
if (percent + 2 >= component.length || !/^[\da-f]{2}$/iu.test(component.slice(percent + 1, percent + 3))) {
|
|
216791
|
+
return true;
|
|
216792
|
+
}
|
|
216793
|
+
percent = component.indexOf("%", percent + 3);
|
|
216794
|
+
}
|
|
216795
|
+
return false;
|
|
216796
|
+
}
|
|
216797
|
+
function isIPLiteral(host) {
|
|
216798
|
+
return host[0] === "[" && host[host.length - 1] === "]";
|
|
216799
|
+
}
|
|
216800
|
+
function hasMalformedComponentPercentEncoding(matches) {
|
|
216801
|
+
const host = matches[4];
|
|
216802
|
+
return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !isIPLiteral(host) && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
|
|
216803
|
+
}
|
|
216804
|
+
function canonicalizeHost(parsed, options, schemeHandler, isIP5) {
|
|
216805
|
+
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP5 === false && nonSimpleDomain(parsed.host)) {
|
|
216806
|
+
try {
|
|
216807
|
+
parsed.host = new URL("http://" + parsed.host).hostname;
|
|
216808
|
+
} catch (e5) {
|
|
216809
|
+
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e5;
|
|
216810
|
+
return true;
|
|
216811
|
+
}
|
|
216812
|
+
}
|
|
216813
|
+
return false;
|
|
216814
|
+
}
|
|
216325
216815
|
function parseWithStatus(uri, opts) {
|
|
216326
216816
|
const options = Object.assign({}, opts);
|
|
216327
216817
|
const parsed = {
|
|
@@ -216334,6 +216824,11 @@ var require_fast_uri = __commonJS({
|
|
|
216334
216824
|
fragment: void 0
|
|
216335
216825
|
};
|
|
216336
216826
|
let malformedAuthorityOrPort = false;
|
|
216827
|
+
let malformedPercentEncoding = false;
|
|
216828
|
+
let malformedSchemeSpecific = false;
|
|
216829
|
+
let malformedHost = false;
|
|
216830
|
+
let malformedIPLiteral = false;
|
|
216831
|
+
let malformedScheme = false;
|
|
216337
216832
|
let isIP5 = false;
|
|
216338
216833
|
if (options.reference === "suffix") {
|
|
216339
216834
|
if (options.scheme) {
|
|
@@ -216370,6 +216865,19 @@ var require_fast_uri = __commonJS({
|
|
|
216370
216865
|
parsed.path = matches[6] || "";
|
|
216371
216866
|
parsed.query = matches[7];
|
|
216372
216867
|
parsed.fragment = matches[8];
|
|
216868
|
+
if (parsed.scheme !== void 0) {
|
|
216869
|
+
const decodedScheme = unescape(parsed.scheme);
|
|
216870
|
+
if (VALID_SCHEME.test(decodedScheme)) {
|
|
216871
|
+
parsed.scheme = decodedScheme.toLowerCase();
|
|
216872
|
+
} else {
|
|
216873
|
+
parsed.error = parsed.error || MALFORMED_SCHEME_ERROR;
|
|
216874
|
+
malformedScheme = true;
|
|
216875
|
+
}
|
|
216876
|
+
}
|
|
216877
|
+
malformedPercentEncoding = hasMalformedComponentPercentEncoding(matches);
|
|
216878
|
+
if (malformedPercentEncoding) {
|
|
216879
|
+
parsed.error = parsed.error || "URI contains malformed percent-encoding.";
|
|
216880
|
+
}
|
|
216373
216881
|
if (isNaN(parsed.port)) {
|
|
216374
216882
|
parsed.port = matches[5];
|
|
216375
216883
|
}
|
|
@@ -216381,9 +216889,16 @@ var require_fast_uri = __commonJS({
|
|
|
216381
216889
|
if (parsed.host) {
|
|
216382
216890
|
const ipv4result = isIPv4(parsed.host);
|
|
216383
216891
|
if (ipv4result === false) {
|
|
216892
|
+
const bracketedIPLiteral = isIPLiteral(parsed.host);
|
|
216893
|
+
const hasIPLiteralBracket = parsed.host.indexOf("[") !== -1 || parsed.host.indexOf("]") !== -1;
|
|
216384
216894
|
const ipv6result = normalizeIPv6(parsed.host);
|
|
216385
|
-
|
|
216386
|
-
|
|
216895
|
+
isIP5 = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
|
|
216896
|
+
malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
|
|
216897
|
+
parsed.host = isIP5 ? ipv6result.host : ipv6result.host.toLowerCase();
|
|
216898
|
+
if (malformedIPLiteral) {
|
|
216899
|
+
parsed.error = parsed.error || "URI host is malformed.";
|
|
216900
|
+
malformedAuthorityOrPort = true;
|
|
216901
|
+
}
|
|
216387
216902
|
} else {
|
|
216388
216903
|
isIP5 = true;
|
|
216389
216904
|
}
|
|
@@ -216401,42 +216916,37 @@ var require_fast_uri = __commonJS({
|
|
|
216401
216916
|
parsed.error = parsed.error || "URI is not a " + options.reference + " reference.";
|
|
216402
216917
|
}
|
|
216403
216918
|
const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
|
|
216404
|
-
if (!
|
|
216405
|
-
|
|
216406
|
-
|
|
216407
|
-
|
|
216408
|
-
|
|
216409
|
-
|
|
216410
|
-
|
|
216919
|
+
if (!malformedIPLiteral) {
|
|
216920
|
+
malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP5);
|
|
216921
|
+
}
|
|
216922
|
+
if (uri.indexOf("%") !== -1 && parsed.host !== void 0 && !malformedIPLiteral) {
|
|
216923
|
+
let host = isIP5 ? parsed.host : normalizePercentEncoding(parsed.host, true);
|
|
216924
|
+
if (!isIP5) {
|
|
216925
|
+
host = normalizePercentEncoding(host.toLowerCase());
|
|
216411
216926
|
}
|
|
216927
|
+
parsed.host = reescapeHostDelimiters(host, isIP5);
|
|
216412
216928
|
}
|
|
216413
216929
|
if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
|
|
216414
|
-
if (uri.indexOf("%") !== -1) {
|
|
216415
|
-
if (parsed.scheme !== void 0) {
|
|
216416
|
-
parsed.scheme = unescape(parsed.scheme);
|
|
216417
|
-
}
|
|
216418
|
-
if (parsed.host !== void 0) {
|
|
216419
|
-
parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP5);
|
|
216420
|
-
}
|
|
216421
|
-
}
|
|
216422
216930
|
if (parsed.path) {
|
|
216423
216931
|
parsed.path = normalizePathEncoding(parsed.path);
|
|
216424
216932
|
}
|
|
216933
|
+
if (parsed.query) {
|
|
216934
|
+
parsed.query = normalizeQueryFragmentEncoding(parsed.query);
|
|
216935
|
+
}
|
|
216425
216936
|
if (parsed.fragment) {
|
|
216426
|
-
|
|
216427
|
-
parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
|
|
216428
|
-
} catch {
|
|
216429
|
-
parsed.error = parsed.error || "URI malformed";
|
|
216430
|
-
}
|
|
216937
|
+
parsed.fragment = normalizeQueryFragmentEncoding(parsed.fragment);
|
|
216431
216938
|
}
|
|
216432
216939
|
}
|
|
216433
216940
|
if (schemeHandler && schemeHandler.parse) {
|
|
216434
216941
|
schemeHandler.parse(parsed, options);
|
|
216942
|
+
if (schemeHandler === SCHEMES.urn && parsed.nid === void 0) {
|
|
216943
|
+
malformedSchemeSpecific = true;
|
|
216944
|
+
}
|
|
216435
216945
|
}
|
|
216436
216946
|
} else {
|
|
216437
216947
|
parsed.error = parsed.error || "URI can not be parsed.";
|
|
216438
216948
|
}
|
|
216439
|
-
return { parsed, malformedAuthorityOrPort };
|
|
216949
|
+
return { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme };
|
|
216440
216950
|
}
|
|
216441
216951
|
function parse5(uri, opts) {
|
|
216442
216952
|
return parseWithStatus(uri, opts).parsed;
|
|
@@ -216445,20 +216955,28 @@ var require_fast_uri = __commonJS({
|
|
|
216445
216955
|
return normalizeStringWithStatus(uri, opts).normalized;
|
|
216446
216956
|
}
|
|
216447
216957
|
function normalizeStringWithStatus(uri, opts) {
|
|
216448
|
-
const { parsed, malformedAuthorityOrPort } = parseWithStatus(uri, opts);
|
|
216958
|
+
const { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = parseWithStatus(uri, opts);
|
|
216449
216959
|
return {
|
|
216450
|
-
normalized: malformedAuthorityOrPort ? uri : serialize(parsed, opts),
|
|
216451
|
-
malformedAuthorityOrPort
|
|
216960
|
+
normalized: malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? uri : serialize(parsed, opts),
|
|
216961
|
+
malformedAuthorityOrPort,
|
|
216962
|
+
malformedPercentEncoding,
|
|
216963
|
+
malformedSchemeSpecific,
|
|
216964
|
+
malformedHost,
|
|
216965
|
+
malformedScheme
|
|
216452
216966
|
};
|
|
216453
216967
|
}
|
|
216454
216968
|
function normalizeComparableURI(uri, opts) {
|
|
216455
|
-
if (typeof uri
|
|
216456
|
-
|
|
216457
|
-
return malformedAuthorityOrPort ? void 0 : normalized;
|
|
216969
|
+
if (typeof uri !== "string" && typeof uri !== "object") {
|
|
216970
|
+
return void 0;
|
|
216458
216971
|
}
|
|
216459
|
-
|
|
216460
|
-
|
|
216972
|
+
let value;
|
|
216973
|
+
try {
|
|
216974
|
+
value = typeof uri === "string" ? uri : serialize(uri, opts);
|
|
216975
|
+
} catch {
|
|
216976
|
+
return void 0;
|
|
216461
216977
|
}
|
|
216978
|
+
const { normalized, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = normalizeStringWithStatus(value, opts);
|
|
216979
|
+
return malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? void 0 : normalized;
|
|
216462
216980
|
}
|
|
216463
216981
|
var fastUri = {
|
|
216464
216982
|
SCHEMES,
|
|
@@ -221070,6 +221588,42 @@ var init_mcp_server = __esm({
|
|
|
221070
221588
|
});
|
|
221071
221589
|
|
|
221072
221590
|
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
|
|
221591
|
+
function toolInputElementCount(value, max) {
|
|
221592
|
+
let count3 = 0;
|
|
221593
|
+
const stack = [value];
|
|
221594
|
+
while (stack.length > 0) {
|
|
221595
|
+
const node = stack.pop();
|
|
221596
|
+
if (node === null || typeof node !== "object")
|
|
221597
|
+
continue;
|
|
221598
|
+
if (Array.isArray(node)) {
|
|
221599
|
+
for (const child of node) {
|
|
221600
|
+
if (++count3 > max)
|
|
221601
|
+
return count3;
|
|
221602
|
+
if (child !== null && typeof child === "object")
|
|
221603
|
+
stack.push(child);
|
|
221604
|
+
}
|
|
221605
|
+
} else {
|
|
221606
|
+
for (const key in node) {
|
|
221607
|
+
if (!Object.prototype.hasOwnProperty.call(node, key))
|
|
221608
|
+
continue;
|
|
221609
|
+
if (++count3 > max)
|
|
221610
|
+
return count3;
|
|
221611
|
+
const child = node[key];
|
|
221612
|
+
if (child !== null && typeof child === "object")
|
|
221613
|
+
stack.push(child);
|
|
221614
|
+
}
|
|
221615
|
+
}
|
|
221616
|
+
}
|
|
221617
|
+
return count3;
|
|
221618
|
+
}
|
|
221619
|
+
function resolveMaxToolInputElements(value) {
|
|
221620
|
+
if (value === void 0 || value === Infinity)
|
|
221621
|
+
return void 0;
|
|
221622
|
+
if (typeof value !== "number" || Number.isNaN(value) || value < 1) {
|
|
221623
|
+
throw new RangeError(`maxToolInputElements must be a number of at least 1, or Infinity, got ${String(value)}`);
|
|
221624
|
+
}
|
|
221625
|
+
return value;
|
|
221626
|
+
}
|
|
221073
221627
|
function isZodTypeLike(value) {
|
|
221074
221628
|
return value !== null && typeof value === "object" && "parse" in value && typeof value.parse === "function" && "safeParse" in value && typeof value.safeParse === "function";
|
|
221075
221629
|
}
|
|
@@ -221160,6 +221714,7 @@ var init_mcp = __esm({
|
|
|
221160
221714
|
this._resourceHandlersInitialized = false;
|
|
221161
221715
|
this._promptHandlersInitialized = false;
|
|
221162
221716
|
this.server = new Server(serverInfo, options);
|
|
221717
|
+
this._maxToolInputElements = resolveMaxToolInputElements(options?.maxToolInputElements);
|
|
221163
221718
|
}
|
|
221164
221719
|
/**
|
|
221165
221720
|
* Access experimental features.
|
|
@@ -221290,12 +221845,15 @@ var init_mcp = __esm({
|
|
|
221290
221845
|
* Validates tool input arguments against the tool's input schema.
|
|
221291
221846
|
*/
|
|
221292
221847
|
async validateToolInput(tool, args, toolName) {
|
|
221848
|
+
if (this._maxToolInputElements !== void 0 && toolInputElementCount(args, this._maxToolInputElements) > this._maxToolInputElements) {
|
|
221849
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid arguments for tool ${toolName}: arguments contain more than the maximum of ${this._maxToolInputElements} elements`);
|
|
221850
|
+
}
|
|
221293
221851
|
if (!tool.inputSchema) {
|
|
221294
221852
|
return void 0;
|
|
221295
221853
|
}
|
|
221296
221854
|
const inputObj = normalizeObjectSchema(tool.inputSchema);
|
|
221297
221855
|
const schemaToParse = inputObj ?? tool.inputSchema;
|
|
221298
|
-
const parseResult = await safeParseAsync3(schemaToParse, args);
|
|
221856
|
+
const parseResult = await safeParseAsync3(schemaToParse, args ?? {});
|
|
221299
221857
|
if (!parseResult.success) {
|
|
221300
221858
|
const error40 = "error" in parseResult ? parseResult.error : "Unknown error";
|
|
221301
221859
|
const errorMessage = getParseErrorMessage(error40);
|
|
@@ -221533,7 +222091,7 @@ var init_mcp = __esm({
|
|
|
221533
222091
|
}
|
|
221534
222092
|
if (prompt2.argsSchema) {
|
|
221535
222093
|
const argsObj = normalizeObjectSchema(prompt2.argsSchema);
|
|
221536
|
-
const parseResult = await safeParseAsync3(argsObj, request.params.arguments);
|
|
222094
|
+
const parseResult = await safeParseAsync3(argsObj, request.params.arguments ?? {});
|
|
221537
222095
|
if (!parseResult.success) {
|
|
221538
222096
|
const error40 = "error" in parseResult ? parseResult.error : "Unknown error";
|
|
221539
222097
|
const errorMessage = getParseErrorMessage(error40);
|
|
@@ -225130,7 +225688,8 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
|
|
|
225130
225688
|
"OPENAI_API_KEY",
|
|
225131
225689
|
"ANTHROPIC_API_KEY",
|
|
225132
225690
|
...resolved.memory.llm.provider === "openrouter" || resolved.memory.llm.baseUrl?.includes("openrouter.ai") ? ["OPENROUTER_API_KEY"] : [],
|
|
225133
|
-
...resolved.memory.llm.provider === "requesty" ? ["REQUESTY_API_KEY"] : []
|
|
225691
|
+
...resolved.memory.llm.provider === "requesty" ? ["REQUESTY_API_KEY"] : [],
|
|
225692
|
+
...resolved.memory.llm.provider === "apiroute" ? ["API_ROUTE_API_KEY"] : []
|
|
225134
225693
|
];
|
|
225135
225694
|
if (llmKey) {
|
|
225136
225695
|
const src2 = resolveDashboardKeySource({ value: llmKey, envKeys: memoryKeyEnv, configSource });
|
|
@@ -265461,12 +266020,13 @@ __export(image_loader_exports, {
|
|
|
265461
266020
|
analyzeImage: () => analyzeImage
|
|
265462
266021
|
});
|
|
265463
266022
|
async function callVisionLLM(systemPrompt, imageBase64, mimeType) {
|
|
265464
|
-
const
|
|
266023
|
+
const config2 = getLLMConfig();
|
|
266024
|
+
const apiKey = config2?.apiKey ?? getLLMApiKey();
|
|
265465
266025
|
if (!apiKey) {
|
|
265466
266026
|
throw new Error("No LLM API key configured for image analysis.");
|
|
265467
266027
|
}
|
|
265468
|
-
const baseUrl = normalizeOpenAICompatibleBaseUrl(getLLMBaseUrl("https://api.openai.com/v1"));
|
|
265469
|
-
const model = getLLMModel("gpt-4o");
|
|
266028
|
+
const baseUrl = normalizeOpenAICompatibleBaseUrl(config2?.baseUrl ?? getLLMBaseUrl("https://api.openai.com/v1"));
|
|
266029
|
+
const model = config2?.model ?? getLLMModel("gpt-4o");
|
|
265470
266030
|
const response = await fetch(`${baseUrl}/chat/completions`, {
|
|
265471
266031
|
method: "POST",
|
|
265472
266032
|
headers: {
|
|
@@ -265521,7 +266081,7 @@ async function analyzeImage(input) {
|
|
|
265521
266081
|
const config2 = getLLMConfig();
|
|
265522
266082
|
if (!OPENAI_COMPATIBLE_PROVIDERS.has(config2.provider)) {
|
|
265523
266083
|
throw new Error(
|
|
265524
|
-
`Image analysis requires an OpenAI-compatible provider (openai, openrouter, requesty, or custom). Current provider "${config2.provider}" uses a different API shape. Set MEMORIX_LLM_PROVIDER=openai or configure an OpenAI-compatible base URL.`
|
|
266084
|
+
`Image analysis requires an OpenAI-compatible provider (openai, openrouter, requesty, apiroute, or custom). Current provider "${config2.provider}" uses a different API shape. Set MEMORIX_LLM_PROVIDER=openai or configure an OpenAI-compatible base URL.`
|
|
265525
266085
|
);
|
|
265526
266086
|
}
|
|
265527
266087
|
const bytes = decodeBase64ImagePayload(input.base64, MAX_VISION_IMAGE_BYTES);
|
|
@@ -265560,7 +266120,7 @@ var init_image_loader = __esm({
|
|
|
265560
266120
|
init_provider2();
|
|
265561
266121
|
init_secret_filter();
|
|
265562
266122
|
init_image_payload();
|
|
265563
|
-
OPENAI_COMPATIBLE_PROVIDERS = /* @__PURE__ */ new Set(["openai", "openrouter", "requesty", "custom"]);
|
|
266123
|
+
OPENAI_COMPATIBLE_PROVIDERS = /* @__PURE__ */ new Set(["openai", "openrouter", "requesty", "apiroute", "custom"]);
|
|
265564
266124
|
MAX_VISION_PROMPT_CHARS = 12e3;
|
|
265565
266125
|
MAX_VISION_DESCRIPTION_CHARS = 12e3;
|
|
265566
266126
|
MAX_VISION_LABELS = 50;
|
|
@@ -265842,8 +266402,8 @@ async function createMemorixServer(cwd, existingServer, sharedTeam, options = {}
|
|
|
265842
266402
|
if (!lightweightUnresolvedSession && !deferProjectRuntimeInit) {
|
|
265843
266403
|
try {
|
|
265844
266404
|
const { getAllObservations: getAllObservations2 } = await Promise.resolve().then(() => (init_observations(), observations_exports));
|
|
265845
|
-
const
|
|
265846
|
-
const observedIds = [...new Set(
|
|
266405
|
+
const store2 = getObservationStore();
|
|
266406
|
+
const observedIds = store2.listProjectIds ? await store2.listProjectIds() : [...new Set(getAllObservations2().map((o4) => o4.projectId))];
|
|
265847
266407
|
const merged = await autoMergeByBaseName(observedIds);
|
|
265848
266408
|
if (merged > 0) {
|
|
265849
266409
|
console.error(`[memorix] Auto-merged ${merged} alias group(s) by base name`);
|
|
@@ -265884,8 +266444,8 @@ async function createMemorixServer(cwd, existingServer, sharedTeam, options = {}
|
|
|
265884
266444
|
try {
|
|
265885
266445
|
const { getAllObservations: getAllObservations2 } = await Promise.resolve().then(() => (init_observations(), observations_exports));
|
|
265886
266446
|
await initObservations(projectDir2);
|
|
265887
|
-
const
|
|
265888
|
-
const observedIds = [...new Set(
|
|
266447
|
+
const store2 = getObservationStore();
|
|
266448
|
+
const observedIds = store2.listProjectIds ? await store2.listProjectIds() : [...new Set(getAllObservations2().map((o4) => o4.projectId))];
|
|
265889
266449
|
const merged = await autoMergeByBaseName(observedIds);
|
|
265890
266450
|
if (merged > 0) {
|
|
265891
266451
|
console.error(`[memorix] Auto-merged ${merged} alias group(s) by base name`);
|
|
@@ -271256,20 +271816,15 @@ var init_websocket = __esm({
|
|
|
271256
271816
|
if (typeof args[0] === "function") {
|
|
271257
271817
|
const [createEvents, options] = args;
|
|
271258
271818
|
return async function upgradeWebSocket2(c6, next) {
|
|
271259
|
-
const
|
|
271260
|
-
|
|
271261
|
-
if (result) {
|
|
271262
|
-
return result;
|
|
271263
|
-
}
|
|
271819
|
+
const result = await handler(c6, await createEvents(c6), options);
|
|
271820
|
+
if (result) return result;
|
|
271264
271821
|
await next();
|
|
271265
271822
|
};
|
|
271266
271823
|
} else {
|
|
271267
271824
|
const [c6, events, options] = args;
|
|
271268
271825
|
return (async () => {
|
|
271269
271826
|
const upgraded = await handler(c6, events, options);
|
|
271270
|
-
if (!upgraded)
|
|
271271
|
-
throw new Error("Failed to upgrade WebSocket");
|
|
271272
|
-
}
|
|
271827
|
+
if (!upgraded) throw new Error("Failed to upgrade WebSocket");
|
|
271273
271828
|
return upgraded;
|
|
271274
271829
|
})();
|
|
271275
271830
|
}
|
|
@@ -272428,6 +272983,57 @@ var init_mediaType = __esm({
|
|
|
272428
272983
|
}
|
|
272429
272984
|
});
|
|
272430
272985
|
|
|
272986
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/requestBody.js
|
|
272987
|
+
function requestBodyTooLargeMessage(maxBytes) {
|
|
272988
|
+
return `Payload Too Large: Request body must not exceed ${maxBytes} bytes`;
|
|
272989
|
+
}
|
|
272990
|
+
function resolveMaxRequestBodySize(value) {
|
|
272991
|
+
if (value === void 0) {
|
|
272992
|
+
return DEFAULT_MAX_REQUEST_BODY_SIZE;
|
|
272993
|
+
}
|
|
272994
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
272995
|
+
throw new RangeError(`maxRequestBodySize must be a positive number of bytes, got ${String(value)}`);
|
|
272996
|
+
}
|
|
272997
|
+
return value;
|
|
272998
|
+
}
|
|
272999
|
+
async function readRequestBody(request, maxBytes = DEFAULT_MAX_REQUEST_BODY_SIZE) {
|
|
273000
|
+
if (Number(request.headers.get("content-length")) > maxBytes) {
|
|
273001
|
+
return { tooLarge: true };
|
|
273002
|
+
}
|
|
273003
|
+
if (request.body === null) {
|
|
273004
|
+
return { tooLarge: false, text: "" };
|
|
273005
|
+
}
|
|
273006
|
+
const reader2 = request.body.getReader();
|
|
273007
|
+
const decoder2 = new TextDecoder();
|
|
273008
|
+
let received = 0;
|
|
273009
|
+
let text3 = "";
|
|
273010
|
+
try {
|
|
273011
|
+
for (; ; ) {
|
|
273012
|
+
const { done, value } = await reader2.read();
|
|
273013
|
+
if (done) {
|
|
273014
|
+
break;
|
|
273015
|
+
}
|
|
273016
|
+
received += value.byteLength;
|
|
273017
|
+
if (received > maxBytes) {
|
|
273018
|
+
return { tooLarge: true };
|
|
273019
|
+
}
|
|
273020
|
+
text3 += decoder2.decode(value, { stream: true });
|
|
273021
|
+
}
|
|
273022
|
+
} finally {
|
|
273023
|
+
reader2.releaseLock();
|
|
273024
|
+
}
|
|
273025
|
+
return { tooLarge: false, text: text3 + decoder2.decode() };
|
|
273026
|
+
}
|
|
273027
|
+
var DEFAULT_MAX_REQUEST_BODY_SIZE, MAX_BATCH_SIZE2;
|
|
273028
|
+
var init_requestBody = __esm({
|
|
273029
|
+
"node_modules/@modelcontextprotocol/sdk/dist/esm/server/requestBody.js"() {
|
|
273030
|
+
"use strict";
|
|
273031
|
+
init_esm_shims();
|
|
273032
|
+
DEFAULT_MAX_REQUEST_BODY_SIZE = 4 * 1024 * 1024;
|
|
273033
|
+
MAX_BATCH_SIZE2 = 100;
|
|
273034
|
+
}
|
|
273035
|
+
});
|
|
273036
|
+
|
|
272431
273037
|
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/sseKeepAlive.js
|
|
272432
273038
|
function armSseKeepAlive(intervalMs, onTick) {
|
|
272433
273039
|
if (!Number.isFinite(intervalMs) || intervalMs < 1) {
|
|
@@ -272454,6 +273060,7 @@ var init_webStandardStreamableHttp = __esm({
|
|
|
272454
273060
|
"use strict";
|
|
272455
273061
|
init_esm_shims();
|
|
272456
273062
|
init_mediaType();
|
|
273063
|
+
init_requestBody();
|
|
272457
273064
|
init_sseKeepAlive();
|
|
272458
273065
|
init_types8();
|
|
272459
273066
|
WebStandardStreamableHTTPServerTransport = class {
|
|
@@ -272478,6 +273085,7 @@ var init_webStandardStreamableHttp = __esm({
|
|
|
272478
273085
|
this._enableDnsRebindingProtection = options.enableDnsRebindingProtection ?? false;
|
|
272479
273086
|
this._retryInterval = options.retryInterval;
|
|
272480
273087
|
this._keepAliveMs = options.keepAliveMs ?? DEFAULT_SSE_KEEP_ALIVE_MS;
|
|
273088
|
+
this._maxRequestBodySize = resolveMaxRequestBodySize(options.maxRequestBodySize);
|
|
272481
273089
|
}
|
|
272482
273090
|
/**
|
|
272483
273091
|
* Arms a keep-alive interval for an SSE stream that periodically writes an SSE
|
|
@@ -272839,12 +273447,22 @@ data:
|
|
|
272839
273447
|
rawMessage = options.parsedBody;
|
|
272840
273448
|
} else {
|
|
272841
273449
|
try {
|
|
272842
|
-
|
|
273450
|
+
const body = await readRequestBody(req, this._maxRequestBodySize);
|
|
273451
|
+
if (body.tooLarge) {
|
|
273452
|
+
const message = requestBodyTooLargeMessage(this._maxRequestBodySize);
|
|
273453
|
+
this.onerror?.(new Error(message));
|
|
273454
|
+
return this.createJsonErrorResponse(413, -32e3, message);
|
|
273455
|
+
}
|
|
273456
|
+
rawMessage = JSON.parse(body.text);
|
|
272843
273457
|
} catch {
|
|
272844
273458
|
this.onerror?.(new Error("Parse error: Invalid JSON"));
|
|
272845
273459
|
return this.createJsonErrorResponse(400, -32700, "Parse error: Invalid JSON");
|
|
272846
273460
|
}
|
|
272847
273461
|
}
|
|
273462
|
+
if (Array.isArray(rawMessage) && rawMessage.length > MAX_BATCH_SIZE2) {
|
|
273463
|
+
this.onerror?.(new Error(`Invalid Request: Batch must not exceed ${MAX_BATCH_SIZE2} messages`));
|
|
273464
|
+
return this.createJsonErrorResponse(400, -32600, `Invalid Request: Batch must not exceed ${MAX_BATCH_SIZE2} messages`);
|
|
273465
|
+
}
|
|
272848
273466
|
let messages;
|
|
272849
273467
|
try {
|
|
272850
273468
|
if (Array.isArray(rawMessage)) {
|
|
@@ -278143,6 +278761,7 @@ function extractEventName(payload, agent) {
|
|
|
278143
278761
|
case "cursor":
|
|
278144
278762
|
return payload.hook_event_name ?? inferCursorEvent(payload);
|
|
278145
278763
|
case "claude":
|
|
278764
|
+
case "qwen":
|
|
278146
278765
|
return payload.hook_event_name ?? "";
|
|
278147
278766
|
case "codex":
|
|
278148
278767
|
return payload.hook_event_name ?? "";
|
|
@@ -278191,7 +278810,7 @@ function normalizeClaude(payload, event) {
|
|
|
278191
278810
|
if (/^bash$/i.test(toolName) && toolInput?.command) {
|
|
278192
278811
|
result.command = toolInput.command;
|
|
278193
278812
|
}
|
|
278194
|
-
if (/^(write|edit|multi_edit|multiedittool)$/i.test(toolName)) {
|
|
278813
|
+
if (/^(write|write_file|edit|edit_file|multi_edit|multiedittool)$/i.test(toolName)) {
|
|
278195
278814
|
result.filePath = toolInput?.file_path ?? toolInput?.filePath;
|
|
278196
278815
|
}
|
|
278197
278816
|
}
|
|
@@ -278481,6 +279100,7 @@ function normalizeHookInput(payload) {
|
|
|
278481
279100
|
let agentSpecific = {};
|
|
278482
279101
|
switch (agent) {
|
|
278483
279102
|
case "claude":
|
|
279103
|
+
case "qwen":
|
|
278484
279104
|
agentSpecific = normalizeClaude(payload, event);
|
|
278485
279105
|
break;
|
|
278486
279106
|
case "copilot":
|
|
@@ -278564,9 +279184,12 @@ var init_normalizer = __esm({
|
|
|
278564
279184
|
PreToolUse: "post_tool",
|
|
278565
279185
|
// we handle pre as post for memory purposes
|
|
278566
279186
|
PostToolUse: "post_tool",
|
|
279187
|
+
PostToolUseFailure: "post_tool",
|
|
278567
279188
|
PreCompact: "pre_compact",
|
|
279189
|
+
PostCompact: "post_compact",
|
|
278568
279190
|
Stop: "session_end",
|
|
278569
279191
|
SessionEnd: "session_end",
|
|
279192
|
+
SessionDelete: "session_end",
|
|
278570
279193
|
// Grok Build (Claude-compatible PascalCase plus snake_case hookEventName)
|
|
278571
279194
|
user_prompt_submit: "user_prompt",
|
|
278572
279195
|
pre_tool_use: "post_tool",
|
|
@@ -278847,11 +279470,7 @@ async function readHookStdin(stdin2, timeoutMs) {
|
|
|
278847
279470
|
stdin2.removeListener("end", finish);
|
|
278848
279471
|
stdin2.removeListener("error", finish);
|
|
278849
279472
|
stdin2.pause?.();
|
|
278850
|
-
|
|
278851
|
-
stdin2.destroy?.();
|
|
278852
|
-
} else {
|
|
278853
|
-
stdin2.unref?.();
|
|
278854
|
-
}
|
|
279473
|
+
stdin2.unref?.();
|
|
278855
279474
|
resolve9(Buffer.concat(chunks).toString("utf-8").trim());
|
|
278856
279475
|
};
|
|
278857
279476
|
const onData = (chunk) => {
|
|
@@ -278932,7 +279551,7 @@ var init_lifecycle2 = __esm({
|
|
|
278932
279551
|
// src/hooks/handler.ts
|
|
278933
279552
|
var handler_exports = {};
|
|
278934
279553
|
__export(handler_exports, {
|
|
278935
|
-
TYPE_EMOJI: () =>
|
|
279554
|
+
TYPE_EMOJI: () => TYPE_EMOJI,
|
|
278936
279555
|
formatHookOutput: () => formatHookOutput,
|
|
278937
279556
|
handleHookEvent: () => handleHookEvent,
|
|
278938
279557
|
resetCooldowns: () => resetCooldowns,
|
|
@@ -279496,7 +280115,7 @@ function toAntigravityHookOutput(rawEventName, output) {
|
|
|
279496
280115
|
return {};
|
|
279497
280116
|
}
|
|
279498
280117
|
}
|
|
279499
|
-
var
|
|
280118
|
+
var TYPE_EMOJI, cooldowns, COOLDOWN_MS, MIN_PROMPT_LENGTH, MAX_CONTENT_LENGTH, STORAGE_POLICY;
|
|
279500
280119
|
var init_handler = __esm({
|
|
279501
280120
|
"src/hooks/handler.ts"() {
|
|
279502
280121
|
"use strict";
|
|
@@ -279506,7 +280125,7 @@ var init_handler = __esm({
|
|
|
279506
280125
|
init_pattern_detector();
|
|
279507
280126
|
init_significance_filter();
|
|
279508
280127
|
init_lifecycle2();
|
|
279509
|
-
|
|
280128
|
+
TYPE_EMOJI = {
|
|
279510
280129
|
"gotcha": "[GOTCHA]",
|
|
279511
280130
|
"decision": "[DECISION]",
|
|
279512
280131
|
"problem-solution": "[FIX]",
|
|
@@ -279600,7 +280219,8 @@ var init_types9 = __esm({
|
|
|
279600
280219
|
pi: "community",
|
|
279601
280220
|
omp: "community",
|
|
279602
280221
|
antigravity: "community",
|
|
279603
|
-
grok: "community"
|
|
280222
|
+
grok: "community",
|
|
280223
|
+
qwen: "extended"
|
|
279604
280224
|
};
|
|
279605
280225
|
}
|
|
279606
280226
|
});
|
|
@@ -279650,6 +280270,7 @@ async function installSingleAgent2(agent, cwd, global2) {
|
|
|
279650
280270
|
function getAgentLabel2(agent) {
|
|
279651
280271
|
const labels = {
|
|
279652
280272
|
claude: "Claude Code",
|
|
280273
|
+
qwen: "Qwen Code",
|
|
279653
280274
|
codex: "Codex",
|
|
279654
280275
|
windsurf: "Windsurf",
|
|
279655
280276
|
cursor: "Cursor",
|
|
@@ -279671,6 +280292,7 @@ function getAgentLabel2(agent) {
|
|
|
279671
280292
|
function getAgentHint2(agent) {
|
|
279672
280293
|
const hints = {
|
|
279673
280294
|
claude: ".claude/settings.json",
|
|
280295
|
+
qwen: ".qwen/settings.json",
|
|
279674
280296
|
windsurf: ".windsurf/hooks.json",
|
|
279675
280297
|
cursor: ".cursor/hooks.json",
|
|
279676
280298
|
copilot: ".github/hooks/memorix.json (project-only, no global)",
|
|
@@ -289707,6 +290329,7 @@ function ConfigureView({ onBack }) {
|
|
|
289707
290329
|
{ key: "anthropic", label: "Anthropic", hint: "claude-3-haiku" },
|
|
289708
290330
|
{ key: "openrouter", label: "OpenRouter", hint: "multi-provider" },
|
|
289709
290331
|
{ key: "requesty", label: "Requesty", hint: "multi-provider" },
|
|
290332
|
+
{ key: "apiroute", label: "API Route", hint: "multi-provider" },
|
|
289710
290333
|
{ key: "atlascloud", label: "Atlas Cloud", hint: "DeepSeek V3.2" },
|
|
289711
290334
|
{ key: "custom", label: "Custom endpoint", hint: "OpenAI-compatible" },
|
|
289712
290335
|
{ key: "disable", label: "Disable LLM", hint: "free heuristic mode", color: COLORS.warning },
|
|
@@ -290001,6 +290624,7 @@ function getDefaultModel(provider2) {
|
|
|
290001
290624
|
if (provider2 === "anthropic") return "claude-3-haiku-20240307";
|
|
290002
290625
|
if (provider2 === "openrouter") return "openai/gpt-4o-mini";
|
|
290003
290626
|
if (provider2 === "requesty") return "openai/gpt-4o-mini";
|
|
290627
|
+
if (provider2 === "apiroute") return "deepseek-v4.1-flash";
|
|
290004
290628
|
if (provider2 === "atlascloud") return "deepseek-ai/deepseek-v3.2";
|
|
290005
290629
|
return "gpt-4o-mini";
|
|
290006
290630
|
}
|
|
@@ -293558,14 +294182,14 @@ var main2 = defineCommand({
|
|
|
293558
294182
|
search: () => Promise.resolve(defineCommand({
|
|
293559
294183
|
meta: { name: "search", description: "Shortcut for `memorix memory search`" },
|
|
293560
294184
|
args: {
|
|
293561
|
-
query: { type: "
|
|
294185
|
+
query: { type: "string", description: "Search query (also accepts the first positional argument)", required: false },
|
|
293562
294186
|
limit: { type: "string", description: "Maximum results" },
|
|
293563
294187
|
quality: { type: "string", description: "Retrieval profile: fast, balanced (default), or thorough" },
|
|
293564
294188
|
json: { type: "boolean", description: "Emit machine-readable JSON output" }
|
|
293565
294189
|
},
|
|
293566
294190
|
async run({ args }) {
|
|
293567
294191
|
await runMemoryShortcut("search", {
|
|
293568
|
-
query: args.query,
|
|
294192
|
+
query: args.query ?? args._?.[0],
|
|
293569
294193
|
limit: args.limit,
|
|
293570
294194
|
quality: args.quality,
|
|
293571
294195
|
json: args.json
|