@openviking/openclaw-plugin 2026.5.8 → 2026.5.10-dev.3

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
@@ -121,15 +121,6 @@ function getNumberFlag(flags, name) {
121
121
  function getBoolFlag(flags, name) {
122
122
  return flags.get(name) === true;
123
123
  }
124
- function parseImportKind(value) {
125
- if (!value) {
126
- return "resource";
127
- }
128
- if (value === "resource" || value === "skill") {
129
- return value;
130
- }
131
- throw new Error("--kind must be resource or skill");
132
- }
133
124
  function extractToolSenderId(ctx) {
134
125
  if (!ctx || typeof ctx !== "object") {
135
126
  return undefined;
@@ -149,23 +140,18 @@ function extractToolSenderId(ctx) {
149
140
  }
150
141
  return undefined;
151
142
  }
152
- export function parseOvImportCommandArgs(args) {
143
+ export function parseAddResourceCommandArgs(args) {
153
144
  const parsed = parseFlagArgs(args);
154
- const kind = parseImportKind(getStringFlag(parsed.flags, "kind"));
155
145
  const source = parsed.positionals.length <= 1 ? parsed.positionals[0] : parsed.positionals.join(" ").trim();
156
146
  if (!source) {
157
- throw new Error("Usage: /ov-import <source> [--kind resource|skill] [--to URI] [--parent URI] [--wait]");
147
+ throw new Error("Usage: /add-resource <source> [--to URI] [--parent URI] [--reason TEXT] [--instruction TEXT] [--wait] [--timeout SEC]");
158
148
  }
159
149
  const to = getStringFlag(parsed.flags, "to");
160
150
  const parent = getStringFlag(parsed.flags, "parent");
161
151
  if (to && parent) {
162
152
  throw new Error("Cannot specify both --to and --parent.");
163
153
  }
164
- if (kind === "skill" && (to || parent || parsed.flags.has("reason") || parsed.flags.has("instruction"))) {
165
- throw new Error("--to, --parent, --reason, and --instruction are resource-only options.");
166
- }
167
154
  return {
168
- kind,
169
155
  source,
170
156
  to,
171
157
  parent,
@@ -175,6 +161,21 @@ export function parseOvImportCommandArgs(args) {
175
161
  timeout: getNumberFlag(parsed.flags, "timeout"),
176
162
  };
177
163
  }
164
+ export function parseAddSkillCommandArgs(args) {
165
+ const parsed = parseFlagArgs(args);
166
+ const source = parsed.positionals.length <= 1 ? parsed.positionals[0] : parsed.positionals.join(" ").trim();
167
+ if (!source) {
168
+ throw new Error("Usage: /add-skill <source> [--wait] [--timeout SEC]");
169
+ }
170
+ if (parsed.flags.has("to") || parsed.flags.has("parent") || parsed.flags.has("reason") || parsed.flags.has("instruction")) {
171
+ throw new Error("--to, --parent, --reason, and --instruction are resource-only options.");
172
+ }
173
+ return {
174
+ source,
175
+ wait: getBoolFlag(parsed.flags, "wait"),
176
+ timeout: getNumberFlag(parsed.flags, "timeout"),
177
+ };
178
+ }
178
179
  export function parseMemorySearchCommandArgs(args) {
179
180
  const parsed = parseFlagArgs(args);
180
181
  // `/memory-search` only accepts a single query string, so positional segments are
@@ -417,32 +418,21 @@ const contextEnginePlugin = {
417
418
  },
418
419
  };
419
420
  };
420
- const executeImport = async (input, agentId) => {
421
- const kind = input.kind ?? "resource";
422
- if (kind === "skill") {
423
- if (input.to || input.parent || input.reason || input.instruction) {
424
- throw new Error("to, parent, reason, and instruction are resource-only options.");
425
- }
426
- return importSkill({
427
- path: input.source,
428
- data: input.data,
429
- wait: input.wait,
430
- timeout: input.timeout,
431
- }, agentId);
432
- }
433
- if (input.data !== undefined && input.data !== null) {
434
- throw new Error("data is only supported for skill imports.");
435
- }
436
- return importResource({
437
- pathOrUrl: input.source ?? "",
438
- to: input.to,
439
- parent: input.parent,
440
- reason: input.reason,
441
- instruction: input.instruction,
442
- wait: input.wait,
443
- timeout: input.timeout,
444
- }, agentId);
445
- };
421
+ const addResourceOpenViking = (input, agentId) => importResource({
422
+ pathOrUrl: input.source ?? "",
423
+ to: input.to,
424
+ parent: input.parent,
425
+ reason: input.reason,
426
+ instruction: input.instruction,
427
+ wait: input.wait,
428
+ timeout: input.timeout,
429
+ }, agentId);
430
+ const addSkillOpenViking = (input, agentId) => importSkill({
431
+ path: input.source,
432
+ data: input.data,
433
+ wait: input.wait,
434
+ timeout: input.timeout,
435
+ }, agentId);
446
436
  const mergeFindResults = (results) => {
447
437
  const deduplicate = (items) => {
448
438
  const seen = new Map();
@@ -566,30 +556,26 @@ const contextEnginePlugin = {
566
556
  };
567
557
  };
568
558
  api.registerTool((ctx) => ({
569
- name: "ov_import",
570
- label: "Import (OpenViking)",
571
- description: "Import an OpenViking resource or skill only when the user explicitly asks to import, add, or index one. " +
572
- "Defaults to resource; set kind=skill for SKILL.md, skill directories, raw skill content, or MCP tool dicts.",
559
+ name: "add_resource",
560
+ label: "Add Resource (OpenViking)",
561
+ description: "Use only when the user explicitly asks to import, add, upload, save, or index a document, directory, URL, Git repository, or OpenClaw media attachment into OpenViking resources. " +
562
+ "For a '[media attached: /path ...]' document, set source to that exact local media path. Do not invent OpenViking upload REST endpoints.",
573
563
  parameters: Type.Object({
574
- kind: Type.Optional(Type.Union([Type.Literal("resource"), Type.Literal("skill")], { description: "Import kind. Default: resource" })),
575
- source: Type.Optional(Type.String({ description: "Local path, directory path, public URL, or Git URL" })),
576
- data: Type.Optional(Type.Any({ description: "Skill only: raw SKILL.md content or MCP tool dict" })),
577
- to: Type.Optional(Type.String({ description: "Resource only: exact target URI, e.g. viking://resources/project-docs" })),
578
- parent: Type.Optional(Type.String({ description: "Resource only: parent URI under viking://resources" })),
579
- reason: Type.Optional(Type.String({ description: "Resource only: reason or note for adding this resource" })),
580
- instruction: Type.Optional(Type.String({ description: "Resource only: processing instruction for semantic extraction" })),
564
+ source: Type.String({ description: "Local path, OpenClaw media attachment path, directory path, public URL, or Git URL" }),
565
+ to: Type.Optional(Type.String({ description: "Exact target URI, e.g. viking://resources/project-docs" })),
566
+ parent: Type.Optional(Type.String({ description: "Parent URI under viking://resources" })),
567
+ reason: Type.Optional(Type.String({ description: "Reason or note for adding this resource" })),
568
+ instruction: Type.Optional(Type.String({ description: "Processing instruction for semantic extraction" })),
581
569
  wait: Type.Optional(Type.Boolean({ description: "Wait for processing to complete" })),
582
570
  timeout: Type.Optional(Type.Number({ description: "Timeout in seconds when wait is true" })),
583
571
  }),
584
572
  async execute(_toolCallId, params) {
585
573
  if (isBypassedSession(ctx)) {
586
- return makeBypassedToolResult("ov_import");
574
+ return makeBypassedToolResult("add_resource");
587
575
  }
588
576
  const session = resolvePluginSessionRouting(ctx);
589
- return executeImport({
590
- kind: params.kind === "skill" ? "skill" : "resource",
577
+ return addResourceOpenViking({
591
578
  source: typeof params.source === "string" ? params.source : undefined,
592
- data: params.data,
593
579
  to: typeof params.to === "string" ? params.to : undefined,
594
580
  parent: typeof params.parent === "string" ? params.parent : undefined,
595
581
  reason: typeof params.reason === "string" ? params.reason : undefined,
@@ -598,7 +584,31 @@ const contextEnginePlugin = {
598
584
  timeout: typeof params.timeout === "number" ? params.timeout : undefined,
599
585
  }, session.agentId);
600
586
  },
601
- }), { name: "ov_import" });
587
+ }), { name: "add_resource" });
588
+ api.registerTool((ctx) => ({
589
+ name: "add_skill",
590
+ label: "Add Skill (OpenViking)",
591
+ description: "Use only when the user explicitly asks to import, add, install, or register a skill into OpenViking. " +
592
+ "Set source to a local SKILL.md file or skill directory, or data to raw SKILL.md content or an MCP tool dict.",
593
+ parameters: Type.Object({
594
+ source: Type.Optional(Type.String({ description: "Local SKILL.md path or skill directory path" })),
595
+ data: Type.Optional(Type.Any({ description: "Raw SKILL.md content or MCP tool dict" })),
596
+ wait: Type.Optional(Type.Boolean({ description: "Wait for processing to complete" })),
597
+ timeout: Type.Optional(Type.Number({ description: "Timeout in seconds when wait is true" })),
598
+ }),
599
+ async execute(_toolCallId, params) {
600
+ if (isBypassedSession(ctx)) {
601
+ return makeBypassedToolResult("add_skill");
602
+ }
603
+ const session = resolvePluginSessionRouting(ctx);
604
+ return addSkillOpenViking({
605
+ source: typeof params.source === "string" ? params.source : undefined,
606
+ data: params.data,
607
+ wait: typeof params.wait === "boolean" ? params.wait : undefined,
608
+ timeout: typeof params.timeout === "number" ? params.timeout : undefined,
609
+ }, session.agentId);
610
+ },
611
+ }), { name: "add_skill" });
602
612
  api.registerTool((ctx) => ({
603
613
  name: "memory_search",
604
614
  label: "Memory Search (OpenViking)",
@@ -621,22 +631,42 @@ const contextEnginePlugin = {
621
631
  },
622
632
  }), { name: "memory_search" });
623
633
  api.registerCommand?.({
624
- name: "ov-import",
625
- description: "Import a resource or skill into OpenViking.",
634
+ name: "add-resource",
635
+ description: "Add a resource into OpenViking.",
636
+ acceptsArgs: true,
637
+ handler: async (ctx) => {
638
+ try {
639
+ if (isBypassedSession(ctx)) {
640
+ const bypassed = makeBypassedToolResult("add_resource");
641
+ return { text: bypassed.content[0].text, details: bypassed.details };
642
+ }
643
+ const session = resolvePluginSessionRouting(ctx);
644
+ const input = parseAddResourceCommandArgs(ctx.args ?? "");
645
+ const result = await addResourceOpenViking(input, session.agentId);
646
+ return { text: result.content[0].text, details: result.details };
647
+ }
648
+ catch (err) {
649
+ return { text: `OpenViking add resource failed: ${err instanceof Error ? err.message : String(err)}` };
650
+ }
651
+ },
652
+ });
653
+ api.registerCommand?.({
654
+ name: "add-skill",
655
+ description: "Add a skill into OpenViking.",
626
656
  acceptsArgs: true,
627
657
  handler: async (ctx) => {
628
658
  try {
629
659
  if (isBypassedSession(ctx)) {
630
- const bypassed = makeBypassedToolResult("ov_import");
660
+ const bypassed = makeBypassedToolResult("add_skill");
631
661
  return { text: bypassed.content[0].text, details: bypassed.details };
632
662
  }
633
663
  const session = resolvePluginSessionRouting(ctx);
634
- const input = parseOvImportCommandArgs(ctx.args ?? "");
635
- const result = await executeImport(input, session.agentId);
664
+ const input = parseAddSkillCommandArgs(ctx.args ?? "");
665
+ const result = await addSkillOpenViking(input, session.agentId);
636
666
  return { text: result.content[0].text, details: result.details };
637
667
  }
638
668
  catch (err) {
639
- return { text: `OpenViking import failed: ${err instanceof Error ? err.message : String(err)}` };
669
+ return { text: `OpenViking add skill failed: ${err instanceof Error ? err.message : String(err)}` };
640
670
  }
641
671
  },
642
672
  });