@x-code-cli/core 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/api-errors.d.ts +11 -0
- package/dist/agent/api-errors.d.ts.map +1 -0
- package/dist/agent/api-errors.js +134 -0
- package/dist/agent/api-errors.js.map +1 -0
- package/dist/agent/context-window.d.ts +26 -0
- package/dist/agent/context-window.d.ts.map +1 -0
- package/dist/agent/context-window.js +126 -0
- package/dist/agent/context-window.js.map +1 -0
- package/dist/agent/loop-state.d.ts +14 -0
- package/dist/agent/loop-state.d.ts.map +1 -0
- package/dist/agent/loop-state.js +12 -0
- package/dist/agent/loop-state.js.map +1 -0
- package/dist/agent/loop.d.ts +11 -15
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +213 -381
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/messages.d.ts +0 -2
- package/dist/agent/messages.d.ts.map +1 -1
- package/dist/agent/messages.js +0 -32
- package/dist/agent/messages.js.map +1 -1
- package/dist/agent/provider-compat.d.ts +17 -0
- package/dist/agent/provider-compat.d.ts.map +1 -0
- package/dist/agent/provider-compat.js +31 -0
- package/dist/agent/provider-compat.js.map +1 -0
- package/dist/agent/stream-utils.d.ts +33 -0
- package/dist/agent/stream-utils.d.ts.map +1 -0
- package/dist/agent/stream-utils.js +14 -0
- package/dist/agent/stream-utils.js.map +1 -0
- package/dist/agent/system-prompt.d.ts +1 -3
- package/dist/agent/system-prompt.d.ts.map +1 -1
- package/dist/agent/system-prompt.js +34 -23
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/agent/tool-execution.d.ts +11 -0
- package/dist/agent/tool-execution.d.ts.map +1 -0
- package/dist/agent/tool-execution.js +171 -0
- package/dist/agent/tool-execution.js.map +1 -0
- package/dist/config/index.d.ts +19 -8
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +66 -32
- package/dist/config/index.js.map +1 -1
- package/dist/index.d.ts +7 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -6
- package/dist/index.js.map +1 -1
- package/dist/knowledge/auto-memory.d.ts +1 -1
- package/dist/knowledge/auto-memory.d.ts.map +1 -1
- package/dist/knowledge/auto-memory.js +55 -16
- package/dist/knowledge/auto-memory.js.map +1 -1
- package/dist/knowledge/init.d.ts +1 -2
- package/dist/knowledge/init.d.ts.map +1 -1
- package/dist/knowledge/init.js +83 -69
- package/dist/knowledge/init.js.map +1 -1
- package/dist/knowledge/loader.d.ts +0 -9
- package/dist/knowledge/loader.d.ts.map +1 -1
- package/dist/knowledge/loader.js +54 -99
- package/dist/knowledge/loader.js.map +1 -1
- package/dist/knowledge/session.d.ts +1 -1
- package/dist/knowledge/session.d.ts.map +1 -1
- package/dist/knowledge/session.js +2 -1
- package/dist/knowledge/session.js.map +1 -1
- package/dist/permissions/index.d.ts +2 -0
- package/dist/permissions/index.d.ts.map +1 -1
- package/dist/permissions/index.js +35 -14
- package/dist/permissions/index.js.map +1 -1
- package/dist/tools/glob.d.ts.map +1 -1
- package/dist/tools/glob.js +3 -1
- package/dist/tools/glob.js.map +1 -1
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +7 -2
- package/dist/tools/grep.js.map +1 -1
- package/dist/tools/index.d.ts +3 -7
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +1 -5
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/list-dir.d.ts.map +1 -1
- package/dist/tools/list-dir.js +3 -1
- package/dist/tools/list-dir.js.map +1 -1
- package/dist/tools/progress.d.ts +6 -0
- package/dist/tools/progress.d.ts.map +1 -0
- package/dist/tools/progress.js +14 -0
- package/dist/tools/progress.js.map +1 -0
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +3 -1
- package/dist/tools/read-file.js.map +1 -1
- package/dist/tools/save-knowledge.d.ts +2 -2
- package/dist/tools/save-knowledge.d.ts.map +1 -1
- package/dist/tools/save-knowledge.js +31 -6
- package/dist/tools/save-knowledge.js.map +1 -1
- package/dist/tools/shell-utils.d.ts.map +1 -1
- package/dist/tools/shell-utils.js +7 -0
- package/dist/tools/shell-utils.js.map +1 -1
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +88 -19
- package/dist/tools/web-fetch.js.map +1 -1
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +85 -12
- package/dist/tools/web-search.js.map +1 -1
- package/dist/types/index.d.ts +60 -21
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +64 -6
- package/dist/types/index.js.map +1 -1
- package/dist/utils.d.ts +3 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +32 -0
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
- package/dist/agent/plan-mode.d.ts +0 -11
- package/dist/agent/plan-mode.d.ts.map +0 -1
- package/dist/agent/plan-mode.js +0 -37
- package/dist/agent/plan-mode.js.map +0 -1
- package/dist/agent/pricing.d.ts +0 -9
- package/dist/agent/pricing.d.ts.map +0 -1
- package/dist/agent/pricing.js +0 -47
- package/dist/agent/pricing.js.map +0 -1
- package/dist/knowledge/hooks.d.ts +0 -3
- package/dist/knowledge/hooks.d.ts.map +0 -1
- package/dist/knowledge/hooks.js +0 -59
- package/dist/knowledge/hooks.js.map +0 -1
- package/dist/tools/enter-plan-mode.d.ts +0 -2
- package/dist/tools/enter-plan-mode.d.ts.map +0 -1
- package/dist/tools/enter-plan-mode.js +0 -11
- package/dist/tools/enter-plan-mode.js.map +0 -1
- package/dist/tools/exit-plan-mode.d.ts +0 -2
- package/dist/tools/exit-plan-mode.d.ts.map +0 -1
- package/dist/tools/exit-plan-mode.js +0 -9
- package/dist/tools/exit-plan-mode.js.map +0 -1
package/dist/config/index.js
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
// @x-code-cli/core — Configuration
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// @x-code-cli/core — Configuration resolution
|
|
2
|
+
//
|
|
3
|
+
// API keys always come from environment variables (provider-specific keys
|
|
4
|
+
// like ANTHROPIC_API_KEY / ALIBABA_API_KEY — never stored on disk).
|
|
5
|
+
//
|
|
6
|
+
// The default **model** can come from four sources, in precedence order:
|
|
7
|
+
// 1. `--model` CLI flag (explicit `input` arg)
|
|
8
|
+
// 2. `~/.x-code/config.json` `model` field — written by `/model` picker
|
|
9
|
+
// 3. `X_CODE_MODEL` environment variable
|
|
10
|
+
// 4. Smart default: first provider (by PROVIDER_DETECTION_ORDER) with a key
|
|
11
|
+
//
|
|
12
|
+
// The picker's choice beats the env var so that `/model` "sticks" across
|
|
13
|
+
// restarts — otherwise a user who had `X_CODE_MODEL` set in their shell /
|
|
14
|
+
// .env file would see their `/model` selection silently reverted next
|
|
15
|
+
// launch (reported bug).
|
|
16
|
+
import fsSync from 'node:fs';
|
|
4
17
|
import path from 'node:path';
|
|
5
18
|
import { MODEL_ALIASES, PROVIDER_DETECTION_ORDER } from '../types/index.js';
|
|
6
|
-
|
|
7
|
-
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
8
|
-
/** Load config from ~/.xcode/config.json (model preference only) */
|
|
9
|
-
export async function loadConfig() {
|
|
10
|
-
try {
|
|
11
|
-
const raw = await fs.readFile(CONFIG_FILE, 'utf-8');
|
|
12
|
-
return JSON.parse(raw);
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
return {};
|
|
16
|
-
}
|
|
17
|
-
}
|
|
19
|
+
import { GLOBAL_XCODE_DIR } from '../utils.js';
|
|
18
20
|
/** Provider → environment variable mapping */
|
|
19
21
|
const ENV_MAP = {
|
|
20
22
|
anthropic: 'ANTHROPIC_API_KEY',
|
|
@@ -43,29 +45,62 @@ export function getAvailableProviders() {
|
|
|
43
45
|
}
|
|
44
46
|
return providers;
|
|
45
47
|
}
|
|
46
|
-
/**
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Resolve a model ID with four levels of precedence:
|
|
50
|
+
* 1. Explicit `input` (e.g. --model CLI flag)
|
|
51
|
+
* 2. `~/.x-code/config.json` `model` field (written by the /model picker)
|
|
52
|
+
* 3. `X_CODE_MODEL` environment variable
|
|
53
|
+
* 4. Smart default: first provider (by PROVIDER_DETECTION_ORDER) with an API key
|
|
54
|
+
*
|
|
55
|
+
* Aliases in MODEL_ALIASES (e.g. "sonnet" → "anthropic:claude-sonnet-4-5")
|
|
56
|
+
* are expanded at all levels. Returns null if no provider is configured.
|
|
57
|
+
*/
|
|
58
|
+
export function resolveModelId(input) {
|
|
59
|
+
const explicit = input ?? loadUserConfig().model ?? process.env.X_CODE_MODEL;
|
|
50
60
|
if (explicit) {
|
|
51
|
-
// Always return explicit choice (will show clear error later if key missing)
|
|
52
61
|
return MODEL_ALIASES[explicit] ?? explicit;
|
|
53
62
|
}
|
|
54
|
-
// 2. Config file model preference — only if provider key is available
|
|
55
|
-
if (config.model) {
|
|
56
|
-
const resolved = MODEL_ALIASES[config.model] ?? config.model;
|
|
57
|
-
const provider = resolved.split(':')[0];
|
|
58
|
-
if (provider && getApiKey(provider)) {
|
|
59
|
-
return resolved;
|
|
60
|
-
}
|
|
61
|
-
// Provider key not available — fall through to smart default
|
|
62
|
-
}
|
|
63
|
-
// 3. Smart default: scan for first available API key
|
|
64
63
|
for (const { envKey, defaultModel } of PROVIDER_DETECTION_ORDER) {
|
|
65
64
|
if (process.env[envKey])
|
|
66
65
|
return defaultModel;
|
|
67
66
|
}
|
|
68
|
-
return null;
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
function userConfigPath() {
|
|
70
|
+
// `X_CODE_HOME` overrides the config directory — used by tests to point
|
|
71
|
+
// at a scratch tmpdir so the real user's config doesn't leak into
|
|
72
|
+
// assertions, and available to end users who want to sandbox the CLI's
|
|
73
|
+
// state. Falls through to `~/.x-code` otherwise.
|
|
74
|
+
const override = process.env.X_CODE_HOME;
|
|
75
|
+
if (override)
|
|
76
|
+
return path.join(override, 'config.json');
|
|
77
|
+
return path.join(GLOBAL_XCODE_DIR, 'config.json');
|
|
78
|
+
}
|
|
79
|
+
/** Read the user config. Returns empty object on any failure (missing file,
|
|
80
|
+
* parse error, wrong shape) so callers don't have to null-check. */
|
|
81
|
+
export function loadUserConfig() {
|
|
82
|
+
try {
|
|
83
|
+
const raw = fsSync.readFileSync(userConfigPath(), 'utf-8');
|
|
84
|
+
const parsed = JSON.parse(raw);
|
|
85
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
86
|
+
return parsed;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// File may not exist yet, or is malformed — either way fall through to {}
|
|
91
|
+
}
|
|
92
|
+
return {};
|
|
93
|
+
}
|
|
94
|
+
/** Write a partial update into the user config, preserving other keys. */
|
|
95
|
+
export function saveUserConfig(update) {
|
|
96
|
+
const merged = { ...loadUserConfig(), ...update };
|
|
97
|
+
try {
|
|
98
|
+
fsSync.mkdirSync(GLOBAL_XCODE_DIR, { recursive: true });
|
|
99
|
+
fsSync.writeFileSync(userConfigPath(), JSON.stringify(merged, null, 2) + '\n', 'utf-8');
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// Best-effort: don't crash the UI if the config dir is read-only.
|
|
103
|
+
}
|
|
69
104
|
}
|
|
70
105
|
/** Build provider options with API keys from env vars */
|
|
71
106
|
export function getProviderOptions() {
|
|
@@ -84,5 +119,4 @@ export function getProviderOptions() {
|
|
|
84
119
|
},
|
|
85
120
|
};
|
|
86
121
|
}
|
|
87
|
-
export { CONFIG_DIR, CONFIG_FILE };
|
|
88
122
|
//# sourceMappingURL=index.js.map
|
package/dist/config/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
1
|
+
export type { PermissionLevel, TokenUsage, DisplayMessage, DisplayToolCall, AgentCallbacks, AgentOptions, KnowledgeCategory, KnowledgeFact, SessionSummary, ModelMessage, LanguageModel, } from './types/index.js';
|
|
2
|
+
export { MODEL_ALIASES, PROVIDER_DETECTION_ORDER, PROVIDER_KEY_URLS, PROVIDER_MODELS } from './types/index.js';
|
|
3
|
+
export type { ProviderModel } from './types/index.js';
|
|
4
|
+
export { resolveModelId, getAvailableProviders, getEnvVarName, loadUserConfig, saveUserConfig } from './config/index.js';
|
|
5
|
+
export type { UserConfig } from './config/index.js';
|
|
5
6
|
export { createModelRegistry } from './providers/registry.js';
|
|
6
7
|
export { agentLoop, saveSession, compressMessages } from './agent/loop.js';
|
|
7
8
|
export type { LoopState } from './agent/loop.js';
|
|
8
9
|
export { buildSystemPrompt } from './agent/system-prompt.js';
|
|
9
|
-
export {
|
|
10
|
-
export { estimateCost, formatCost } from './agent/pricing.js';
|
|
11
|
-
export type { CostEstimate } from './agent/pricing.js';
|
|
10
|
+
export { classifyApiError } from './agent/api-errors.js';
|
|
12
11
|
export { toolRegistry, truncateToolResult } from './tools/index.js';
|
|
13
12
|
export { getShellConfig } from './tools/shell-utils.js';
|
|
14
13
|
export { checkPermission, getPermissionLevel } from './permissions/index.js';
|
|
14
|
+
export { GLOBAL_XCODE_DIR, XCODE_DIR, debugLog } from './utils.js';
|
|
15
15
|
export { buildKnowledgeContext } from './knowledge/loader.js';
|
|
16
16
|
export { getAutoMemory, initMemories } from './knowledge/auto-memory.js';
|
|
17
17
|
export { loadLatestSession, saveSessionSummary, formatSessionForPrompt } from './knowledge/session.js';
|
|
18
|
-
export { scanProject } from './knowledge/hooks.js';
|
|
19
18
|
export { initProject } from './knowledge/init.js';
|
|
20
19
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,eAAe,EACf,UAAU,EACV,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,aAAa,GACd,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAC9G,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAGrD,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACxH,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAGnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAG7D,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAC1E,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAGxD,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAGvD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAG5E,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAGlE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACxE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AACtG,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
// @x-code-cli/core — Public API exports
|
|
2
|
-
export
|
|
3
|
-
export { MODEL_ALIASES, PROVIDER_DETECTION_ORDER, PROVIDER_KEY_URLS } from './types/index.js';
|
|
2
|
+
export { MODEL_ALIASES, PROVIDER_DETECTION_ORDER, PROVIDER_KEY_URLS, PROVIDER_MODELS } from './types/index.js';
|
|
4
3
|
// Config
|
|
5
|
-
export {
|
|
4
|
+
export { resolveModelId, getAvailableProviders, getEnvVarName, loadUserConfig, saveUserConfig } from './config/index.js';
|
|
6
5
|
// Provider Registry
|
|
7
6
|
export { createModelRegistry } from './providers/registry.js';
|
|
8
7
|
// Agent
|
|
9
8
|
export { agentLoop, saveSession, compressMessages } from './agent/loop.js';
|
|
10
9
|
export { buildSystemPrompt } from './agent/system-prompt.js';
|
|
11
|
-
export {
|
|
12
|
-
export { estimateCost, formatCost } from './agent/pricing.js';
|
|
10
|
+
export { classifyApiError } from './agent/api-errors.js';
|
|
13
11
|
// Tools
|
|
14
12
|
export { toolRegistry, truncateToolResult } from './tools/index.js';
|
|
15
13
|
export { getShellConfig } from './tools/shell-utils.js';
|
|
16
14
|
// Permissions
|
|
17
15
|
export { checkPermission, getPermissionLevel } from './permissions/index.js';
|
|
16
|
+
// Utils
|
|
17
|
+
export { GLOBAL_XCODE_DIR, XCODE_DIR, debugLog } from './utils.js';
|
|
18
18
|
// Knowledge
|
|
19
19
|
export { buildKnowledgeContext } from './knowledge/loader.js';
|
|
20
20
|
export { getAutoMemory, initMemories } from './knowledge/auto-memory.js';
|
|
21
21
|
export { loadLatestSession, saveSessionSummary, formatSessionForPrompt } from './knowledge/session.js';
|
|
22
|
-
export { scanProject } from './knowledge/hooks.js';
|
|
23
22
|
export { initProject } from './knowledge/init.js';
|
|
24
23
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AAiBxC,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAG9G,SAAS;AACT,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAGxH,oBAAoB;AACpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAE7D,QAAQ;AACR,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAE1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAExD,QAAQ;AACR,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAEvD,cAAc;AACd,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAE5E,QAAQ;AACR,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAElE,YAAY;AACZ,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACxE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AACtG,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -7,7 +7,7 @@ declare class AutoMemory {
|
|
|
7
7
|
constructor(filePath: string);
|
|
8
8
|
/** Load from markdown file */
|
|
9
9
|
load(): Promise<void>;
|
|
10
|
-
/** Add or update: same category + same key → replace */
|
|
10
|
+
/** Add or update: same category + same key → replace. Rejects unknown categories. */
|
|
11
11
|
add(newFact: KnowledgeFact): void;
|
|
12
12
|
/** Delete by key (optionally scoped to category) */
|
|
13
13
|
delete(key: string, category?: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-memory.d.ts","sourceRoot":"","sources":["../../src/knowledge/auto-memory.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auto-memory.d.ts","sourceRoot":"","sources":["../../src/knowledge/auto-memory.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAqB,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAwBzE,cAAM,UAAU;IACd,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,QAAQ,CAAQ;IACxB,uDAAuD;IACvD,OAAO,CAAC,SAAS,CAAmC;gBAExC,QAAQ,EAAE,MAAM;IAI5B,8BAA8B;IACxB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,qFAAqF;IACrF,GAAG,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAuBjC,oDAAoD;IACpD,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAK5C,+CAA+C;IAC/C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI/D,wCAAwC;IACxC,KAAK,CAAC,UAAU,GAAE,MAAW,GAAG,IAAI;IAOpC,oBAAoB;IACpB,MAAM,IAAI,aAAa,EAAE;IAIzB,qEAAqE;IACrE,gBAAgB,IAAI,MAAM;IAS1B,mCAAmC;IACnC,OAAO,CAAC,SAAS;IAsBjB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAInB,mBAAmB;YACL,IAAI;CAQnB;AA6CD,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,CAcrE;AAED,+DAA+D;AAC/D,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAMlD;AAED,OAAO,EAAE,UAAU,EAAE,CAAA"}
|
|
@@ -1,8 +1,24 @@
|
|
|
1
1
|
// @x-code-cli/core — AutoMemory class (key-based CRUD + conflict detection + TTL eviction)
|
|
2
2
|
import fs from 'node:fs/promises';
|
|
3
|
-
import os from 'node:os';
|
|
4
3
|
import path from 'node:path';
|
|
4
|
+
import { GLOBAL_XCODE_DIR, XCODE_DIR } from '../utils.js';
|
|
5
5
|
const MAX_LOAD_LINES = 200;
|
|
6
|
+
/** Whitelist of valid categories — keep in sync with `KnowledgeCategory` in types/index.ts.
|
|
7
|
+
* Anything outside this set is rejected at both write time and parse time so legacy
|
|
8
|
+
* entries written by older schema-less versions (`context`, `tech-stack`, `commands`, …)
|
|
9
|
+
* don't silently persist across sessions. */
|
|
10
|
+
const VALID_CATEGORIES = new Set(['user', 'feedback', 'project', 'reference']);
|
|
11
|
+
function isValidCategory(c) {
|
|
12
|
+
return VALID_CATEGORIES.has(c);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Collapse newlines and trim whitespace — keeps the serialized line-per-fact
|
|
16
|
+
* invariant intact even if a caller passes multi-line content. Returns '' for
|
|
17
|
+
* falsy input so callers don't have to null-check.
|
|
18
|
+
*/
|
|
19
|
+
function sanitizeLine(s) {
|
|
20
|
+
return s.replace(/\s+/g, ' ').trim();
|
|
21
|
+
}
|
|
6
22
|
class AutoMemory {
|
|
7
23
|
facts = [];
|
|
8
24
|
filePath;
|
|
@@ -21,14 +37,25 @@ class AutoMemory {
|
|
|
21
37
|
this.facts = [];
|
|
22
38
|
}
|
|
23
39
|
}
|
|
24
|
-
/** Add or update: same category + same key → replace */
|
|
40
|
+
/** Add or update: same category + same key → replace. Rejects unknown categories. */
|
|
25
41
|
add(newFact) {
|
|
26
|
-
|
|
42
|
+
if (!isValidCategory(newFact.category)) {
|
|
43
|
+
// Defense in depth: the tool schema should have caught this, but if a
|
|
44
|
+
// caller bypasses it we'd rather drop the write than pollute the file.
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
// Sanitize so embedded newlines can't break the markdown line format.
|
|
48
|
+
const fact = {
|
|
49
|
+
...newFact,
|
|
50
|
+
key: sanitizeLine(newFact.key),
|
|
51
|
+
fact: sanitizeLine(newFact.fact),
|
|
52
|
+
};
|
|
53
|
+
const conflictIndex = this.facts.findIndex((existing) => existing.category === fact.category && existing.key === fact.key);
|
|
27
54
|
if (conflictIndex >= 0) {
|
|
28
|
-
this.facts[conflictIndex] =
|
|
55
|
+
this.facts[conflictIndex] = fact;
|
|
29
56
|
}
|
|
30
57
|
else {
|
|
31
|
-
this.facts.push(
|
|
58
|
+
this.facts.push(fact);
|
|
32
59
|
}
|
|
33
60
|
this.enqueueSave();
|
|
34
61
|
}
|
|
@@ -100,7 +127,9 @@ class AutoMemory {
|
|
|
100
127
|
}
|
|
101
128
|
}
|
|
102
129
|
}
|
|
103
|
-
/** Parse markdown memory file back to facts
|
|
130
|
+
/** Parse markdown memory file back to facts. Drops entries under unknown
|
|
131
|
+
* categories so legacy sections (`context`, `tech-stack`, `commands`, …) get
|
|
132
|
+
* dropped on next save instead of being re-serialized. */
|
|
104
133
|
function parseMemoryFile(content) {
|
|
105
134
|
const facts = [];
|
|
106
135
|
let currentCategory = '';
|
|
@@ -111,7 +140,7 @@ function parseMemoryFile(content) {
|
|
|
111
140
|
continue;
|
|
112
141
|
}
|
|
113
142
|
const factMatch = line.match(/^- \[(\d{4}-\d{2}-\d{2})\] (.+?):\s*(.+)$/);
|
|
114
|
-
if (factMatch && currentCategory) {
|
|
143
|
+
if (factMatch && isValidCategory(currentCategory)) {
|
|
115
144
|
facts.push({
|
|
116
145
|
date: factMatch[1],
|
|
117
146
|
key: factMatch[2].trim(),
|
|
@@ -123,21 +152,31 @@ function parseMemoryFile(content) {
|
|
|
123
152
|
return facts;
|
|
124
153
|
}
|
|
125
154
|
// ─── Singleton instances ───
|
|
126
|
-
|
|
155
|
+
//
|
|
156
|
+
// Project memory is keyed by cwd so that if the process ever changes its
|
|
157
|
+
// working directory (e.g. embedding in a daemon or test harness), we get a
|
|
158
|
+
// fresh instance bound to the right file rather than silently reusing the
|
|
159
|
+
// stale one. Global memory is a true singleton — its path is fixed by
|
|
160
|
+
// GLOBAL_XCODE_DIR.
|
|
161
|
+
const projectMemories = new Map();
|
|
127
162
|
let globalMemory = null;
|
|
163
|
+
function projectMemoryPath(cwd) {
|
|
164
|
+
return path.join(cwd, XCODE_DIR, 'memory', 'auto.md');
|
|
165
|
+
}
|
|
128
166
|
export function getAutoMemory(scope) {
|
|
129
167
|
if (scope === 'project') {
|
|
130
|
-
|
|
131
|
-
|
|
168
|
+
const filePath = projectMemoryPath(process.cwd());
|
|
169
|
+
let mem = projectMemories.get(filePath);
|
|
170
|
+
if (!mem) {
|
|
171
|
+
mem = new AutoMemory(filePath);
|
|
172
|
+
projectMemories.set(filePath, mem);
|
|
132
173
|
}
|
|
133
|
-
return
|
|
174
|
+
return mem;
|
|
134
175
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
globalMemory = new AutoMemory(path.join(os.homedir(), '.xcode', 'memory', 'auto.md'));
|
|
138
|
-
}
|
|
139
|
-
return globalMemory;
|
|
176
|
+
if (!globalMemory) {
|
|
177
|
+
globalMemory = new AutoMemory(path.join(GLOBAL_XCODE_DIR, 'memory', 'auto.md'));
|
|
140
178
|
}
|
|
179
|
+
return globalMemory;
|
|
141
180
|
}
|
|
142
181
|
/** Initialize memories (load from disk + evict old entries) */
|
|
143
182
|
export async function initMemories() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-memory.js","sourceRoot":"","sources":["../../src/knowledge/auto-memory.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACjC,OAAO,
|
|
1
|
+
{"version":3,"file":"auto-memory.js","sourceRoot":"","sources":["../../src/knowledge/auto-memory.ts"],"names":[],"mappings":"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"}
|
package/dist/knowledge/init.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
interface InitResult {
|
|
2
|
-
detectedFacts: string[];
|
|
3
2
|
createdFiles: string[];
|
|
4
3
|
}
|
|
5
|
-
/** Initialize .x-code/
|
|
4
|
+
/** Initialize .x-code/ directory structure and seed AGENTS.md at the project root */
|
|
6
5
|
export declare function initProject(cwd?: string): Promise<InitResult>;
|
|
7
6
|
export {};
|
|
8
7
|
//# sourceMappingURL=init.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/knowledge/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/knowledge/init.ts"],"names":[],"mappings":"AAoBA,UAAU,UAAU;IAClB,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,qFAAqF;AACrF,wBAAsB,WAAW,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,UAAU,CAAC,CAoClF"}
|
package/dist/knowledge/init.js
CHANGED
|
@@ -1,19 +1,35 @@
|
|
|
1
1
|
// @x-code-cli/core — Project initialization (xc init / /init)
|
|
2
|
+
//
|
|
3
|
+
// Creates the .x-code/ directory structure (for CLI internal state only) and
|
|
4
|
+
// seeds an AGENTS.md template at the project root for the user to fill in.
|
|
5
|
+
//
|
|
6
|
+
// AGENTS.md is the industry-convergent convention (Codex, OpenCode, etc.) for
|
|
7
|
+
// "user-authored project context the agent should read every session". Placing
|
|
8
|
+
// it at the repo root — not in a hidden directory — matches how Claude Code,
|
|
9
|
+
// Codex, and OpenCode all treat this kind of file: as a first-class,
|
|
10
|
+
// discoverable, user-maintained document, same category as README.md.
|
|
11
|
+
//
|
|
12
|
+
// We do NOT scan manifest files (package.json, Cargo.toml, etc.) to infer tech
|
|
13
|
+
// stack — that biases the CLI toward a specific ecosystem. Language and
|
|
14
|
+
// framework discovery is left to the agent's own exploration; AGENTS.md
|
|
15
|
+
// captures whatever the user (or a future AI-driven /init) chooses to record.
|
|
2
16
|
import fs from 'node:fs/promises';
|
|
3
17
|
import path from 'node:path';
|
|
4
18
|
import { XCODE_DIR, fileExists } from '../utils.js';
|
|
5
|
-
|
|
6
|
-
import { scanProject } from './hooks.js';
|
|
7
|
-
/** Initialize .x-code/ project structure and generate knowledge from project analysis */
|
|
19
|
+
/** Initialize .x-code/ directory structure and seed AGENTS.md at the project root */
|
|
8
20
|
export async function initProject(cwd = process.cwd()) {
|
|
9
|
-
const xDir = path.join(cwd, XCODE_DIR);
|
|
10
|
-
const detectedFacts = [];
|
|
11
21
|
const createdFiles = [];
|
|
12
|
-
//
|
|
22
|
+
// AGENTS.md at the project root — the user-facing project spec.
|
|
23
|
+
const agentsPath = path.join(cwd, 'AGENTS.md');
|
|
24
|
+
if (!(await fileExists(agentsPath))) {
|
|
25
|
+
await fs.writeFile(agentsPath, AGENTS_TEMPLATE, 'utf-8');
|
|
26
|
+
createdFiles.push('AGENTS.md');
|
|
27
|
+
}
|
|
28
|
+
// .x-code/ directory — CLI internal state only (memory, sessions, plans, local overrides).
|
|
29
|
+
const xDir = path.join(cwd, XCODE_DIR);
|
|
13
30
|
const dirs = [
|
|
14
31
|
xDir,
|
|
15
32
|
path.join(xDir, 'memory'),
|
|
16
|
-
path.join(xDir, 'rules'),
|
|
17
33
|
path.join(xDir, 'sessions'),
|
|
18
34
|
path.join(xDir, 'plans'),
|
|
19
35
|
path.join(xDir, 'local'),
|
|
@@ -21,78 +37,76 @@ export async function initProject(cwd = process.cwd()) {
|
|
|
21
37
|
for (const dir of dirs) {
|
|
22
38
|
await fs.mkdir(dir, { recursive: true });
|
|
23
39
|
}
|
|
24
|
-
// Scan project and populate auto memory
|
|
25
|
-
await scanProject(cwd);
|
|
26
|
-
const memory = getAutoMemory('project');
|
|
27
|
-
const facts = memory.getAll();
|
|
28
|
-
for (const fact of facts) {
|
|
29
|
-
detectedFacts.push(`${fact.key}: ${fact.fact}`);
|
|
30
|
-
}
|
|
31
|
-
// Generate knowledge.md
|
|
32
|
-
const knowledgePath = path.join(xDir, 'knowledge.md');
|
|
33
|
-
const knowledgeExists = await fileExists(knowledgePath);
|
|
34
|
-
if (!knowledgeExists) {
|
|
35
|
-
const knowledgeContent = generateKnowledgeMd(facts.map((f) => ({ key: f.key, fact: f.fact, category: f.category })));
|
|
36
|
-
await fs.writeFile(knowledgePath, knowledgeContent, 'utf-8');
|
|
37
|
-
createdFiles.push('.x-code/knowledge.md');
|
|
38
|
-
}
|
|
39
|
-
// Create .x-code/local/.gitignore if not exists
|
|
40
40
|
const localGitignore = path.join(xDir, 'local', '.gitignore');
|
|
41
41
|
if (!(await fileExists(localGitignore))) {
|
|
42
42
|
await fs.writeFile(localGitignore, '*\n', 'utf-8');
|
|
43
43
|
createdFiles.push('.x-code/local/.gitignore');
|
|
44
44
|
}
|
|
45
|
-
// Create .x-code/local/preferences.md template if not exists
|
|
46
45
|
const prefsPath = path.join(xDir, 'local', 'preferences.md');
|
|
47
46
|
if (!(await fileExists(prefsPath))) {
|
|
48
|
-
await fs.writeFile(prefsPath,
|
|
47
|
+
await fs.writeFile(prefsPath, PREFERENCES_TEMPLATE, 'utf-8');
|
|
49
48
|
createdFiles.push('.x-code/local/preferences.md');
|
|
50
49
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
await fs.writeFile(rulesReadme, `# Rules
|
|
50
|
+
return { createdFiles };
|
|
51
|
+
}
|
|
52
|
+
const AGENTS_TEMPLATE = `# AGENTS.md
|
|
55
53
|
|
|
56
|
-
|
|
54
|
+
<!--
|
|
55
|
+
This file is loaded into the agent's context at the start of every session.
|
|
56
|
+
Keep it concise — the agent reads it every turn.
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
description: "..." # Listed for agent to request on demand
|
|
63
|
-
---
|
|
64
|
-
\`\`\`
|
|
58
|
+
In a monorepo, package-level AGENTS.md files (e.g. packages/web/AGENTS.md)
|
|
59
|
+
are concatenated after this one, so you can override root-level guidance
|
|
60
|
+
with more specific context in sub-packages.
|
|
61
|
+
-->
|
|
65
62
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
63
|
+
## Overview
|
|
64
|
+
|
|
65
|
+
<!-- One or two sentences: what does this project do? Who uses it? -->
|
|
66
|
+
|
|
67
|
+
## Tech Stack
|
|
68
|
+
|
|
69
|
+
<!--
|
|
70
|
+
Language, frameworks, key libraries. Example:
|
|
71
|
+
- Language: Rust 1.75 (2021 edition)
|
|
72
|
+
- Build: cargo
|
|
73
|
+
- Test: cargo test, integration tests under tests/
|
|
74
|
+
-->
|
|
75
|
+
|
|
76
|
+
## Commands
|
|
77
|
+
|
|
78
|
+
<!--
|
|
79
|
+
Common commands the agent should prefer. Example:
|
|
80
|
+
- Build: make build
|
|
81
|
+
- Test: pytest tests/
|
|
82
|
+
- Lint: ruff check .
|
|
83
|
+
- Run locally: docker compose up
|
|
84
|
+
-->
|
|
85
|
+
|
|
86
|
+
## Conventions
|
|
87
|
+
|
|
88
|
+
<!--
|
|
89
|
+
Project-specific conventions that aren't obvious from the code. Example:
|
|
90
|
+
- All public APIs must have doctests
|
|
91
|
+
- Error types live in errors.rs, never inline
|
|
92
|
+
- Database migrations are numbered, never renamed
|
|
93
|
+
-->
|
|
94
|
+
|
|
95
|
+
## Business Context
|
|
96
|
+
|
|
97
|
+
<!--
|
|
98
|
+
Domain knowledge, non-obvious constraints, key stakeholders.
|
|
99
|
+
What would a new contributor spend their first week figuring out?
|
|
100
|
+
-->
|
|
101
|
+
`;
|
|
102
|
+
const PREFERENCES_TEMPLATE = `# Personal Preferences
|
|
103
|
+
|
|
104
|
+
<!--
|
|
105
|
+
Your personal preferences for this project. This file is gitignored.
|
|
106
|
+
Example:
|
|
107
|
+
- Reply in Chinese
|
|
108
|
+
- Prefer terse commit messages
|
|
109
|
+
- Don't run the test suite unless I ask
|
|
110
|
+
-->
|
|
111
|
+
`;
|
|
98
112
|
//# sourceMappingURL=init.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/knowledge/init.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/knowledge/init.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,6EAA6E;AAC7E,qEAAqE;AACrE,sEAAsE;AACtE,EAAE;AACF,+EAA+E;AAC/E,wEAAwE;AACxE,wEAAwE;AACxE,8EAA8E;AAC9E,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACjC,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAMnD,qFAAqF;AACrF,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAC3D,MAAM,YAAY,GAAa,EAAE,CAAA;IAEjC,gEAAgE;IAChE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAA;IAC9C,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;QACpC,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,eAAe,EAAE,OAAO,CAAC,CAAA;QACxD,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAChC,CAAC;IAED,2FAA2F;IAC3F,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;IACtC,MAAM,IAAI,GAAG;QACX,IAAI;QACJ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC;KACzB,CAAA;IACD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1C,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,CAAA;IAC7D,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC;QACxC,MAAM,EAAE,CAAC,SAAS,CAAC,cAAc,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;QAClD,YAAY,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAA;IAC/C,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAA;IAC5D,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QACnC,MAAM,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,oBAAoB,EAAE,OAAO,CAAC,CAAA;QAC5D,YAAY,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAA;IACnD,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,CAAA;AACzB,CAAC;AAED,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDvB,CAAA;AAED,MAAM,oBAAoB,GAAG;;;;;;;;;CAS5B,CAAA"}
|
|
@@ -1,14 +1,5 @@
|
|
|
1
|
-
import type { RuleFile } from '../types/index.js';
|
|
2
|
-
/** Load all rule files from .x-code/rules/ */
|
|
3
|
-
declare function loadRuleFiles(): Promise<RuleFile[]>;
|
|
4
|
-
/** Check if a file path matches any of the glob patterns (simple matching) */
|
|
5
|
-
declare function matchesPath(filePath: string, patterns: string[]): boolean;
|
|
6
1
|
/** Build the full knowledge context for system prompt injection */
|
|
7
2
|
export declare function buildKnowledgeContext(options?: {
|
|
8
|
-
activeFilePaths?: string[];
|
|
9
3
|
sessionContext?: string;
|
|
10
|
-
/** Pre-loaded rules to avoid redundant disk reads */
|
|
11
|
-
rules?: RuleFile[];
|
|
12
4
|
}): Promise<string>;
|
|
13
|
-
export { loadRuleFiles, matchesPath };
|
|
14
5
|
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/knowledge/loader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/knowledge/loader.ts"],"names":[],"mappings":"AAoDA,mEAAmE;AACnE,wBAAsB,qBAAqB,CAAC,OAAO,CAAC,EAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAsClG"}
|