@x-code-cli/core 0.1.0

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.
Files changed (125) hide show
  1. package/dist/agent/loop.d.ts +19 -0
  2. package/dist/agent/loop.d.ts.map +1 -0
  3. package/dist/agent/loop.js +443 -0
  4. package/dist/agent/loop.js.map +1 -0
  5. package/dist/agent/messages.d.ts +8 -0
  6. package/dist/agent/messages.d.ts.map +1 -0
  7. package/dist/agent/messages.js +51 -0
  8. package/dist/agent/messages.js.map +1 -0
  9. package/dist/agent/plan-mode.d.ts +11 -0
  10. package/dist/agent/plan-mode.d.ts.map +1 -0
  11. package/dist/agent/plan-mode.js +37 -0
  12. package/dist/agent/plan-mode.js.map +1 -0
  13. package/dist/agent/pricing.d.ts +9 -0
  14. package/dist/agent/pricing.d.ts.map +1 -0
  15. package/dist/agent/pricing.js +47 -0
  16. package/dist/agent/pricing.js.map +1 -0
  17. package/dist/agent/system-prompt.d.ts +9 -0
  18. package/dist/agent/system-prompt.d.ts.map +1 -0
  19. package/dist/agent/system-prompt.js +93 -0
  20. package/dist/agent/system-prompt.js.map +1 -0
  21. package/dist/config/index.d.ts +28 -0
  22. package/dist/config/index.d.ts.map +1 -0
  23. package/dist/config/index.js +88 -0
  24. package/dist/config/index.js.map +1 -0
  25. package/dist/index.d.ts +20 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +24 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/knowledge/auto-memory.d.ts +36 -0
  30. package/dist/knowledge/auto-memory.d.ts.map +1 -0
  31. package/dist/knowledge/auto-memory.js +151 -0
  32. package/dist/knowledge/auto-memory.js.map +1 -0
  33. package/dist/knowledge/hooks.d.ts +3 -0
  34. package/dist/knowledge/hooks.d.ts.map +1 -0
  35. package/dist/knowledge/hooks.js +59 -0
  36. package/dist/knowledge/hooks.js.map +1 -0
  37. package/dist/knowledge/init.d.ts +8 -0
  38. package/dist/knowledge/init.d.ts.map +1 -0
  39. package/dist/knowledge/init.js +98 -0
  40. package/dist/knowledge/init.js.map +1 -0
  41. package/dist/knowledge/loader.d.ts +14 -0
  42. package/dist/knowledge/loader.d.ts.map +1 -0
  43. package/dist/knowledge/loader.js +130 -0
  44. package/dist/knowledge/loader.js.map +1 -0
  45. package/dist/knowledge/session.d.ts +11 -0
  46. package/dist/knowledge/session.d.ts.map +1 -0
  47. package/dist/knowledge/session.js +108 -0
  48. package/dist/knowledge/session.js.map +1 -0
  49. package/dist/permissions/index.d.ts +14 -0
  50. package/dist/permissions/index.d.ts.map +1 -0
  51. package/dist/permissions/index.js +46 -0
  52. package/dist/permissions/index.js.map +1 -0
  53. package/dist/providers/registry.d.ts +2 -0
  54. package/dist/providers/registry.d.ts.map +1 -0
  55. package/dist/providers/registry.js +46 -0
  56. package/dist/providers/registry.js.map +1 -0
  57. package/dist/tools/ask-user.d.ts +8 -0
  58. package/dist/tools/ask-user.d.ts.map +1 -0
  59. package/dist/tools/ask-user.js +19 -0
  60. package/dist/tools/ask-user.js.map +1 -0
  61. package/dist/tools/edit.d.ts +7 -0
  62. package/dist/tools/edit.d.ts.map +1 -0
  63. package/dist/tools/edit.js +14 -0
  64. package/dist/tools/edit.js.map +1 -0
  65. package/dist/tools/enter-plan-mode.d.ts +2 -0
  66. package/dist/tools/enter-plan-mode.d.ts.map +1 -0
  67. package/dist/tools/enter-plan-mode.js +11 -0
  68. package/dist/tools/enter-plan-mode.js.map +1 -0
  69. package/dist/tools/exit-plan-mode.d.ts +2 -0
  70. package/dist/tools/exit-plan-mode.d.ts.map +1 -0
  71. package/dist/tools/exit-plan-mode.js +9 -0
  72. package/dist/tools/exit-plan-mode.js.map +1 -0
  73. package/dist/tools/glob.d.ts +5 -0
  74. package/dist/tools/glob.d.ts.map +1 -0
  75. package/dist/tools/glob.js +28 -0
  76. package/dist/tools/glob.js.map +1 -0
  77. package/dist/tools/grep.d.ts +7 -0
  78. package/dist/tools/grep.d.ts.map +1 -0
  79. package/dist/tools/grep.js +54 -0
  80. package/dist/tools/grep.js.map +1 -0
  81. package/dist/tools/index.d.ts +77 -0
  82. package/dist/tools/index.d.ts.map +1 -0
  83. package/dist/tools/index.js +41 -0
  84. package/dist/tools/index.js.map +1 -0
  85. package/dist/tools/list-dir.d.ts +4 -0
  86. package/dist/tools/list-dir.d.ts.map +1 -0
  87. package/dist/tools/list-dir.js +25 -0
  88. package/dist/tools/list-dir.js.map +1 -0
  89. package/dist/tools/read-file.d.ts +6 -0
  90. package/dist/tools/read-file.d.ts.map +1 -0
  91. package/dist/tools/read-file.js +28 -0
  92. package/dist/tools/read-file.js.map +1 -0
  93. package/dist/tools/save-knowledge.d.ts +8 -0
  94. package/dist/tools/save-knowledge.d.ts.map +1 -0
  95. package/dist/tools/save-knowledge.js +36 -0
  96. package/dist/tools/save-knowledge.js.map +1 -0
  97. package/dist/tools/shell-utils.d.ts +14 -0
  98. package/dist/tools/shell-utils.d.ts.map +1 -0
  99. package/dist/tools/shell-utils.js +111 -0
  100. package/dist/tools/shell-utils.js.map +1 -0
  101. package/dist/tools/shell.d.ts +5 -0
  102. package/dist/tools/shell.d.ts.map +1 -0
  103. package/dist/tools/shell.js +12 -0
  104. package/dist/tools/shell.js.map +1 -0
  105. package/dist/tools/web-fetch.d.ts +5 -0
  106. package/dist/tools/web-fetch.d.ts.map +1 -0
  107. package/dist/tools/web-fetch.js +59 -0
  108. package/dist/tools/web-fetch.js.map +1 -0
  109. package/dist/tools/web-search.d.ts +5 -0
  110. package/dist/tools/web-search.d.ts.map +1 -0
  111. package/dist/tools/web-search.js +27 -0
  112. package/dist/tools/web-search.js.map +1 -0
  113. package/dist/tools/write-file.d.ts +5 -0
  114. package/dist/tools/write-file.d.ts.map +1 -0
  115. package/dist/tools/write-file.js +12 -0
  116. package/dist/tools/write-file.js.map +1 -0
  117. package/dist/types/index.d.ts +108 -0
  118. package/dist/types/index.d.ts.map +1 -0
  119. package/dist/types/index.js +36 -0
  120. package/dist/types/index.js.map +1 -0
  121. package/dist/utils.d.ts +9 -0
  122. package/dist/utils.d.ts.map +1 -0
  123. package/dist/utils.js +34 -0
  124. package/dist/utils.js.map +1 -0
  125. package/package.json +42 -0
@@ -0,0 +1,47 @@
1
+ // @x-code/core — Model pricing table and cost estimation
2
+ const MODEL_PRICING = {
3
+ // ── USD providers ──
4
+ // Anthropic
5
+ 'anthropic:claude-opus-4-6': { input: 15, output: 75, currency: 'USD' },
6
+ 'anthropic:claude-sonnet-4-5': { input: 3, output: 15, currency: 'USD' },
7
+ 'anthropic:claude-haiku-4-5': { input: 0.8, output: 4, currency: 'USD' },
8
+ // OpenAI
9
+ 'openai:gpt-4.1': { input: 2, output: 8, currency: 'USD' },
10
+ 'openai:gpt-4.1-mini': { input: 0.4, output: 1.6, currency: 'USD' },
11
+ 'openai:gpt-4.1-nano': { input: 0.1, output: 0.4, currency: 'USD' },
12
+ 'openai:o3': { input: 2, output: 8, currency: 'USD' },
13
+ 'openai:o4-mini': { input: 1.1, output: 4.4, currency: 'USD' },
14
+ // Google
15
+ 'google:gemini-2.5-pro': { input: 1.25, output: 10, currency: 'USD' },
16
+ 'google:gemini-2.5-flash': { input: 0.15, output: 0.6, currency: 'USD' },
17
+ // xAI
18
+ 'xai:grok-3': { input: 3, output: 15, currency: 'USD' },
19
+ 'xai:grok-3-mini': { input: 0.3, output: 0.5, currency: 'USD' },
20
+ // ── CNY (人民币) providers ──
21
+ // DeepSeek (api.deepseek.com, V3.2 统一定价, 人民币)
22
+ 'deepseek:deepseek-chat': { input: 2, output: 3, currency: 'CNY' },
23
+ 'deepseek:deepseek-reasoner': { input: 2, output: 3, currency: 'CNY' },
24
+ // Alibaba / 阿里云百炼 (dashscope.aliyuncs.com, 中国内地定价)
25
+ 'alibaba:qwen-max': { input: 2.4, output: 9.6, currency: 'CNY' },
26
+ 'alibaba:qwen-plus': { input: 0.8, output: 2, currency: 'CNY' },
27
+ // Zhipu / 智谱 (bigmodel.cn)
28
+ 'zhipu:glm-4-plus': { input: 5, output: 5, currency: 'CNY' },
29
+ // Moonshot / 月之暗面 (platform.moonshot.cn, 人民币)
30
+ 'moonshotai:kimi-k2.5': { input: 4, output: 16, currency: 'CNY' },
31
+ };
32
+ /** Estimate cost from model ID and token counts. Returns cost and currency. */
33
+ export function estimateCost(modelId, inputTokens, outputTokens) {
34
+ const pricing = MODEL_PRICING[modelId];
35
+ if (!pricing)
36
+ return { cost: 0, currency: 'USD' };
37
+ const cost = (inputTokens * pricing.input + outputTokens * pricing.output) / 1_000_000;
38
+ return { cost, currency: pricing.currency };
39
+ }
40
+ /** Format cost string with currency symbol */
41
+ export function formatCost(estimate) {
42
+ if (estimate.cost <= 0)
43
+ return '';
44
+ const symbol = estimate.currency === 'CNY' ? '¥' : '$';
45
+ return `${symbol}${estimate.cost.toFixed(4)}`;
46
+ }
47
+ //# sourceMappingURL=pricing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing.js","sourceRoot":"","sources":["../../src/agent/pricing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /** Plan mode overlay prompt — injected when plan mode is active */
2
+ export declare const PLAN_MODE_PROMPT = "\nPlan mode is active. You MUST NOT make any edits to project code, execute write commands, or make any changes to user files.\nOnly use read-only tools: readFile, glob, grep, listDir, webSearch, webFetch.\nThe ONLY exception: use writeFile to save your plan to .x-code/plans/{plan-id}.md.\nWhen the plan is ready, call exitPlanMode.";
3
+ /** Build the full system prompt with dynamic values and optional knowledge context */
4
+ export declare function buildSystemPrompt(options?: {
5
+ knowledgeContext?: string;
6
+ planMode?: boolean;
7
+ modelId?: string;
8
+ }): string;
9
+ //# sourceMappingURL=system-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/agent/system-prompt.ts"],"names":[],"mappings":"AAyEA,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,kVAIc,CAAA;AAE3C,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE;IAC1C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,GAAG,MAAM,CAiBT"}
@@ -0,0 +1,93 @@
1
+ // @x-code/core — System Prompt management
2
+ import { getShellConfig } from '../tools/shell-utils.js';
3
+ const BASE_SYSTEM_PROMPT = `You are X-Code, an AI coding assistant running in the user's terminal. You are powered by the {model} model.
4
+
5
+ When users ask about your identity, model, or version, you should tell them:
6
+ - You are X-Code CLI, a terminal-based AI coding assistant
7
+ - You are powered by {model}
8
+ - Do NOT fabricate information about your training data cutoff, architecture, or capabilities beyond what is stated here
9
+
10
+ ## Capabilities
11
+ You have access to these tools:
12
+ - readFile: Read file contents with line numbers
13
+ - writeFile: Create or overwrite files
14
+ - edit: Replace specific strings in files (preferred over writeFile for modifications)
15
+ - shell: Execute commands in the current platform's shell
16
+ - glob: Find files by pattern (preferred over shell ls/find)
17
+ - grep: Search file contents by regex (preferred over shell grep)
18
+ - listDir: List directory contents
19
+ - webSearch: Search the web for information
20
+ - webFetch: Fetch and extract content from URLs
21
+ - askUser: Ask the user clarifying questions with choices
22
+ - saveKnowledge: Save project/user knowledge facts to persistent memory
23
+ - enterPlanMode: Enter plan mode to explore codebase and design implementation plan before coding
24
+ - exitPlanMode: Signal that plan is complete and ready for user review
25
+
26
+ ## Planning
27
+ For non-trivial tasks (new features, multi-file changes, architectural decisions, unclear requirements), call enterPlanMode BEFORE writing any code. This lets the user review your approach first. Skip planning for simple fixes, single-line changes, or when the user gives very specific instructions.
28
+
29
+ ## Response Format
30
+ - IMPORTANT: You MUST NOT use any emojis, icons, or special Unicode symbols (such as ✅❌📦🔧🔍📋🤔💡⚡🚀 etc.) in your responses, plans, or generated code. Use plain text markers like numbers, dashes, or asterisks instead. This is a strict requirement.
31
+ - Reply in the same language the user uses.
32
+
33
+ ## Rules
34
+
35
+ ### File Operations
36
+ - ALWAYS read a file before modifying it
37
+ - Prefer edit (string replacement) over writeFile when modifying existing files — it's safer and costs fewer tokens
38
+ - Prefer editing existing files over creating new files — avoid file bloat
39
+ - Use absolute paths for all file operations
40
+ - Do NOT create files unless absolutely necessary for the task
41
+ - Do NOT add comments, docstrings, or type annotations to code you didn't change
42
+
43
+ ### Command Execution
44
+ - Generate commands compatible with the current shell ({shell})
45
+ - Use platform-appropriate path separators and syntax
46
+ - Do NOT execute destructive commands (rm -rf, format, drop table) unless explicitly asked
47
+ - Prefer dedicated tools over shell commands: use glob instead of find/ls, grep instead of grep/rg, readFile instead of cat
48
+
49
+ ### Interaction
50
+ - When uncertain between multiple approaches, use askUser to let the user choose
51
+ - Keep responses concise — focus on what changed and why
52
+ - Use markdown formatting with language-tagged code blocks
53
+
54
+ ### Security
55
+ - NEVER output API keys, passwords, or secrets in responses
56
+ - NEVER generate code with known security vulnerabilities (injection, XSS, etc.)
57
+ - NEVER commit .env files or credential files
58
+ - If you notice insecure code, fix it or warn the user
59
+
60
+ ## Auto Memory Guidelines
61
+ When you discover the following, call saveKnowledge to record:
62
+ - User explicitly tells you about tech stack changes (frameworks, toolchain, language versions)
63
+ - User expresses preferences (code style, reply language, work habits)
64
+ - You discover project conventions during task execution (naming rules, dir structure, test strategy)
65
+ - You find existing knowledge contradicts the current codebase (delete outdated knowledge)
66
+ Do NOT create memories for temporary, one-off information.
67
+
68
+ ## Environment
69
+ - Platform: {platform}
70
+ - Shell: {shell}
71
+ - Working Directory: {cwd}`;
72
+ /** Plan mode overlay prompt — injected when plan mode is active */
73
+ export const PLAN_MODE_PROMPT = `
74
+ Plan mode is active. You MUST NOT make any edits to project code, execute write commands, or make any changes to user files.
75
+ Only use read-only tools: readFile, glob, grep, listDir, webSearch, webFetch.
76
+ The ONLY exception: use writeFile to save your plan to .x-code/plans/{plan-id}.md.
77
+ When the plan is ready, call exitPlanMode.`;
78
+ /** Build the full system prompt with dynamic values and optional knowledge context */
79
+ export function buildSystemPrompt(options) {
80
+ const shellConfig = getShellConfig();
81
+ let prompt = BASE_SYSTEM_PROMPT.replace(/\{platform\}/g, process.platform)
82
+ .replace(/\{shell\}/g, shellConfig.type)
83
+ .replace(/\{cwd\}/g, process.cwd())
84
+ .replace(/\{model\}/g, options?.modelId ?? 'unknown');
85
+ if (options?.planMode) {
86
+ prompt += '\n' + PLAN_MODE_PROMPT;
87
+ }
88
+ if (options?.knowledgeContext) {
89
+ prompt += '\n\n' + options.knowledgeContext;
90
+ }
91
+ return prompt;
92
+ }
93
+ //# sourceMappingURL=system-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/agent/system-prompt.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAExD,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAoEA,CAAA;AAE3B,mEAAmE;AACnE,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;2CAIW,CAAA;AAE3C,sFAAsF;AACtF,MAAM,UAAU,iBAAiB,CAAC,OAIjC;IACC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IAEpC,IAAI,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,eAAe,EAAE,OAAO,CAAC,QAAQ,CAAC;SACvE,OAAO,CAAC,YAAY,EAAE,WAAW,CAAC,IAAI,CAAC;SACvC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;SAClC,OAAO,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,IAAI,SAAS,CAAC,CAAA;IAEvD,IAAI,OAAO,EAAE,QAAQ,EAAE,CAAC;QACtB,MAAM,IAAI,IAAI,GAAG,gBAAgB,CAAA;IACnC,CAAC;IAED,IAAI,OAAO,EAAE,gBAAgB,EAAE,CAAC;QAC9B,MAAM,IAAI,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAA;IAC7C,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { AppConfig } from '../types/index.js';
2
+ declare const CONFIG_DIR: string;
3
+ declare const CONFIG_FILE: string;
4
+ /** Load config from ~/.xcode/config.json (model preference only) */
5
+ export declare function loadConfig(): Promise<AppConfig>;
6
+ /** Get the env var name for a provider */
7
+ export declare function getEnvVarName(provider: string): string | undefined;
8
+ /** Check which providers have API keys configured (env vars only) */
9
+ export declare function getAvailableProviders(): string[];
10
+ /** Resolve model ID from alias/full ID, with smart default fallback */
11
+ export declare function resolveModelId(input: string | undefined, config: AppConfig): string | null;
12
+ /** Build provider options with API keys from env vars */
13
+ export declare function getProviderOptions(): {
14
+ anthropic: string | undefined;
15
+ openai: string | undefined;
16
+ google: string | undefined;
17
+ xai: string | undefined;
18
+ deepseek: string | undefined;
19
+ alibaba: string | undefined;
20
+ zhipu: string | undefined;
21
+ moonshotai: string | undefined;
22
+ custom: {
23
+ apiKey: string | undefined;
24
+ baseURL: string | undefined;
25
+ };
26
+ };
27
+ export { CONFIG_DIR, CONFIG_FILE };
28
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAGlD,QAAA,MAAM,UAAU,QAAoC,CAAA;AACpD,QAAA,MAAM,WAAW,QAAuC,CAAA;AAExD,oEAAoE;AACpE,wBAAsB,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,CAOrD;AAoBD,0CAA0C;AAC1C,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAElE;AAED,qEAAqE;AACrE,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAMhD;AAED,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAwB1F;AAED,yDAAyD;AACzD,wBAAgB,kBAAkB;;;;;;;;;;;;;EAejC;AAED,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,CAAA"}
@@ -0,0 +1,88 @@
1
+ // @x-code/core — Configuration loading (env vars for API keys, config file for model preference)
2
+ import fs from 'node:fs/promises';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { MODEL_ALIASES, PROVIDER_DETECTION_ORDER } from '../types/index.js';
6
+ const CONFIG_DIR = path.join(os.homedir(), '.xcode');
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
+ }
18
+ /** Provider → environment variable mapping */
19
+ const ENV_MAP = {
20
+ anthropic: 'ANTHROPIC_API_KEY',
21
+ openai: 'OPENAI_API_KEY',
22
+ google: 'GOOGLE_GENERATIVE_AI_API_KEY',
23
+ xai: 'XAI_API_KEY',
24
+ deepseek: 'DEEPSEEK_API_KEY',
25
+ alibaba: 'ALIBABA_API_KEY',
26
+ zhipu: 'ZHIPU_API_KEY',
27
+ moonshotai: 'MOONSHOT_API_KEY',
28
+ };
29
+ /** Get API key for a provider — reads from environment variables only */
30
+ function getApiKey(provider) {
31
+ const envKey = ENV_MAP[provider];
32
+ return envKey ? process.env[envKey] : undefined;
33
+ }
34
+ /** Get the env var name for a provider */
35
+ export function getEnvVarName(provider) {
36
+ return ENV_MAP[provider];
37
+ }
38
+ /** Check which providers have API keys configured (env vars only) */
39
+ export function getAvailableProviders() {
40
+ const providers = Object.keys(ENV_MAP).filter((p) => getApiKey(p));
41
+ if (process.env.OPENAI_COMPATIBLE_API_KEY && process.env.OPENAI_COMPATIBLE_BASE_URL) {
42
+ providers.push('custom');
43
+ }
44
+ return providers;
45
+ }
46
+ /** Resolve model ID from alias/full ID, with smart default fallback */
47
+ export function resolveModelId(input, config) {
48
+ // 1. Explicit user choice: --model flag or X_CODE_MODEL env var
49
+ const explicit = input ?? process.env.X_CODE_MODEL;
50
+ if (explicit) {
51
+ // Always return explicit choice (will show clear error later if key missing)
52
+ return MODEL_ALIASES[explicit] ?? explicit;
53
+ }
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
+ for (const { envKey, defaultModel } of PROVIDER_DETECTION_ORDER) {
65
+ if (process.env[envKey])
66
+ return defaultModel;
67
+ }
68
+ return null; // No provider configured
69
+ }
70
+ /** Build provider options with API keys from env vars */
71
+ export function getProviderOptions() {
72
+ return {
73
+ anthropic: getApiKey('anthropic'),
74
+ openai: getApiKey('openai'),
75
+ google: getApiKey('google'),
76
+ xai: getApiKey('xai'),
77
+ deepseek: getApiKey('deepseek'),
78
+ alibaba: getApiKey('alibaba'),
79
+ zhipu: getApiKey('zhipu'),
80
+ moonshotai: getApiKey('moonshotai'),
81
+ custom: {
82
+ apiKey: process.env.OPENAI_COMPATIBLE_API_KEY,
83
+ baseURL: process.env.OPENAI_COMPATIBLE_BASE_URL,
84
+ },
85
+ };
86
+ }
87
+ export { CONFIG_DIR, CONFIG_FILE };
88
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export declare const VERSION = "0.1.0";
2
+ export type { PermissionLevel, TokenUsage, DisplayMessage, DisplayToolCall, AgentCallbacks, AgentOptions, AppConfig, KnowledgeFact, SessionSummary, RuleFrontmatter, RuleFile, ModelMessage, LanguageModel, } from './types/index.js';
3
+ export { MODEL_ALIASES, PROVIDER_DETECTION_ORDER, PROVIDER_KEY_URLS } from './types/index.js';
4
+ export { loadConfig, resolveModelId, getAvailableProviders, getEnvVarName, CONFIG_DIR, CONFIG_FILE, } from './config/index.js';
5
+ export { createModelRegistry } from './providers/registry.js';
6
+ export { agentLoop, saveSession, compressMessages } from './agent/loop.js';
7
+ export type { LoopState } from './agent/loop.js';
8
+ export { buildSystemPrompt } from './agent/system-prompt.js';
9
+ export { estimateTokens } from './agent/messages.js';
10
+ export { estimateCost, formatCost } from './agent/pricing.js';
11
+ export type { CostEstimate } from './agent/pricing.js';
12
+ export { toolRegistry, truncateToolResult } from './tools/index.js';
13
+ export { getShellConfig } from './tools/shell-utils.js';
14
+ export { checkPermission, getPermissionLevel } from './permissions/index.js';
15
+ export { buildKnowledgeContext } from './knowledge/loader.js';
16
+ export { getAutoMemory, initMemories } from './knowledge/auto-memory.js';
17
+ export { loadLatestSession, saveSessionSummary, formatSessionForPrompt } from './knowledge/session.js';
18
+ export { scanProject } from './knowledge/hooks.js';
19
+ export { initProject } from './knowledge/init.js';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,UAAU,CAAA;AAG9B,YAAY,EACV,eAAe,EACf,UAAU,EACV,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,EACZ,SAAS,EACT,aAAa,EACb,cAAc,EACd,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,aAAa,GACd,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAG7F,OAAO,EACL,UAAU,EACV,cAAc,EACd,qBAAqB,EACrB,aAAa,EACb,UAAU,EACV,WAAW,GACZ,MAAM,mBAAmB,CAAA;AAG1B,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,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC7D,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAGtD,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,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,sBAAsB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ // @x-code/core — Public API exports
2
+ export const VERSION = '0.1.0';
3
+ export { MODEL_ALIASES, PROVIDER_DETECTION_ORDER, PROVIDER_KEY_URLS } from './types/index.js';
4
+ // Config
5
+ export { loadConfig, resolveModelId, getAvailableProviders, getEnvVarName, CONFIG_DIR, CONFIG_FILE, } from './config/index.js';
6
+ // Provider Registry
7
+ export { createModelRegistry } from './providers/registry.js';
8
+ // Agent
9
+ export { agentLoop, saveSession, compressMessages } from './agent/loop.js';
10
+ export { buildSystemPrompt } from './agent/system-prompt.js';
11
+ export { estimateTokens } from './agent/messages.js';
12
+ export { estimateCost, formatCost } from './agent/pricing.js';
13
+ // Tools
14
+ export { toolRegistry, truncateToolResult } from './tools/index.js';
15
+ export { getShellConfig } from './tools/shell-utils.js';
16
+ // Permissions
17
+ export { checkPermission, getPermissionLevel } from './permissions/index.js';
18
+ // Knowledge
19
+ export { buildKnowledgeContext } from './knowledge/loader.js';
20
+ export { getAutoMemory, initMemories } from './knowledge/auto-memory.js';
21
+ export { loadLatestSession, saveSessionSummary, formatSessionForPrompt } from './knowledge/session.js';
22
+ export { scanProject } from './knowledge/hooks.js';
23
+ export { initProject } from './knowledge/init.js';
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AAEpC,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAA;AAmB9B,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAE7F,SAAS;AACT,OAAO,EACL,UAAU,EACV,cAAc,EACd,qBAAqB,EACrB,aAAa,EACb,UAAU,EACV,WAAW,GACZ,MAAM,mBAAmB,CAAA;AAE1B,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,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAG7D,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,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,sBAAsB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA"}
@@ -0,0 +1,36 @@
1
+ import type { KnowledgeFact } from '../types/index.js';
2
+ declare class AutoMemory {
3
+ private facts;
4
+ private filePath;
5
+ /** Queued save promise – prevents concurrent writes */
6
+ private saveQueue;
7
+ constructor(filePath: string);
8
+ /** Load from markdown file */
9
+ load(): Promise<void>;
10
+ /** Add or update: same category + same key → replace */
11
+ add(newFact: KnowledgeFact): void;
12
+ /** Delete by key (optionally scoped to category) */
13
+ delete(key: string, category?: string): void;
14
+ /** Find a fact by key and optional category */
15
+ find(key: string, category?: string): KnowledgeFact | undefined;
16
+ /** Evict facts older than maxAgeDays */
17
+ evict(maxAgeDays?: number): void;
18
+ /** Get all facts */
19
+ getAll(): KnowledgeFact[];
20
+ /** Get content for system prompt injection (first MAX_LOAD_LINES) */
21
+ getPromptContent(): string;
22
+ /** Serialize to markdown format */
23
+ private serialize;
24
+ /**
25
+ * Enqueue a save so that concurrent add/delete calls are serialized.
26
+ * Each save waits for the previous one to finish before writing.
27
+ */
28
+ private enqueueSave;
29
+ /** Save to file */
30
+ private save;
31
+ }
32
+ export declare function getAutoMemory(scope: 'project' | 'global'): AutoMemory;
33
+ /** Initialize memories (load from disk + evict old entries) */
34
+ export declare function initMemories(): Promise<void>;
35
+ export { AutoMemory };
36
+ //# sourceMappingURL=auto-memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-memory.d.ts","sourceRoot":"","sources":["../../src/knowledge/auto-memory.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAItD,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,wDAAwD;IACxD,GAAG,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAYjC,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;AAiCD,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,CAYrE;AAED,+DAA+D;AAC/D,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAMlD;AAED,OAAO,EAAE,UAAU,EAAE,CAAA"}
@@ -0,0 +1,151 @@
1
+ // @x-code/core — AutoMemory class (key-based CRUD + conflict detection + TTL eviction)
2
+ import fs from 'node:fs/promises';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ const MAX_LOAD_LINES = 200;
6
+ class AutoMemory {
7
+ facts = [];
8
+ filePath;
9
+ /** Queued save promise – prevents concurrent writes */
10
+ saveQueue = Promise.resolve();
11
+ constructor(filePath) {
12
+ this.filePath = filePath;
13
+ }
14
+ /** Load from markdown file */
15
+ async load() {
16
+ try {
17
+ const content = await fs.readFile(this.filePath, 'utf-8');
18
+ this.facts = parseMemoryFile(content);
19
+ }
20
+ catch {
21
+ this.facts = [];
22
+ }
23
+ }
24
+ /** Add or update: same category + same key → replace */
25
+ add(newFact) {
26
+ const conflictIndex = this.facts.findIndex((existing) => existing.category === newFact.category && existing.key === newFact.key);
27
+ if (conflictIndex >= 0) {
28
+ this.facts[conflictIndex] = newFact;
29
+ }
30
+ else {
31
+ this.facts.push(newFact);
32
+ }
33
+ this.enqueueSave();
34
+ }
35
+ /** Delete by key (optionally scoped to category) */
36
+ delete(key, category) {
37
+ this.facts = this.facts.filter((f) => !(f.key === key && (!category || f.category === category)));
38
+ this.enqueueSave();
39
+ }
40
+ /** Find a fact by key and optional category */
41
+ find(key, category) {
42
+ return this.facts.find((f) => f.key === key && (!category || f.category === category));
43
+ }
44
+ /** Evict facts older than maxAgeDays */
45
+ evict(maxAgeDays = 90) {
46
+ const cutoff = Date.now() - maxAgeDays * 86400_000;
47
+ const before = this.facts.length;
48
+ this.facts = this.facts.filter((f) => new Date(f.date).getTime() > cutoff);
49
+ if (this.facts.length < before)
50
+ this.save();
51
+ }
52
+ /** Get all facts */
53
+ getAll() {
54
+ return [...this.facts];
55
+ }
56
+ /** Get content for system prompt injection (first MAX_LOAD_LINES) */
57
+ getPromptContent() {
58
+ const content = this.serialize();
59
+ const lines = content.split('\n');
60
+ if (lines.length > MAX_LOAD_LINES) {
61
+ return lines.slice(0, MAX_LOAD_LINES).join('\n') + '\n... (truncated)';
62
+ }
63
+ return content;
64
+ }
65
+ /** Serialize to markdown format */
66
+ serialize() {
67
+ if (this.facts.length === 0)
68
+ return '';
69
+ const categories = new Map();
70
+ for (const fact of this.facts) {
71
+ const list = categories.get(fact.category) ?? [];
72
+ list.push(fact);
73
+ categories.set(fact.category, list);
74
+ }
75
+ const sections = ['## Auto Memory', ''];
76
+ for (const [category, facts] of categories) {
77
+ sections.push(`### ${category}`);
78
+ for (const f of facts) {
79
+ sections.push(`- [${f.date}] ${f.key}: ${f.fact}`);
80
+ }
81
+ sections.push('');
82
+ }
83
+ return sections.join('\n');
84
+ }
85
+ /**
86
+ * Enqueue a save so that concurrent add/delete calls are serialized.
87
+ * Each save waits for the previous one to finish before writing.
88
+ */
89
+ enqueueSave() {
90
+ this.saveQueue = this.saveQueue.then(() => this.save());
91
+ }
92
+ /** Save to file */
93
+ async save() {
94
+ try {
95
+ await fs.mkdir(path.dirname(this.filePath), { recursive: true });
96
+ await fs.writeFile(this.filePath, this.serialize(), 'utf-8');
97
+ }
98
+ catch {
99
+ // Silently fail — don't crash agent if memory write fails
100
+ }
101
+ }
102
+ }
103
+ /** Parse markdown memory file back to facts */
104
+ function parseMemoryFile(content) {
105
+ const facts = [];
106
+ let currentCategory = '';
107
+ for (const line of content.split('\n')) {
108
+ const categoryMatch = line.match(/^### (.+)$/);
109
+ if (categoryMatch) {
110
+ currentCategory = categoryMatch[1].trim();
111
+ continue;
112
+ }
113
+ const factMatch = line.match(/^- \[(\d{4}-\d{2}-\d{2})\] (.+?):\s*(.+)$/);
114
+ if (factMatch && currentCategory) {
115
+ facts.push({
116
+ date: factMatch[1],
117
+ key: factMatch[2].trim(),
118
+ fact: factMatch[3].trim(),
119
+ category: currentCategory,
120
+ });
121
+ }
122
+ }
123
+ return facts;
124
+ }
125
+ // ─── Singleton instances ───
126
+ let projectMemory = null;
127
+ let globalMemory = null;
128
+ export function getAutoMemory(scope) {
129
+ if (scope === 'project') {
130
+ if (!projectMemory) {
131
+ projectMemory = new AutoMemory(path.join(process.cwd(), '.x-code', 'memory', 'auto.md'));
132
+ }
133
+ return projectMemory;
134
+ }
135
+ else {
136
+ if (!globalMemory) {
137
+ globalMemory = new AutoMemory(path.join(os.homedir(), '.xcode', 'memory', 'auto.md'));
138
+ }
139
+ return globalMemory;
140
+ }
141
+ }
142
+ /** Initialize memories (load from disk + evict old entries) */
143
+ export async function initMemories() {
144
+ const project = getAutoMemory('project');
145
+ const global = getAutoMemory('global');
146
+ await Promise.all([project.load(), global.load()]);
147
+ project.evict(90);
148
+ global.evict(90);
149
+ }
150
+ export { AutoMemory };
151
+ //# sourceMappingURL=auto-memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-memory.js","sourceRoot":"","sources":["../../src/knowledge/auto-memory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Scan project root and populate auto memory with basic facts */
2
+ export declare function scanProject(projectRoot: string): Promise<void>;
3
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/knowledge/hooks.ts"],"names":[],"mappings":"AAUA,kEAAkE;AAClE,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDpE"}
@@ -0,0 +1,59 @@
1
+ // @x-code/core — Startup project scan (reads config files to inject basic context)
2
+ import path from 'node:path';
3
+ import { fileExists, readJsonSafe } from '../utils.js';
4
+ import { getAutoMemory } from './auto-memory.js';
5
+ function today() {
6
+ return new Date().toISOString().slice(0, 10);
7
+ }
8
+ /** Scan project root and populate auto memory with basic facts */
9
+ export async function scanProject(projectRoot) {
10
+ const memory = getAutoMemory('project');
11
+ // Detect package manager from lock files
12
+ if (await fileExists(path.join(projectRoot, 'pnpm-lock.yaml'))) {
13
+ memory.add({ key: 'package-manager', fact: 'pnpm', category: 'tech-stack', date: today() });
14
+ }
15
+ else if (await fileExists(path.join(projectRoot, 'yarn.lock'))) {
16
+ memory.add({ key: 'package-manager', fact: 'yarn', category: 'tech-stack', date: today() });
17
+ }
18
+ else if (await fileExists(path.join(projectRoot, 'package-lock.json'))) {
19
+ memory.add({ key: 'package-manager', fact: 'npm', category: 'tech-stack', date: today() });
20
+ }
21
+ // Read package.json
22
+ const pkg = await readJsonSafe(path.join(projectRoot, 'package.json'));
23
+ if (pkg) {
24
+ const scripts = pkg.scripts;
25
+ if (scripts?.test) {
26
+ memory.add({ key: 'test-command', fact: scripts.test, category: 'commands', date: today() });
27
+ }
28
+ if (scripts?.build) {
29
+ memory.add({ key: 'build-command', fact: scripts.build, category: 'commands', date: today() });
30
+ }
31
+ if (scripts?.lint) {
32
+ memory.add({ key: 'lint-command', fact: scripts.lint, category: 'commands', date: today() });
33
+ }
34
+ const deps = {
35
+ ...pkg.dependencies,
36
+ ...pkg.devDependencies,
37
+ };
38
+ if (deps.react)
39
+ memory.add({ key: 'ui-framework', fact: `React ${deps.react}`, category: 'tech-stack', date: today() });
40
+ if (deps.vitest)
41
+ memory.add({ key: 'test-framework', fact: 'Vitest', category: 'tech-stack', date: today() });
42
+ if (deps.typescript)
43
+ memory.add({ key: 'language', fact: `TypeScript ${deps.typescript}`, category: 'tech-stack', date: today() });
44
+ if (deps.ink)
45
+ memory.add({ key: 'tui-framework', fact: `Ink ${deps.ink}`, category: 'tech-stack', date: today() });
46
+ }
47
+ // Read tsconfig for TS settings
48
+ const tsconfig = await readJsonSafe(path.join(projectRoot, 'tsconfig.json'));
49
+ if (tsconfig) {
50
+ const compilerOptions = tsconfig.compilerOptions;
51
+ if (compilerOptions?.strict) {
52
+ memory.add({ key: 'ts-strict-mode', fact: 'enabled', category: 'conventions', date: today() });
53
+ }
54
+ if (compilerOptions?.module?.toString().toLowerCase().includes('nodenext')) {
55
+ memory.add({ key: 'module-system', fact: 'ESM (NodeNext)', category: 'conventions', date: today() });
56
+ }
57
+ }
58
+ }
59
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/knowledge/hooks.ts"],"names":[],"mappings":"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"}