@contextos/core 0.1.0 → 0.2.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 (2) hide show
  1. package/dist/index.js +1198 -5
  2. package/package.json +46 -46
package/dist/index.js CHANGED
@@ -2049,11 +2049,11 @@ var ContextBuilder = class {
2049
2049
  const graphPath = join4(rootDir, CONTEXTOS_DIR2, GRAPH_FILE);
2050
2050
  const graphDir = join4(rootDir, CONTEXTOS_DIR2, "db");
2051
2051
  if (!existsSync4(graphDir)) {
2052
- const { mkdirSync: mkdirSync7 } = await import("fs");
2053
- mkdirSync7(graphDir, { recursive: true });
2052
+ const { mkdirSync: mkdirSync9 } = await import("fs");
2053
+ mkdirSync9(graphDir, { recursive: true });
2054
2054
  }
2055
- const { writeFileSync: writeFileSync7 } = await import("fs");
2056
- writeFileSync7(graphPath, JSON.stringify(this.graph.toJSON(), null, 2));
2055
+ const { writeFileSync: writeFileSync9 } = await import("fs");
2056
+ writeFileSync9(graphPath, JSON.stringify(this.graph.toJSON(), null, 2));
2057
2057
  return {
2058
2058
  filesIndexed,
2059
2059
  chunksCreated,
@@ -5534,6 +5534,1185 @@ var AuditLogger = class {
5534
5534
  }
5535
5535
  };
5536
5536
 
5537
+ // src/plugins/manager.ts
5538
+ import { existsSync as existsSync11, readdirSync, readFileSync as readFileSync11, mkdirSync as mkdirSync7, rmSync, writeFileSync as writeFileSync7 } from "fs";
5539
+ import { join as join10, resolve } from "path";
5540
+ var PluginManager = class {
5541
+ plugins = /* @__PURE__ */ new Map();
5542
+ pluginsDir;
5543
+ projectRoot;
5544
+ storage = /* @__PURE__ */ new Map();
5545
+ constructor(projectRoot) {
5546
+ this.projectRoot = projectRoot;
5547
+ this.pluginsDir = join10(projectRoot, ".contextos", "plugins");
5548
+ if (!existsSync11(this.pluginsDir)) {
5549
+ mkdirSync7(this.pluginsDir, { recursive: true });
5550
+ }
5551
+ }
5552
+ /**
5553
+ * Load all plugins from plugins directory
5554
+ */
5555
+ async loadAll() {
5556
+ const loaded = [];
5557
+ const errors = [];
5558
+ if (!existsSync11(this.pluginsDir)) {
5559
+ return { loaded, errors };
5560
+ }
5561
+ const entries = readdirSync(this.pluginsDir, { withFileTypes: true });
5562
+ for (const entry of entries) {
5563
+ if (!entry.isDirectory()) continue;
5564
+ const pluginPath = join10(this.pluginsDir, entry.name);
5565
+ try {
5566
+ await this.loadPlugin(pluginPath);
5567
+ loaded.push(entry.name);
5568
+ } catch (error) {
5569
+ errors.push({
5570
+ name: entry.name,
5571
+ error: error instanceof Error ? error.message : String(error)
5572
+ });
5573
+ }
5574
+ }
5575
+ return { loaded, errors };
5576
+ }
5577
+ /**
5578
+ * Load a single plugin from path
5579
+ */
5580
+ async loadPlugin(pluginPath) {
5581
+ const manifestPath = join10(pluginPath, "package.json");
5582
+ if (!existsSync11(manifestPath)) {
5583
+ throw new Error(`Plugin manifest not found: ${manifestPath}`);
5584
+ }
5585
+ const manifestContent = readFileSync11(manifestPath, "utf-8");
5586
+ const manifest = JSON.parse(manifestContent);
5587
+ if (!manifest.name || !manifest.version || !manifest.main) {
5588
+ throw new Error(`Invalid plugin manifest: missing name, version, or main`);
5589
+ }
5590
+ const mainPath = join10(pluginPath, manifest.main);
5591
+ if (!existsSync11(mainPath)) {
5592
+ throw new Error(`Plugin main file not found: ${mainPath}`);
5593
+ }
5594
+ const pluginModule = await import(`file://${resolve(mainPath)}`);
5595
+ const plugin = pluginModule.default || pluginModule;
5596
+ if (!plugin.name || !plugin.version) {
5597
+ throw new Error(`Invalid plugin: missing name or version`);
5598
+ }
5599
+ const state = {
5600
+ manifest,
5601
+ instance: plugin,
5602
+ enabled: true,
5603
+ path: pluginPath,
5604
+ loadedAt: /* @__PURE__ */ new Date()
5605
+ };
5606
+ this.plugins.set(plugin.name, state);
5607
+ if (plugin.activate) {
5608
+ const context = this.createPluginContext(plugin.name);
5609
+ await plugin.activate(context);
5610
+ }
5611
+ return plugin;
5612
+ }
5613
+ /**
5614
+ * Unload a plugin
5615
+ */
5616
+ async unloadPlugin(name) {
5617
+ const state = this.plugins.get(name);
5618
+ if (!state) return false;
5619
+ if (state.instance.deactivate) {
5620
+ await state.instance.deactivate();
5621
+ }
5622
+ this.storage.delete(name);
5623
+ this.plugins.delete(name);
5624
+ return true;
5625
+ }
5626
+ /**
5627
+ * Enable a disabled plugin
5628
+ */
5629
+ async enablePlugin(name) {
5630
+ const state = this.plugins.get(name);
5631
+ if (!state) return false;
5632
+ if (state.enabled) return true;
5633
+ state.enabled = true;
5634
+ if (state.instance.activate) {
5635
+ const context = this.createPluginContext(name);
5636
+ await state.instance.activate(context);
5637
+ }
5638
+ return true;
5639
+ }
5640
+ /**
5641
+ * Disable a plugin (keep loaded but inactive)
5642
+ */
5643
+ async disablePlugin(name) {
5644
+ const state = this.plugins.get(name);
5645
+ if (!state) return false;
5646
+ if (!state.enabled) return true;
5647
+ state.enabled = false;
5648
+ if (state.instance.deactivate) {
5649
+ await state.instance.deactivate();
5650
+ }
5651
+ return true;
5652
+ }
5653
+ /**
5654
+ * Install a plugin
5655
+ */
5656
+ async install(source, options = {}) {
5657
+ const targetDir = join10(this.pluginsDir, source.split("/").pop() || source);
5658
+ if (existsSync11(targetDir) && !options.force) {
5659
+ throw new Error(`Plugin already installed: ${source}`);
5660
+ }
5661
+ if (options.local) {
5662
+ const sourcePath = resolve(source);
5663
+ if (!existsSync11(sourcePath)) {
5664
+ throw new Error(`Source path not found: ${sourcePath}`);
5665
+ }
5666
+ if (options.force && existsSync11(targetDir)) {
5667
+ rmSync(targetDir, { recursive: true });
5668
+ }
5669
+ mkdirSync7(targetDir, { recursive: true });
5670
+ const manifest = JSON.parse(readFileSync11(join10(sourcePath, "package.json"), "utf-8"));
5671
+ writeFileSync7(join10(targetDir, "package.json"), JSON.stringify(manifest, null, 2));
5672
+ const mainContent = readFileSync11(join10(sourcePath, manifest.main), "utf-8");
5673
+ writeFileSync7(join10(targetDir, manifest.main), mainContent);
5674
+ } else {
5675
+ throw new Error("Remote plugin installation not yet implemented");
5676
+ }
5677
+ const plugin = await this.loadPlugin(targetDir);
5678
+ if (options.skipActivate) {
5679
+ await this.disablePlugin(plugin.name);
5680
+ }
5681
+ return plugin;
5682
+ }
5683
+ /**
5684
+ * Uninstall a plugin
5685
+ */
5686
+ async uninstall(name) {
5687
+ const state = this.plugins.get(name);
5688
+ if (!state) return false;
5689
+ await this.unloadPlugin(name);
5690
+ if (existsSync11(state.path)) {
5691
+ rmSync(state.path, { recursive: true });
5692
+ }
5693
+ return true;
5694
+ }
5695
+ /**
5696
+ * Get all loaded plugins
5697
+ */
5698
+ list() {
5699
+ return Array.from(this.plugins.values());
5700
+ }
5701
+ /**
5702
+ * Get a specific plugin
5703
+ */
5704
+ get(name) {
5705
+ return this.plugins.get(name);
5706
+ }
5707
+ /**
5708
+ * Execute a hook across all enabled plugins
5709
+ */
5710
+ async executeHook(hookName, ...args) {
5711
+ const result = {
5712
+ modified: false,
5713
+ value: args[0],
5714
+ pluginsExecuted: [],
5715
+ errors: []
5716
+ };
5717
+ for (const [name, state] of this.plugins) {
5718
+ if (!state.enabled) continue;
5719
+ const hook = state.instance.hooks?.[hookName];
5720
+ if (!hook) continue;
5721
+ try {
5722
+ const hookFn = hook;
5723
+ const hookResult = await hookFn(...args);
5724
+ if (hookResult !== void 0) {
5725
+ result.modified = true;
5726
+ result.value = hookResult;
5727
+ args[0] = hookResult;
5728
+ }
5729
+ result.pluginsExecuted.push(name);
5730
+ } catch (error) {
5731
+ result.errors.push({
5732
+ plugin: name,
5733
+ error: error instanceof Error ? error : new Error(String(error))
5734
+ });
5735
+ }
5736
+ }
5737
+ return result;
5738
+ }
5739
+ /**
5740
+ * Create a scaffold for new plugin
5741
+ */
5742
+ createPluginScaffold(template) {
5743
+ const pluginDir = join10(this.pluginsDir, template.name);
5744
+ if (existsSync11(pluginDir)) {
5745
+ throw new Error(`Plugin directory already exists: ${template.name}`);
5746
+ }
5747
+ mkdirSync7(pluginDir, { recursive: true });
5748
+ const manifest = {
5749
+ name: template.name,
5750
+ version: "1.0.0",
5751
+ description: template.description,
5752
+ author: template.author,
5753
+ main: "index.js",
5754
+ engines: {
5755
+ contextos: ">=2.0.0"
5756
+ }
5757
+ };
5758
+ writeFileSync7(
5759
+ join10(pluginDir, "package.json"),
5760
+ JSON.stringify(manifest, null, 2)
5761
+ );
5762
+ const hookCode = template.hooks.map((h) => ` ${h}: async (value) => {
5763
+ // TODO: Implement ${h}
5764
+ return value;
5765
+ },`).join("\n");
5766
+ const commandsCode = template.withCommands ? `
5767
+ commands: {
5768
+ 'my-command': {
5769
+ description: 'Example command',
5770
+ handler: async (args, context) => {
5771
+ context.log.info('Command executed with args:', args);
5772
+ },
5773
+ },
5774
+ },` : "";
5775
+ const pluginCode = `/**
5776
+ * ${template.name} - ContextOS Plugin
5777
+ * ${template.description}
5778
+ */
5779
+
5780
+ module.exports = {
5781
+ name: '${template.name}',
5782
+ version: '1.0.0',
5783
+ description: '${template.description}',
5784
+
5785
+ hooks: {
5786
+ ${hookCode}
5787
+ },
5788
+ ${commandsCode}
5789
+
5790
+ activate: async (context) => {
5791
+ context.log.info('${template.name} activated');
5792
+ },
5793
+
5794
+ deactivate: async () => {
5795
+ // Cleanup if needed
5796
+ },
5797
+ };
5798
+ `;
5799
+ writeFileSync7(join10(pluginDir, "index.js"), pluginCode);
5800
+ return pluginDir;
5801
+ }
5802
+ /**
5803
+ * Create plugin context for API access
5804
+ */
5805
+ createPluginContext(pluginName) {
5806
+ if (!this.storage.has(pluginName)) {
5807
+ this.storage.set(pluginName, /* @__PURE__ */ new Map());
5808
+ }
5809
+ const pluginStorage = this.storage.get(pluginName);
5810
+ return {
5811
+ projectRoot: this.projectRoot,
5812
+ configDir: join10(this.projectRoot, ".contextos"),
5813
+ log: {
5814
+ debug: (msg, ...args) => console.debug(`[${pluginName}]`, msg, ...args),
5815
+ info: (msg, ...args) => console.info(`[${pluginName}]`, msg, ...args),
5816
+ warn: (msg, ...args) => console.warn(`[${pluginName}]`, msg, ...args),
5817
+ error: (msg, ...args) => console.error(`[${pluginName}]`, msg, ...args)
5818
+ },
5819
+ query: async (_goal) => {
5820
+ return { files: [], context: "" };
5821
+ },
5822
+ readFile: async (path) => {
5823
+ const fullPath = join10(this.projectRoot, path);
5824
+ return readFileSync11(fullPath, "utf-8");
5825
+ },
5826
+ getDependencies: async (_path, _depth = 2) => {
5827
+ return [];
5828
+ },
5829
+ storage: {
5830
+ get: (key) => pluginStorage.get(key),
5831
+ set: (key, value) => {
5832
+ pluginStorage.set(key, value);
5833
+ },
5834
+ delete: (key) => pluginStorage.delete(key)
5835
+ }
5836
+ };
5837
+ }
5838
+ };
5839
+ function createPluginManager(projectRoot) {
5840
+ return new PluginManager(projectRoot);
5841
+ }
5842
+
5843
+ // src/plugins/registry.ts
5844
+ import { existsSync as existsSync12, readdirSync as readdirSync2, readFileSync as readFileSync12 } from "fs";
5845
+ import { join as join11 } from "path";
5846
+ var PluginRegistry = class {
5847
+ config;
5848
+ remoteCache = /* @__PURE__ */ new Map();
5849
+ constructor(config) {
5850
+ this.config = config;
5851
+ }
5852
+ /**
5853
+ * List all locally installed plugins
5854
+ */
5855
+ listLocal() {
5856
+ const plugins = [];
5857
+ if (!existsSync12(this.config.localDir)) {
5858
+ return plugins;
5859
+ }
5860
+ const entries = readdirSync2(this.config.localDir, { withFileTypes: true });
5861
+ for (const entry of entries) {
5862
+ if (!entry.isDirectory()) continue;
5863
+ const pluginPath = join11(this.config.localDir, entry.name);
5864
+ const manifestPath = join11(pluginPath, "package.json");
5865
+ if (!existsSync12(manifestPath)) continue;
5866
+ try {
5867
+ const manifest = JSON.parse(
5868
+ readFileSync12(manifestPath, "utf-8")
5869
+ );
5870
+ const disabledPath = join11(pluginPath, ".disabled");
5871
+ const enabled = !existsSync12(disabledPath);
5872
+ plugins.push({
5873
+ name: manifest.name,
5874
+ version: manifest.version,
5875
+ description: manifest.description,
5876
+ path: pluginPath,
5877
+ enabled
5878
+ });
5879
+ } catch {
5880
+ }
5881
+ }
5882
+ return plugins;
5883
+ }
5884
+ /**
5885
+ * Search remote registry for plugins
5886
+ */
5887
+ async searchRemote(query) {
5888
+ if (!this.config.remoteUrl) {
5889
+ return [];
5890
+ }
5891
+ const cacheKey = `search:${query}`;
5892
+ if (this.remoteCache.has(cacheKey)) {
5893
+ return this.remoteCache.get(cacheKey);
5894
+ }
5895
+ try {
5896
+ const searchUrl = `${this.config.remoteUrl}/-/v1/search?text=${encodeURIComponent(query)}&scope=contextos-plugin`;
5897
+ const response = await fetch(searchUrl);
5898
+ if (!response.ok) {
5899
+ throw new Error(`Registry search failed: ${response.statusText}`);
5900
+ }
5901
+ const data = await response.json();
5902
+ const results = data.objects.map((obj) => obj.package);
5903
+ this.remoteCache.set(cacheKey, results);
5904
+ setTimeout(() => this.remoteCache.delete(cacheKey), 5 * 60 * 1e3);
5905
+ return results;
5906
+ } catch (error) {
5907
+ console.error("Remote registry search failed:", error);
5908
+ return [];
5909
+ }
5910
+ }
5911
+ /**
5912
+ * Get plugin info from remote registry
5913
+ */
5914
+ async getRemoteInfo(name, version) {
5915
+ if (!this.config.remoteUrl) {
5916
+ return null;
5917
+ }
5918
+ try {
5919
+ const infoUrl = version ? `${this.config.remoteUrl}/${name}/${version}` : `${this.config.remoteUrl}/${name}/latest`;
5920
+ const response = await fetch(infoUrl);
5921
+ if (!response.ok) {
5922
+ return null;
5923
+ }
5924
+ return await response.json();
5925
+ } catch {
5926
+ return null;
5927
+ }
5928
+ }
5929
+ /**
5930
+ * Check if a plugin is installed locally
5931
+ */
5932
+ isInstalled(name) {
5933
+ const plugins = this.listLocal();
5934
+ return plugins.some((p) => p.name === name);
5935
+ }
5936
+ /**
5937
+ * Get local plugin by name
5938
+ */
5939
+ getLocal(name) {
5940
+ const plugins = this.listLocal();
5941
+ return plugins.find((p) => p.name === name) || null;
5942
+ }
5943
+ /**
5944
+ * Get featured/popular plugins from remote
5945
+ */
5946
+ async getFeatured() {
5947
+ if (!this.config.remoteUrl) {
5948
+ return [
5949
+ {
5950
+ name: "@contextos/plugin-docker",
5951
+ version: "1.0.0",
5952
+ description: "Docker context integration - scan Dockerfiles and compose files",
5953
+ author: "ContextOS Team",
5954
+ downloads: 1200,
5955
+ lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
5956
+ tarball: "",
5957
+ keywords: ["docker", "container", "devops"]
5958
+ },
5959
+ {
5960
+ name: "@contextos/plugin-kubernetes",
5961
+ version: "1.0.0",
5962
+ description: "Kubernetes context integration - scan K8s manifests",
5963
+ author: "ContextOS Team",
5964
+ downloads: 800,
5965
+ lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
5966
+ tarball: "",
5967
+ keywords: ["kubernetes", "k8s", "devops"]
5968
+ },
5969
+ {
5970
+ name: "@contextos/plugin-graphql",
5971
+ version: "1.0.0",
5972
+ description: "GraphQL schema and resolver context",
5973
+ author: "ContextOS Team",
5974
+ downloads: 650,
5975
+ lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
5976
+ tarball: "",
5977
+ keywords: ["graphql", "api", "schema"]
5978
+ },
5979
+ {
5980
+ name: "@contextos/plugin-prisma",
5981
+ version: "1.0.0",
5982
+ description: "Prisma ORM schema integration",
5983
+ author: "ContextOS Team",
5984
+ downloads: 500,
5985
+ lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
5986
+ tarball: "",
5987
+ keywords: ["prisma", "database", "orm"]
5988
+ }
5989
+ ];
5990
+ }
5991
+ return this.searchRemote("contextos-plugin featured");
5992
+ }
5993
+ /**
5994
+ * Clear remote cache
5995
+ */
5996
+ clearCache() {
5997
+ this.remoteCache.clear();
5998
+ }
5999
+ };
6000
+ function createPluginRegistry(projectRoot) {
6001
+ return new PluginRegistry({
6002
+ localDir: join11(projectRoot, ".contextos", "plugins"),
6003
+ remoteUrl: process.env.CONTEXTOS_REGISTRY_URL || void 0,
6004
+ cacheDir: join11(projectRoot, ".contextos", "cache", "plugins")
6005
+ });
6006
+ }
6007
+
6008
+ // src/finetuning/collector.ts
6009
+ import { existsSync as existsSync13, readFileSync as readFileSync13, writeFileSync as writeFileSync8, mkdirSync as mkdirSync8 } from "fs";
6010
+ import { join as join12 } from "path";
6011
+ import { createHash as createHash4 } from "crypto";
6012
+ var TrainingDataCollector = class {
6013
+ dataDir;
6014
+ examples = [];
6015
+ loaded = false;
6016
+ constructor(projectRoot) {
6017
+ this.dataDir = join12(projectRoot, ".contextos", "training");
6018
+ if (!existsSync13(this.dataDir)) {
6019
+ mkdirSync8(this.dataDir, { recursive: true });
6020
+ }
6021
+ }
6022
+ /**
6023
+ * Load existing training data
6024
+ */
6025
+ load() {
6026
+ if (this.loaded) return;
6027
+ const dataFile = join12(this.dataDir, "examples.json");
6028
+ if (existsSync13(dataFile)) {
6029
+ try {
6030
+ const data = JSON.parse(readFileSync13(dataFile, "utf-8"));
6031
+ this.examples = data.examples || [];
6032
+ } catch {
6033
+ this.examples = [];
6034
+ }
6035
+ }
6036
+ this.loaded = true;
6037
+ }
6038
+ /**
6039
+ * Save training data
6040
+ */
6041
+ save() {
6042
+ const dataFile = join12(this.dataDir, "examples.json");
6043
+ writeFileSync8(dataFile, JSON.stringify({
6044
+ version: "1.0",
6045
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
6046
+ examples: this.examples
6047
+ }, null, 2));
6048
+ }
6049
+ /**
6050
+ * Record a context build for training
6051
+ */
6052
+ record(goal, selectedFiles, context, tokenCount, meta) {
6053
+ this.load();
6054
+ const example = {
6055
+ id: this.generateId(goal, meta.timestamp),
6056
+ goal,
6057
+ selectedFiles,
6058
+ context,
6059
+ tokenCount,
6060
+ meta
6061
+ };
6062
+ this.examples.push(example);
6063
+ this.save();
6064
+ return example;
6065
+ }
6066
+ /**
6067
+ * Add feedback to an existing example
6068
+ */
6069
+ addFeedback(exampleId, rating, comment) {
6070
+ this.load();
6071
+ const example = this.examples.find((e) => e.id === exampleId);
6072
+ if (!example) return false;
6073
+ example.feedback = { rating, comment };
6074
+ this.save();
6075
+ return true;
6076
+ }
6077
+ /**
6078
+ * Get all examples
6079
+ */
6080
+ getAll() {
6081
+ this.load();
6082
+ return [...this.examples];
6083
+ }
6084
+ /**
6085
+ * Get example by ID
6086
+ */
6087
+ get(id) {
6088
+ this.load();
6089
+ return this.examples.find((e) => e.id === id);
6090
+ }
6091
+ /**
6092
+ * Get recent examples
6093
+ */
6094
+ getRecent(limit = 10) {
6095
+ this.load();
6096
+ return this.examples.sort(
6097
+ (a, b) => new Date(b.meta.timestamp).getTime() - new Date(a.meta.timestamp).getTime()
6098
+ ).slice(0, limit);
6099
+ }
6100
+ /**
6101
+ * Filter examples
6102
+ */
6103
+ filter(predicate) {
6104
+ this.load();
6105
+ return this.examples.filter(predicate);
6106
+ }
6107
+ /**
6108
+ * Get dataset statistics
6109
+ */
6110
+ getStats() {
6111
+ this.load();
6112
+ const stats = {
6113
+ totalExamples: this.examples.length,
6114
+ ratingDistribution: {
6115
+ good: 0,
6116
+ neutral: 0,
6117
+ bad: 0,
6118
+ unrated: 0
6119
+ },
6120
+ languageDistribution: {},
6121
+ avgTokenCount: 0,
6122
+ avgFilesPerExample: 0,
6123
+ dateRange: {
6124
+ earliest: /* @__PURE__ */ new Date(),
6125
+ latest: /* @__PURE__ */ new Date(0)
6126
+ }
6127
+ };
6128
+ if (this.examples.length === 0) {
6129
+ return stats;
6130
+ }
6131
+ let totalTokens = 0;
6132
+ let totalFiles = 0;
6133
+ for (const example of this.examples) {
6134
+ if (example.feedback) {
6135
+ stats.ratingDistribution[example.feedback.rating]++;
6136
+ } else {
6137
+ stats.ratingDistribution.unrated++;
6138
+ }
6139
+ const lang = example.meta.language;
6140
+ stats.languageDistribution[lang] = (stats.languageDistribution[lang] || 0) + 1;
6141
+ totalTokens += example.tokenCount;
6142
+ totalFiles += example.selectedFiles.length;
6143
+ const date = new Date(example.meta.timestamp);
6144
+ if (date < stats.dateRange.earliest) {
6145
+ stats.dateRange.earliest = date;
6146
+ }
6147
+ if (date > stats.dateRange.latest) {
6148
+ stats.dateRange.latest = date;
6149
+ }
6150
+ }
6151
+ stats.avgTokenCount = Math.round(totalTokens / this.examples.length);
6152
+ stats.avgFilesPerExample = Math.round(totalFiles / this.examples.length * 10) / 10;
6153
+ return stats;
6154
+ }
6155
+ /**
6156
+ * Delete an example
6157
+ */
6158
+ delete(id) {
6159
+ this.load();
6160
+ const index = this.examples.findIndex((e) => e.id === id);
6161
+ if (index === -1) return false;
6162
+ this.examples.splice(index, 1);
6163
+ this.save();
6164
+ return true;
6165
+ }
6166
+ /**
6167
+ * Clear all examples
6168
+ */
6169
+ clear() {
6170
+ this.examples = [];
6171
+ this.save();
6172
+ }
6173
+ /**
6174
+ * Generate unique ID
6175
+ */
6176
+ generateId(goal, timestamp) {
6177
+ const hash = createHash4("sha256").update(goal + timestamp.toISOString()).digest("hex").substring(0, 12);
6178
+ return `ex_${hash}`;
6179
+ }
6180
+ };
6181
+ function createTrainingDataCollector(projectRoot) {
6182
+ return new TrainingDataCollector(projectRoot);
6183
+ }
6184
+
6185
+ // src/finetuning/formatter.ts
6186
+ import { createReadStream, createWriteStream, existsSync as existsSync14 } from "fs";
6187
+ import { createInterface } from "readline";
6188
+ var DatasetFormatter = class {
6189
+ /**
6190
+ * Export examples to file
6191
+ */
6192
+ async export(examples, outputPath, format, config = {}) {
6193
+ let filtered = this.filterExamples(examples, config);
6194
+ if (config.shuffle) {
6195
+ filtered = this.shuffle(filtered);
6196
+ }
6197
+ if (config.maxExamples && filtered.length > config.maxExamples) {
6198
+ filtered = filtered.slice(0, config.maxExamples);
6199
+ }
6200
+ const stream = createWriteStream(outputPath);
6201
+ for (const example of filtered) {
6202
+ const formatted = this.formatExample(example, format);
6203
+ stream.write(formatted + "\n");
6204
+ }
6205
+ stream.end();
6206
+ return { exported: filtered.length, path: outputPath };
6207
+ }
6208
+ /**
6209
+ * Export with train/validation split
6210
+ */
6211
+ async exportWithSplit(examples, outputDir, format, config = {}) {
6212
+ const split = config.validationSplit || 0.1;
6213
+ let filtered = this.filterExamples(examples, config);
6214
+ if (config.shuffle) {
6215
+ filtered = this.shuffle(filtered);
6216
+ }
6217
+ const splitIndex = Math.floor(filtered.length * (1 - split));
6218
+ const trainExamples = filtered.slice(0, splitIndex);
6219
+ const validationExamples = filtered.slice(splitIndex);
6220
+ await this.export(trainExamples, `${outputDir}/train.jsonl`, format, {});
6221
+ await this.export(validationExamples, `${outputDir}/validation.jsonl`, format, {});
6222
+ return {
6223
+ train: trainExamples.length,
6224
+ validation: validationExamples.length
6225
+ };
6226
+ }
6227
+ /**
6228
+ * Validate a dataset file
6229
+ */
6230
+ async validate(filePath) {
6231
+ const result = {
6232
+ valid: true,
6233
+ errors: [],
6234
+ warnings: [],
6235
+ stats: {
6236
+ totalExamples: 0,
6237
+ ratingDistribution: { good: 0, neutral: 0, bad: 0, unrated: 0 },
6238
+ languageDistribution: {},
6239
+ avgTokenCount: 0,
6240
+ avgFilesPerExample: 0,
6241
+ dateRange: { earliest: /* @__PURE__ */ new Date(), latest: /* @__PURE__ */ new Date(0) }
6242
+ }
6243
+ };
6244
+ if (!existsSync14(filePath)) {
6245
+ result.valid = false;
6246
+ result.errors.push({
6247
+ line: 0,
6248
+ field: "file",
6249
+ message: `File not found: ${filePath}`
6250
+ });
6251
+ return result;
6252
+ }
6253
+ const fileStream = createReadStream(filePath);
6254
+ const rl = createInterface({
6255
+ input: fileStream,
6256
+ crlfDelay: Infinity
6257
+ });
6258
+ let lineNumber = 0;
6259
+ let totalTokens = 0;
6260
+ let totalFiles = 0;
6261
+ for await (const line of rl) {
6262
+ lineNumber++;
6263
+ if (!line.trim()) continue;
6264
+ try {
6265
+ const example = JSON.parse(line);
6266
+ if (!example.goal) {
6267
+ result.errors.push({
6268
+ line: lineNumber,
6269
+ field: "goal",
6270
+ message: "Missing required field: goal"
6271
+ });
6272
+ result.valid = false;
6273
+ }
6274
+ if (!example.context) {
6275
+ result.errors.push({
6276
+ line: lineNumber,
6277
+ field: "context",
6278
+ message: "Missing required field: context"
6279
+ });
6280
+ result.valid = false;
6281
+ }
6282
+ result.stats.totalExamples++;
6283
+ totalTokens += example.tokenCount || 0;
6284
+ totalFiles += example.selectedFiles?.length || 0;
6285
+ if (example.feedback) {
6286
+ result.stats.ratingDistribution[example.feedback.rating]++;
6287
+ } else {
6288
+ result.stats.ratingDistribution.unrated++;
6289
+ }
6290
+ if (example.meta?.language) {
6291
+ const lang = example.meta.language;
6292
+ result.stats.languageDistribution[lang] = (result.stats.languageDistribution[lang] || 0) + 1;
6293
+ }
6294
+ if (example.meta?.timestamp) {
6295
+ const date = new Date(example.meta.timestamp);
6296
+ if (date < result.stats.dateRange.earliest) {
6297
+ result.stats.dateRange.earliest = date;
6298
+ }
6299
+ if (date > result.stats.dateRange.latest) {
6300
+ result.stats.dateRange.latest = date;
6301
+ }
6302
+ }
6303
+ } catch (error) {
6304
+ result.errors.push({
6305
+ line: lineNumber,
6306
+ field: "json",
6307
+ message: `Invalid JSON: ${error instanceof Error ? error.message : "Parse error"}`
6308
+ });
6309
+ result.valid = false;
6310
+ }
6311
+ }
6312
+ if (result.stats.totalExamples > 0) {
6313
+ result.stats.avgTokenCount = Math.round(totalTokens / result.stats.totalExamples);
6314
+ result.stats.avgFilesPerExample = Math.round(totalFiles / result.stats.totalExamples * 10) / 10;
6315
+ }
6316
+ if (result.stats.totalExamples < 100) {
6317
+ result.warnings.push("Dataset has fewer than 100 examples. Consider collecting more data.");
6318
+ }
6319
+ if (result.stats.ratingDistribution.bad > result.stats.totalExamples * 0.2) {
6320
+ result.warnings.push("More than 20% of examples have negative ratings.");
6321
+ }
6322
+ return result;
6323
+ }
6324
+ /**
6325
+ * Filter examples based on config
6326
+ */
6327
+ filterExamples(examples, config) {
6328
+ return examples.filter((example) => {
6329
+ if (config.minRating) {
6330
+ if (!example.feedback && !config.includeUnrated) {
6331
+ return false;
6332
+ }
6333
+ if (example.feedback) {
6334
+ const ratingOrder = { bad: 0, neutral: 1, good: 2 };
6335
+ if (ratingOrder[example.feedback.rating] < ratingOrder[config.minRating]) {
6336
+ return false;
6337
+ }
6338
+ }
6339
+ }
6340
+ if (config.projectFilter && example.meta.projectName !== config.projectFilter) {
6341
+ return false;
6342
+ }
6343
+ if (config.languageFilter && example.meta.language !== config.languageFilter) {
6344
+ return false;
6345
+ }
6346
+ return true;
6347
+ });
6348
+ }
6349
+ /**
6350
+ * Format a single example
6351
+ */
6352
+ formatExample(example, format) {
6353
+ switch (format.format) {
6354
+ case "openai":
6355
+ return JSON.stringify({
6356
+ messages: [
6357
+ {
6358
+ role: "system",
6359
+ content: "You are a code context selection assistant. Given a goal, select the most relevant files from a codebase."
6360
+ },
6361
+ {
6362
+ role: "user",
6363
+ content: `Goal: ${example.goal}
6364
+
6365
+ Project: ${example.meta.projectName} (${example.meta.language})`
6366
+ },
6367
+ {
6368
+ role: "assistant",
6369
+ content: `Selected files:
6370
+ ${example.selectedFiles.map((f) => `- ${f}`).join("\n")}
6371
+
6372
+ ${example.context}`
6373
+ }
6374
+ ]
6375
+ });
6376
+ case "anthropic":
6377
+ return JSON.stringify({
6378
+ prompt: `
6379
+
6380
+ Human: Goal: ${example.goal}
6381
+
6382
+ Project: ${example.meta.projectName} (${example.meta.language})
6383
+
6384
+ Assistant:`,
6385
+ completion: ` Selected files:
6386
+ ${example.selectedFiles.map((f) => `- ${f}`).join("\n")}
6387
+
6388
+ ${example.context}`
6389
+ });
6390
+ case "csv":
6391
+ const escapeCsv = (s) => `"${s.replace(/"/g, '""')}"`;
6392
+ return [
6393
+ escapeCsv(example.id),
6394
+ escapeCsv(example.goal),
6395
+ escapeCsv(example.selectedFiles.join(";")),
6396
+ example.tokenCount,
6397
+ example.feedback?.rating || "",
6398
+ escapeCsv(example.meta.language)
6399
+ ].join(",");
6400
+ case "jsonl":
6401
+ default:
6402
+ return JSON.stringify(example);
6403
+ }
6404
+ }
6405
+ /**
6406
+ * Shuffle array
6407
+ */
6408
+ shuffle(array) {
6409
+ const shuffled = [...array];
6410
+ for (let i = shuffled.length - 1; i > 0; i--) {
6411
+ const j = Math.floor(Math.random() * (i + 1));
6412
+ [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
6413
+ }
6414
+ return shuffled;
6415
+ }
6416
+ };
6417
+ function createDatasetFormatter() {
6418
+ return new DatasetFormatter();
6419
+ }
6420
+
6421
+ // src/deployment/docker.ts
6422
+ function generateDockerCompose(config) {
6423
+ const services = {
6424
+ contextos: {
6425
+ image: "contextos/server:latest",
6426
+ container_name: config.name,
6427
+ ports: [`${config.port}:${config.port}`],
6428
+ environment: {
6429
+ NODE_ENV: config.environment,
6430
+ PORT: config.port.toString(),
6431
+ HOST: config.host,
6432
+ LOG_LEVEL: config.logging.level,
6433
+ LOG_FORMAT: config.logging.format,
6434
+ ...config.environment
6435
+ },
6436
+ volumes: config.volumes?.map(
6437
+ (v) => `${v.source}:${v.target}${v.readonly ? ":ro" : ""}`
6438
+ ) || [
6439
+ "./data:/data",
6440
+ "./.contextos:/app/.contextos"
6441
+ ],
6442
+ restart: "unless-stopped",
6443
+ healthcheck: {
6444
+ test: ["CMD", "curl", "-f", `http://localhost:${config.port}/health`],
6445
+ interval: "30s",
6446
+ timeout: "10s",
6447
+ retries: 3,
6448
+ start_period: "10s"
6449
+ }
6450
+ }
6451
+ };
6452
+ if (config.resources) {
6453
+ services.contextos = {
6454
+ ...services.contextos,
6455
+ deploy: {
6456
+ resources: {
6457
+ limits: {
6458
+ memory: config.resources.memory,
6459
+ cpus: config.resources.cpus
6460
+ }
6461
+ }
6462
+ }
6463
+ };
6464
+ }
6465
+ if (config.redis) {
6466
+ services.redis = {
6467
+ image: "redis:7-alpine",
6468
+ container_name: `${config.name}-redis`,
6469
+ ports: [`${config.redis.port}:6379`],
6470
+ volumes: ["redis-data:/data"],
6471
+ restart: "unless-stopped"
6472
+ };
6473
+ services.contextos.depends_on = ["redis"];
6474
+ const env = services.contextos.environment;
6475
+ env.REDIS_HOST = "redis";
6476
+ env.REDIS_PORT = "6379";
6477
+ }
6478
+ const compose = {
6479
+ version: "3.8",
6480
+ services,
6481
+ volumes: {
6482
+ "contextos-data": {},
6483
+ ...config.redis ? { "redis-data": {} } : {}
6484
+ }
6485
+ };
6486
+ return generateYaml(compose);
6487
+ }
6488
+ function generateDockerfile() {
6489
+ return `# ContextOS Server Dockerfile
6490
+ FROM node:20-alpine AS base
6491
+
6492
+ # Install dependencies only when needed
6493
+ FROM base AS deps
6494
+ WORKDIR /app
6495
+ COPY package*.json pnpm-lock.yaml ./
6496
+ RUN npm install -g pnpm && pnpm install --frozen-lockfile
6497
+
6498
+ # Build the application
6499
+ FROM base AS builder
6500
+ WORKDIR /app
6501
+ COPY --from=deps /app/node_modules ./node_modules
6502
+ COPY . .
6503
+ RUN npm run build
6504
+
6505
+ # Production image
6506
+ FROM base AS runner
6507
+ WORKDIR /app
6508
+
6509
+ ENV NODE_ENV=production
6510
+
6511
+ RUN addgroup --system --gid 1001 nodejs
6512
+ RUN adduser --system --uid 1001 contextos
6513
+
6514
+ COPY --from=builder --chown=contextos:nodejs /app/dist ./dist
6515
+ COPY --from=builder --chown=contextos:nodejs /app/node_modules ./node_modules
6516
+ COPY --from=builder --chown=contextos:nodejs /app/package.json ./
6517
+
6518
+ USER contextos
6519
+
6520
+ EXPOSE 3000
6521
+
6522
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \\
6523
+ CMD curl -f http://localhost:3000/health || exit 1
6524
+
6525
+ CMD ["node", "dist/server.js"]
6526
+ `;
6527
+ }
6528
+ function generateHelmValues(config) {
6529
+ const values = {
6530
+ replicaCount: config.replicas,
6531
+ image: {
6532
+ repository: "contextos/server",
6533
+ tag: "latest",
6534
+ pullPolicy: "IfNotPresent"
6535
+ },
6536
+ service: {
6537
+ type: "ClusterIP",
6538
+ port: config.port
6539
+ },
6540
+ ingress: {
6541
+ enabled: config.ingress?.enabled || false,
6542
+ className: "nginx",
6543
+ annotations: config.ingress?.annotations || {},
6544
+ hosts: config.ingress ? [{
6545
+ host: config.ingress.host,
6546
+ paths: [{ path: "/", pathType: "Prefix" }]
6547
+ }] : [],
6548
+ tls: config.ingress?.tls ? [{
6549
+ secretName: `${config.name}-tls`,
6550
+ hosts: [config.ingress.host]
6551
+ }] : []
6552
+ },
6553
+ resources: config.resources,
6554
+ env: {
6555
+ NODE_ENV: config.environment,
6556
+ LOG_LEVEL: config.logging.level
6557
+ },
6558
+ serviceAccount: {
6559
+ create: !!config.serviceAccount,
6560
+ name: config.serviceAccount || ""
6561
+ },
6562
+ podAnnotations: config.podAnnotations || {}
6563
+ };
6564
+ return generateYaml(values);
6565
+ }
6566
+ function generateK8sDeployment(config) {
6567
+ const deployment = {
6568
+ apiVersion: "apps/v1",
6569
+ kind: "Deployment",
6570
+ metadata: {
6571
+ name: config.name,
6572
+ namespace: config.namespace,
6573
+ labels: {
6574
+ "app.kubernetes.io/name": config.name,
6575
+ "app.kubernetes.io/instance": config.name
6576
+ }
6577
+ },
6578
+ spec: {
6579
+ replicas: config.replicas,
6580
+ selector: {
6581
+ matchLabels: {
6582
+ "app.kubernetes.io/name": config.name,
6583
+ "app.kubernetes.io/instance": config.name
6584
+ }
6585
+ },
6586
+ template: {
6587
+ metadata: {
6588
+ labels: {
6589
+ "app.kubernetes.io/name": config.name,
6590
+ "app.kubernetes.io/instance": config.name
6591
+ },
6592
+ annotations: config.podAnnotations || {}
6593
+ },
6594
+ spec: {
6595
+ serviceAccountName: config.serviceAccount,
6596
+ containers: [{
6597
+ name: config.name,
6598
+ image: "contextos/server:latest",
6599
+ ports: [{ containerPort: config.port }],
6600
+ env: [
6601
+ { name: "NODE_ENV", value: config.environment },
6602
+ { name: "PORT", value: config.port.toString() },
6603
+ { name: "LOG_LEVEL", value: config.logging.level }
6604
+ ],
6605
+ resources: config.resources,
6606
+ livenessProbe: {
6607
+ httpGet: { path: "/health", port: config.port },
6608
+ initialDelaySeconds: 10,
6609
+ periodSeconds: 30
6610
+ },
6611
+ readinessProbe: {
6612
+ httpGet: { path: "/health", port: config.port },
6613
+ initialDelaySeconds: 5,
6614
+ periodSeconds: 10
6615
+ }
6616
+ }]
6617
+ }
6618
+ }
6619
+ }
6620
+ };
6621
+ return generateYaml(deployment);
6622
+ }
6623
+ function checkHealth(config) {
6624
+ const checks = [];
6625
+ let overallHealthy = true;
6626
+ try {
6627
+ checks.push({
6628
+ name: "database",
6629
+ status: "pass",
6630
+ message: `${config.database.type} connection OK`
6631
+ });
6632
+ } catch (error) {
6633
+ checks.push({
6634
+ name: "database",
6635
+ status: "fail",
6636
+ message: error instanceof Error ? error.message : "Connection failed"
6637
+ });
6638
+ overallHealthy = false;
6639
+ }
6640
+ checks.push({
6641
+ name: "filesystem",
6642
+ status: "pass",
6643
+ message: "Write access OK"
6644
+ });
6645
+ return {
6646
+ status: overallHealthy ? "healthy" : "unhealthy",
6647
+ timestamp: /* @__PURE__ */ new Date(),
6648
+ version: "2.0.0",
6649
+ uptime: process.uptime(),
6650
+ checks
6651
+ };
6652
+ }
6653
+ function validateLicense(key) {
6654
+ if (!key || key.length < 10) {
6655
+ return null;
6656
+ }
6657
+ const parts = key.split("-");
6658
+ if (parts.length < 6 || parts[0] !== "CTXOS") {
6659
+ return null;
6660
+ }
6661
+ const typeMap = {
6662
+ "T": "trial",
6663
+ "TM": "team",
6664
+ "E": "enterprise"
6665
+ };
6666
+ return {
6667
+ key,
6668
+ type: typeMap[parts[1]] || "trial",
6669
+ organization: parts[2],
6670
+ maxSeats: parseInt(parts[3]) || 5,
6671
+ expiresAt: new Date(parseInt(parts[4]) * 1e3),
6672
+ features: ["core", "analytics", "sync"],
6673
+ signature: parts.slice(5).join("-")
6674
+ };
6675
+ }
6676
+ function generateYaml(obj, indent = 0) {
6677
+ const spaces = " ".repeat(indent);
6678
+ if (obj === null || obj === void 0) {
6679
+ return "null";
6680
+ }
6681
+ if (typeof obj === "string") {
6682
+ return obj.includes(":") || obj.includes("#") ? `"${obj}"` : obj;
6683
+ }
6684
+ if (typeof obj === "number" || typeof obj === "boolean") {
6685
+ return String(obj);
6686
+ }
6687
+ if (Array.isArray(obj)) {
6688
+ if (obj.length === 0) return "[]";
6689
+ return obj.map((item) => {
6690
+ if (typeof item === "object" && item !== null) {
6691
+ const yaml = generateYaml(item, indent + 1);
6692
+ return `${spaces}- ${yaml.trim().replace(/\n/g, `
6693
+ ${spaces} `)}`;
6694
+ }
6695
+ return `${spaces}- ${generateYaml(item, indent)}`;
6696
+ }).join("\n");
6697
+ }
6698
+ if (typeof obj === "object") {
6699
+ const entries = Object.entries(obj);
6700
+ if (entries.length === 0) return "{}";
6701
+ return entries.map(([key, value]) => {
6702
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
6703
+ return `${spaces}${key}:
6704
+ ${generateYaml(value, indent + 1)}`;
6705
+ }
6706
+ if (Array.isArray(value)) {
6707
+ return `${spaces}${key}:
6708
+ ${generateYaml(value, indent + 1)}`;
6709
+ }
6710
+ return `${spaces}${key}: ${generateYaml(value, indent)}`;
6711
+ }).join("\n");
6712
+ }
6713
+ return String(obj);
6714
+ }
6715
+
5537
6716
  // src/errors.ts
5538
6717
  var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
5539
6718
  ErrorCode2["CONFIG_NOT_FOUND"] = "E1001";
@@ -5880,6 +7059,7 @@ export {
5880
7059
  ContextYamlSchema,
5881
7060
  DEFAULT_RLM_CONFIG,
5882
7061
  DEFAULT_SYNC_CONFIG,
7062
+ DatasetFormatter,
5883
7063
  DependencyGraph,
5884
7064
  DriftDetector,
5885
7065
  E2EEncryption,
@@ -5896,6 +7076,8 @@ export {
5896
7076
  MODEL_SPECIFIC_ADDENDUM,
5897
7077
  MetaSchema,
5898
7078
  OpenAIAdapter,
7079
+ PluginManager,
7080
+ PluginRegistry,
5899
7081
  ProjectConfigSchema,
5900
7082
  ProposalManager,
5901
7083
  RBACManager,
@@ -5907,24 +7089,30 @@ export {
5907
7089
  TeamSync,
5908
7090
  TemplateManager,
5909
7091
  TokenBudget,
7092
+ TrainingDataCollector,
5910
7093
  VectorStore,
5911
7094
  Watchdog,
5912
7095
  calculateCost,
7096
+ checkHealth,
5913
7097
  chunkCode,
5914
7098
  createAnthropicAdapter,
5915
7099
  createBlackboard,
5916
7100
  createContextAPI,
7101
+ createDatasetFormatter,
5917
7102
  createGeminiClient,
5918
7103
  createInitialUserMessage,
5919
7104
  createLogger,
5920
7105
  createObservationMessage,
5921
7106
  createOpenAIAdapter,
7107
+ createPluginManager,
7108
+ createPluginRegistry,
5922
7109
  createProposalManager,
5923
7110
  createRLMEngine,
5924
7111
  createSandbox,
5925
7112
  createSandboxContext,
5926
7113
  createScopeManager,
5927
7114
  createSubAgentResultMessage,
7115
+ createTrainingDataCollector,
5928
7116
  createWatchdog,
5929
7117
  detectDrift,
5930
7118
  detectProjectType,
@@ -5934,6 +7122,10 @@ export {
5934
7122
  extractFunctionsRegex,
5935
7123
  extractImportsRegex,
5936
7124
  findContextosRoot,
7125
+ generateDockerCompose,
7126
+ generateDockerfile,
7127
+ generateHelmValues,
7128
+ generateK8sDeployment,
5937
7129
  generateSystemPrompt,
5938
7130
  getContextBuilder,
5939
7131
  getGlobalBlackboard,
@@ -5961,5 +7153,6 @@ export {
5961
7153
  saveContextYaml,
5962
7154
  setGlobalLogger,
5963
7155
  splitContextToFiles,
5964
- validateCode
7156
+ validateCode,
7157
+ validateLicense
5965
7158
  };
package/package.json CHANGED
@@ -1,48 +1,48 @@
1
1
  {
2
- "name": "@contextos/core",
3
- "version": "0.1.0",
4
- "description": "Core engine for ContextOS - context management, parsing, and ranking",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "import": "./dist/index.js",
11
- "types": "./dist/index.d.ts"
12
- }
13
- },
14
- "scripts": {
15
- "build": "tsup src/index.ts --format esm --clean",
16
- "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
17
- "test": "vitest run",
18
- "test:watch": "vitest",
19
- "test:coverage": "vitest run --coverage",
20
- "lint": "eslint src/",
21
- "clean": "rimraf dist"
22
- },
23
- "dependencies": {
24
- "@xenova/transformers": "^2.17.0",
25
- "better-sqlite3": "^11.0.0",
26
- "chokidar": "^3.6.0",
27
- "glob": "^10.3.0",
28
- "tiktoken": "^1.0.15",
29
- "web-tree-sitter": "^0.22.0",
30
- "yaml": "^2.4.0",
31
- "zod": "^3.23.0"
32
- },
33
- "devDependencies": {
34
- "@types/better-sqlite3": "^7.6.9",
35
- "eslint": "^8.57.0",
36
- "rimraf": "^5.0.5",
37
- "tsup": "^8.0.2",
38
- "typescript": "^5.4.0",
39
- "vitest": "^1.4.0"
40
- },
41
- "peerDependencies": {
42
- "typescript": "^5.0.0"
43
- },
44
- "files": [
45
- "dist"
46
- ],
47
- "license": "MIT"
2
+ "name": "@contextos/core",
3
+ "version": "0.2.0",
4
+ "description": "Core engine for ContextOS - context management, parsing, and ranking",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "dependencies": {
15
+ "@xenova/transformers": "^2.17.0",
16
+ "better-sqlite3": "^11.0.0",
17
+ "chokidar": "^3.6.0",
18
+ "glob": "^10.3.0",
19
+ "tiktoken": "^1.0.15",
20
+ "web-tree-sitter": "^0.22.0",
21
+ "yaml": "^2.4.0",
22
+ "zod": "^3.23.0"
23
+ },
24
+ "devDependencies": {
25
+ "@types/better-sqlite3": "^7.6.9",
26
+ "eslint": "^8.57.0",
27
+ "rimraf": "^5.0.5",
28
+ "tsup": "^8.0.2",
29
+ "typescript": "^5.4.0",
30
+ "vitest": "^1.4.0"
31
+ },
32
+ "peerDependencies": {
33
+ "typescript": "^5.0.0"
34
+ },
35
+ "files": [
36
+ "dist"
37
+ ],
38
+ "license": "MIT",
39
+ "scripts": {
40
+ "build": "tsup src/index.ts --format esm --clean",
41
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
42
+ "test": "vitest run",
43
+ "test:watch": "vitest",
44
+ "test:coverage": "vitest run --coverage",
45
+ "lint": "eslint src/",
46
+ "clean": "rimraf dist"
47
+ }
48
48
  }