oricore 1.5.0 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  Session,
3
3
  SessionConfigManager,
4
4
  loadSessionMessages
5
- } from "./chunk-OYWDQD3F.js";
5
+ } from "./chunk-P4RPHQOE.js";
6
6
  import {
7
7
  Compression,
8
8
  ConfigManager,
@@ -19,8 +19,10 @@ import {
19
19
  resolveTools,
20
20
  runLoop,
21
21
  safeStringify
22
- } from "./chunk-4QYFQSAC.js";
23
- import "./chunk-DO76AL42.js";
22
+ } from "./chunk-E7TB3WLC.js";
23
+ import {
24
+ __require
25
+ } from "./chunk-D5X6YFSK.js";
24
26
 
25
27
  // src/core/context.ts
26
28
  import fs10 from "fs";
@@ -2443,6 +2445,116 @@ import degit from "degit";
2443
2445
  import fs9 from "fs";
2444
2446
  import os3 from "os";
2445
2447
  import path9 from "pathe";
2448
+
2449
+ // src/skill/bundled.ts
2450
+ var BundledSkillRegistry = class {
2451
+ skills = /* @__PURE__ */ new Map();
2452
+ aliases = /* @__PURE__ */ new Map();
2453
+ /**
2454
+ * Register a bundled skill.
2455
+ * @param definition The skill definition
2456
+ */
2457
+ register(definition) {
2458
+ if (!definition.name) {
2459
+ throw new Error("Bundled skill must have a name");
2460
+ }
2461
+ if (!definition.description) {
2462
+ throw new Error("Bundled skill must have a description");
2463
+ }
2464
+ if (!definition.getPrompt) {
2465
+ throw new Error("Bundled skill must have a getPrompt function");
2466
+ }
2467
+ this.skills.set(definition.name, definition);
2468
+ if (definition.aliases) {
2469
+ for (const alias of definition.aliases) {
2470
+ this.aliases.set(alias, definition.name);
2471
+ }
2472
+ }
2473
+ }
2474
+ /**
2475
+ * Get a bundled skill by name or alias.
2476
+ * @param name Skill name or alias
2477
+ * @returns The skill definition or undefined if not found
2478
+ */
2479
+ get(name) {
2480
+ const skill = this.skills.get(name);
2481
+ if (skill) return skill;
2482
+ const aliasedName = this.aliases.get(name);
2483
+ if (aliasedName) {
2484
+ return this.skills.get(aliasedName);
2485
+ }
2486
+ return void 0;
2487
+ }
2488
+ /**
2489
+ * Get all registered bundled skills.
2490
+ * @param context Optional context to filter by isEnabled
2491
+ * @returns Array of skill definitions
2492
+ */
2493
+ getAll(context) {
2494
+ return Array.from(this.skills.values()).filter((skill) => {
2495
+ if (skill.isEnabled === void 0) return true;
2496
+ if (typeof skill.isEnabled === "boolean") return skill.isEnabled;
2497
+ if (typeof skill.isEnabled === "function" && context) {
2498
+ return skill.isEnabled(context);
2499
+ }
2500
+ return true;
2501
+ });
2502
+ }
2503
+ /**
2504
+ * Check if a skill is registered.
2505
+ * @param name Skill name or alias
2506
+ */
2507
+ has(name) {
2508
+ return this.skills.has(name) || this.aliases.has(name);
2509
+ }
2510
+ /**
2511
+ * Unregister a skill.
2512
+ * @param name Skill name
2513
+ */
2514
+ unregister(name) {
2515
+ const skill = this.skills.get(name);
2516
+ if (skill && skill.aliases) {
2517
+ for (const alias of skill.aliases) {
2518
+ this.aliases.delete(alias);
2519
+ }
2520
+ }
2521
+ this.skills.delete(name);
2522
+ }
2523
+ /**
2524
+ * Clear all registered skills.
2525
+ */
2526
+ clear() {
2527
+ this.skills.clear();
2528
+ this.aliases.clear();
2529
+ }
2530
+ };
2531
+ var bundledSkillRegistry = new BundledSkillRegistry();
2532
+ function bundledSkillToMetadata(definition, source = "builtin") {
2533
+ return {
2534
+ name: definition.name,
2535
+ description: definition.description,
2536
+ path: `bundled://${definition.name}`,
2537
+ source,
2538
+ allowedTools: definition.allowedTools,
2539
+ context: definition.context,
2540
+ agent: definition.agent,
2541
+ userInvocable: definition.userInvocable ?? true,
2542
+ modelInvocable: definition.modelInvocable ?? true
2543
+ // Note: bundled skills don't support 'paths' conditional activation
2544
+ };
2545
+ }
2546
+ function createBundledSkill(config) {
2547
+ return {
2548
+ ...config,
2549
+ getPrompt: typeof config.prompt === "string" ? () => config.prompt : config.prompt
2550
+ };
2551
+ }
2552
+ function registerBundledSkill(config) {
2553
+ const skill = createBundledSkill(config);
2554
+ bundledSkillRegistry.register(skill);
2555
+ }
2556
+
2557
+ // src/skill/skill.ts
2446
2558
  function isDirOrSymlinkToDir(parentDir, entry) {
2447
2559
  if (entry.isDirectory()) return true;
2448
2560
  if (entry.isSymbolicLink()) {
@@ -2459,6 +2571,7 @@ var SkillSource = /* @__PURE__ */ ((SkillSource2) => {
2459
2571
  SkillSource2["Global"] = "global";
2460
2572
  SkillSource2["ProjectClaude"] = "project-claude";
2461
2573
  SkillSource2["Project"] = "project";
2574
+ SkillSource2["Builtin"] = "builtin";
2462
2575
  return SkillSource2;
2463
2576
  })(SkillSource || {});
2464
2577
  var MAX_NAME_LENGTH2 = 64;
@@ -2468,21 +2581,119 @@ var SkillManager = class {
2468
2581
  errors = [];
2469
2582
  paths;
2470
2583
  context;
2584
+ /**
2585
+ * Tracks which skills are currently "active" based on file operations.
2586
+ * Skills with `paths` frontmatter are activated when matching files are accessed.
2587
+ */
2588
+ activeSkillNames = /* @__PURE__ */ new Set();
2589
+ /**
2590
+ * Maps alias names to original skill names for bundled skills.
2591
+ */
2592
+ aliasMap = /* @__PURE__ */ new Map();
2471
2593
  constructor(opts) {
2472
2594
  this.context = opts.context;
2473
2595
  this.paths = opts.context.paths;
2474
2596
  }
2475
- getSkills() {
2476
- return Array.from(this.skillsMap.values());
2597
+ /**
2598
+ * Get all loaded skills.
2599
+ * @param options Filter options
2600
+ * @returns Array of skill metadata
2601
+ */
2602
+ getSkills(options) {
2603
+ let skills = Array.from(this.skillsMap.values());
2604
+ if (options?.userInvocable !== void 0) {
2605
+ skills = skills.filter(
2606
+ (s) => (s.userInvocable ?? true) === options.userInvocable
2607
+ );
2608
+ }
2609
+ if (options?.modelInvocable !== void 0) {
2610
+ skills = skills.filter(
2611
+ (s) => (s.modelInvocable ?? true) === options.modelInvocable
2612
+ );
2613
+ }
2614
+ if (options?.activeOnly) {
2615
+ skills = skills.filter((s) => this.activeSkillNames.has(s.name));
2616
+ }
2617
+ return skills;
2477
2618
  }
2619
+ /**
2620
+ * Get a specific skill by name.
2621
+ * Automatically resolves aliases to the original skill.
2622
+ * @param name Skill name or alias
2623
+ * @returns Skill metadata or undefined if not found
2624
+ */
2478
2625
  getSkill(name) {
2479
- return this.skillsMap.get(name);
2626
+ const skill = this.skillsMap.get(name);
2627
+ if (skill) return skill;
2628
+ const originalName = this.aliasMap.get(name);
2629
+ if (originalName) {
2630
+ return this.skillsMap.get(originalName);
2631
+ }
2632
+ return void 0;
2633
+ }
2634
+ /**
2635
+ * Check if a skill is active (has matching paths for current context).
2636
+ * @param name Skill name
2637
+ */
2638
+ isSkillActive(name) {
2639
+ return this.activeSkillNames.has(name);
2640
+ }
2641
+ /**
2642
+ * Activate skills based on file paths.
2643
+ * Skills with `paths` frontmatter that match the given paths will be activated.
2644
+ * @param filePaths Array of file paths to check
2645
+ * @returns Array of newly activated skill names
2646
+ */
2647
+ activateSkillsForPaths(filePaths) {
2648
+ const newlyActivated = [];
2649
+ const minimatch = __require("minimatch");
2650
+ for (const [name, skill] of this.skillsMap) {
2651
+ if (skill.paths && skill.paths.length > 0) {
2652
+ const isMatch = skill.paths.some(
2653
+ (pattern) => filePaths.some((filePath) => minimatch(filePath, pattern))
2654
+ );
2655
+ if (isMatch && !this.activeSkillNames.has(name)) {
2656
+ this.activeSkillNames.add(name);
2657
+ newlyActivated.push(name);
2658
+ }
2659
+ }
2660
+ }
2661
+ return newlyActivated;
2662
+ }
2663
+ /**
2664
+ * Clear all active skill activations.
2665
+ * Useful when switching contexts or projects.
2666
+ */
2667
+ clearActiveSkills() {
2668
+ this.activeSkillNames.clear();
2669
+ }
2670
+ /**
2671
+ * Get all skills that have path-based conditional activation.
2672
+ * @returns Array of skills with paths defined
2673
+ */
2674
+ getConditionalSkills() {
2675
+ return Array.from(this.skillsMap.values()).filter(
2676
+ (s) => s.paths && s.paths.length > 0
2677
+ );
2480
2678
  }
2481
2679
  getErrors() {
2482
2680
  return this.errors;
2483
2681
  }
2484
- async readSkillBody(skill) {
2682
+ /**
2683
+ * Read the body content of a skill.
2684
+ * For file-based skills, reads from disk.
2685
+ * For bundled skills, generates content via getPrompt.
2686
+ */
2687
+ async readSkillBody(skill, args = "") {
2485
2688
  try {
2689
+ if (skill.path.startsWith("bundled://")) {
2690
+ const bundledName = skill.path.replace("bundled://", "");
2691
+ const bundledSkill = bundledSkillRegistry.get(bundledName);
2692
+ if (!bundledSkill) {
2693
+ throw new Error(`Bundled skill "${bundledName}" not found in registry`);
2694
+ }
2695
+ return await bundledSkill.getPrompt(args, this.context);
2696
+ }
2486
2697
  const content = fs9.readFileSync(skill.path, "utf-8");
2487
2698
  const { body } = safeFrontMatter(content, skill.path);
2488
2699
  return body;
@@ -2491,9 +2702,26 @@ var SkillManager = class {
2491
2702
  throw new Error(`Failed to read skill ${skill.name}: ${message}`);
2492
2703
  }
2493
2704
  }
2705
+ /**
2706
+ * Get a bundled skill definition by name.
2707
+ * @param name Bundled skill name
2708
+ * @returns Bundled skill definition or undefined if not found
2709
+ */
2710
+ getBundledSkill(name) {
2711
+ return bundledSkillRegistry.get(name);
2712
+ }
2713
+ /**
2714
+ * Register a bundled skill programmatically.
2715
+ * @param definition Bundled skill definition
2716
+ */
2717
+ registerBundledSkill(definition) {
2718
+ bundledSkillRegistry.register(definition);
2719
+ this.loadBuiltinSkills();
2720
+ }
2494
2721
  async loadSkills() {
2495
2722
  this.skillsMap.clear();
2496
2723
  this.errors = [];
2724
+ this.loadBuiltinSkills();
2497
2725
  const pluginSkills = await this.context.apply({
2498
2726
  hook: "skill",
2499
2727
  args: [],
@@ -2536,6 +2764,22 @@ var SkillManager = class {
2536
2764
  const projectDir = path9.join(this.paths.projectConfigDir, "skills");
2537
2765
  this.loadSkillsFromDirectory(projectDir, "project" /* Project */);
2538
2766
  }
2767
+ /**
2768
+ * Load builtin/bundled skills from the registry.
2769
+ */
2770
+ loadBuiltinSkills() {
2771
+ this.aliasMap.clear();
2772
+ const bundledSkills = bundledSkillRegistry.getAll(this.context);
2773
+ for (const skill of bundledSkills) {
2774
+ const metadata = bundledSkillToMetadata(skill, "builtin" /* Builtin */);
2775
+ this.skillsMap.set(skill.name, metadata);
2776
+ if (skill.aliases) {
2777
+ for (const alias of skill.aliases) {
2778
+ this.aliasMap.set(alias, skill.name);
2779
+ }
2780
+ }
2781
+ }
2782
+ }
2539
2783
  loadSkillsFromDirectory(skillsDir, source) {
2540
2784
  if (!fs9.existsSync(skillsDir)) {
2541
2785
  return;
@@ -2611,10 +2855,19 @@ var SkillManager = class {
2611
2855
  });
2612
2856
  return null;
2613
2857
  }
2858
+ const allowedTools = this.parseStringArrayField(attributes.allowedTools);
2859
+ const context = attributes.context === "inline" || attributes.context === "fork" ? attributes.context : void 0;
2860
+ const paths = this.parseStringArrayField(attributes.paths);
2614
2861
  return {
2615
2862
  name: attributes.name,
2616
2863
  description: attributes.description,
2617
- path: skillPath
2864
+ path: skillPath,
2865
+ allowedTools,
2866
+ context,
2867
+ agent: attributes.agent,
2868
+ paths,
2869
+ userInvocable: attributes.userInvocable ?? true,
2870
+ modelInvocable: attributes.modelInvocable ?? true
2618
2871
  };
2619
2872
  } catch (error) {
2620
2873
  this.errors.push({
@@ -2624,6 +2877,21 @@ var SkillManager = class {
2624
2877
  return null;
2625
2878
  }
2626
2879
  }
2880
+ /**
2881
+ * Parse a field that can be either a comma-separated string or an array of strings.
2882
+ * @param value The value to parse
2883
+ * @returns Array of strings or undefined if empty
2884
+ */
2885
+ parseStringArrayField(value) {
2886
+ if (!value) return void 0;
2887
+ if (Array.isArray(value)) {
2888
+ return value.map((item) => item.trim()).filter((item) => item.length > 0);
2889
+ }
2890
+ if (typeof value === "string") {
2891
+ return value.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
2892
+ }
2893
+ return void 0;
2894
+ }
2627
2895
  async addSkill(source, options = {}) {
2628
2896
  const {
2629
2897
  global: isGlobal = false,
@@ -4013,12 +4281,12 @@ var Engine = class {
4013
4281
  const systemPrompt = context.config.systemPrompt || "";
4014
4282
  let sessionHistory = void 0;
4015
4283
  if (options.sessionId) {
4016
- const { loadSessionMessages: loadSessionMessages2 } = await import("./session-QMS6OYG2.js");
4284
+ const { loadSessionMessages: loadSessionMessages2 } = await import("./session-Z2XIKFVN.js");
4017
4285
  const logPath = context.paths.getSessionLogPath(sessionId);
4018
4286
  try {
4019
4287
  const existingMessages = loadSessionMessages2({ logPath });
4020
4288
  if (existingMessages.length > 0) {
4021
- const { History: History2 } = await import("./history-AGNMX5YW.js");
4289
+ const { History: History2 } = await import("./history-WTZON3PI.js");
4022
4290
  sessionHistory = new History2({
4023
4291
  messages: existingMessages
4024
4292
  });
@@ -4220,6 +4488,9 @@ export {
4220
4488
  Usage,
4221
4489
  brainstormMode,
4222
4490
  builtinModes,
4491
+ bundledSkillRegistry,
4492
+ bundledSkillToMetadata,
4493
+ createBundledSkill,
4223
4494
  createEngine,
4224
4495
  debugMode,
4225
4496
  defaultMode,
@@ -4231,6 +4502,7 @@ export {
4231
4502
  planMode,
4232
4503
  randomUUID,
4233
4504
  registerBuiltinModes,
4505
+ registerBundledSkill,
4234
4506
  reviewMode
4235
4507
  };
4236
4508
  //# sourceMappingURL=index.js.map