botlearn 0.0.1 → 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 BotLearn
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,25 +1,106 @@
1
1
  # botlearn
2
2
 
3
- Official Node.js SDK for [BotLearn.ai](https://www.botlearn.ai/) - AI-powered bot learning platform.
3
+ BotLearn OpenClaw Skills SDK types, validator, and utilities for `@botlearn/*` skill packages.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
+ # Install the SDK (for building custom skills or tools)
8
9
  npm install botlearn
9
- # or
10
- pnpm add botlearn
11
- # or
12
- yarn add botlearn
10
+
11
+ # Install individual skills into your Agent
12
+ npm install @botlearn/google-search
13
+ npm install @botlearn/code-gen
14
+ clawhub install @botlearn/google-search
15
+ ```
16
+
17
+ ## Skills
18
+
19
+ ### Information Retrieval (5)
20
+
21
+ | Skill | Description | Dependencies |
22
+ |-------|-------------|-------------|
23
+ | `@botlearn/google-search` | Web search query optimization and result curation | — |
24
+ | `@botlearn/academic-search` | Academic paper discovery and literature review | google-search |
25
+ | `@botlearn/rss-manager` | RSS/Atom feed monitoring, deduplication, and digest generation | — |
26
+ | `@botlearn/twitter-intel` | Twitter/X intelligence gathering and trend analysis | — |
27
+ | `@botlearn/reddit-tracker` | Reddit trend detection and cross-subreddit correlation | — |
28
+
29
+ ### Content Processing (5)
30
+
31
+ | Skill | Description | Dependencies |
32
+ |-------|-------------|-------------|
33
+ | `@botlearn/summarizer` | Multi-format content summarization with discourse analysis | — |
34
+ | `@botlearn/translator` | Context-aware translation with terminology management | — |
35
+ | `@botlearn/rewriter` | Audience-adaptive content rewriting and style transformation | summarizer |
36
+ | `@botlearn/keyword-extractor` | Multi-layer keyword and keyphrase extraction | — |
37
+ | `@botlearn/sentiment-analyzer` | Aspect-level sentiment analysis with sarcasm detection | — |
38
+
39
+ ### Programming Assistance (5)
40
+
41
+ | Skill | Description | Dependencies |
42
+ |-------|-------------|-------------|
43
+ | `@botlearn/code-gen` | Multi-language code generation with architecture-aware design | — |
44
+ | `@botlearn/code-review` | Security, performance, and quality code review (OWASP Top 10) | — |
45
+ | `@botlearn/debugger` | Systematic bug diagnosis and root cause analysis | code-review |
46
+ | `@botlearn/refactor` | Design-pattern-driven code refactoring | code-review |
47
+ | `@botlearn/doc-gen` | API documentation and README generation | code-gen |
48
+
49
+ ### Creative Generation (5)
50
+
51
+ | Skill | Description | Dependencies |
52
+ |-------|-------------|-------------|
53
+ | `@botlearn/brainstorm` | Structured creative ideation (SCAMPER, Six Hats, TRIZ) | — |
54
+ | `@botlearn/storyteller` | Narrative craft across genres and structures | — |
55
+ | `@botlearn/writer` | Long-form article writing with argument frameworks | summarizer, keyword-extractor |
56
+ | `@botlearn/copywriter` | Persuasion-framework-driven marketing copy | sentiment-analyzer |
57
+ | `@botlearn/social-media` | Platform-native social media content creation | copywriter |
58
+
59
+ ## Skill Package Structure
60
+
61
+ Each skill is an independent npm package with a standardized structure:
62
+
63
+ ```
64
+ @botlearn/<skill-name>/ # npm package
65
+ ├── package.json # npm package config
66
+ ├── manifest.json # Skill metadata: category, benchmark dimension
67
+ ├── skill.md # Role definition, triggers, activation rules
68
+ ├── knowledge/
69
+ │ ├── domain.md # Domain expertise
70
+ │ ├── best-practices.md # Quality standards
71
+ │ └── anti-patterns.md # Common mistakes to avoid
72
+ ├── strategies/
73
+ │ └── main.md # Step-by-step behavioral strategy
74
+ └── tests/
75
+ ├── smoke.json # 1 task, < 60s, pass threshold 60/100
76
+ └── benchmark.json # 10 tasks (3 easy, 4 medium, 3 hard)
13
77
  ```
14
78
 
15
- ## Usage
79
+ ## SDK API
16
80
 
17
81
  ```typescript
18
- import { hello } from 'botlearn';
82
+ import { validateManifest } from "botlearn";
83
+ import type { SkillManifest, ValidationResult } from "botlearn";
19
84
 
20
- console.log(hello('Bot')); // Hello, Bot!
85
+ // Validate a manifest
86
+ const result: ValidationResult = validateManifest(manifest, knownSkillNames);
87
+ console.log(result.valid, result.errors);
21
88
  ```
22
89
 
90
+ ## Publishing
91
+
92
+ Each skill is published independently to npm:
93
+
94
+ ```bash
95
+ cd packages/skills/google-search
96
+ npm publish --access public # publishes @botlearn/google-search
97
+ ```
98
+
99
+ ## Compatibility
100
+
101
+ - OpenClaw Agent: `>=0.5.0`
102
+ - Node.js: `>=18`
103
+
23
104
  ## License
24
105
 
25
106
  MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ VALID_CATEGORIES: () => VALID_CATEGORIES,
24
+ VALID_DIMENSIONS: () => VALID_DIMENSIONS,
25
+ validateManifest: () => validateManifest
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+
29
+ // src/validator.ts
30
+ var VALID_CATEGORIES = [
31
+ "information-retrieval",
32
+ "content-processing",
33
+ "programming-assistance",
34
+ "creative-generation"
35
+ ];
36
+ var VALID_DIMENSIONS = [
37
+ "information-retrieval",
38
+ "content-understanding",
39
+ "logical-reasoning",
40
+ "code-generation",
41
+ "creative-generation"
42
+ ];
43
+ var SEMVER_RE = /^\d+\.\d+\.\d+(?:-[\w.]+)?(?:\+[\w.]+)?$/;
44
+ var SEMVER_RANGE_RE = /^(?:[~^]?\d+\.\d+\.\d+(?:-[\w.]+)?|>=?\d+\.\d+\.\d+)$/;
45
+ var SKILL_NAME_RE = /^@botlearn\/[a-z][a-z0-9-]*$/;
46
+ function validateManifest(manifest, knownSkillNames) {
47
+ const errors = [];
48
+ if (manifest === null || typeof manifest !== "object") {
49
+ return { valid: false, errors: [{ field: "(root)", message: "Manifest must be a non-null object" }] };
50
+ }
51
+ const m = manifest;
52
+ requireString(m, "name", errors);
53
+ requireString(m, "version", errors);
54
+ requireString(m, "description", errors);
55
+ requireString(m, "author", errors);
56
+ if (typeof m.name === "string" && !SKILL_NAME_RE.test(m.name)) {
57
+ errors.push({
58
+ field: "name",
59
+ message: `Name must match @botlearn/<kebab-case>, got "${m.name}"`
60
+ });
61
+ }
62
+ if (typeof m.version === "string" && !SEMVER_RE.test(m.version)) {
63
+ errors.push({
64
+ field: "version",
65
+ message: `Version must be valid semver, got "${m.version}"`
66
+ });
67
+ }
68
+ if (!VALID_CATEGORIES.includes(m.category)) {
69
+ errors.push({
70
+ field: "category",
71
+ message: `Category must be one of: ${VALID_CATEGORIES.join(", ")}`
72
+ });
73
+ }
74
+ if (!VALID_DIMENSIONS.includes(m.benchmarkDimension)) {
75
+ errors.push({
76
+ field: "benchmarkDimension",
77
+ message: `benchmarkDimension must be one of: ${VALID_DIMENSIONS.join(", ")}`
78
+ });
79
+ }
80
+ if (typeof m.expectedImprovement !== "number" || m.expectedImprovement < 0) {
81
+ errors.push({
82
+ field: "expectedImprovement",
83
+ message: "expectedImprovement must be a non-negative number"
84
+ });
85
+ }
86
+ if (m.dependencies !== void 0) {
87
+ if (typeof m.dependencies !== "object" || m.dependencies === null) {
88
+ errors.push({
89
+ field: "dependencies",
90
+ message: "dependencies must be an object"
91
+ });
92
+ } else {
93
+ const deps = m.dependencies;
94
+ for (const [depName, depVersion] of Object.entries(deps)) {
95
+ if (!SKILL_NAME_RE.test(depName)) {
96
+ errors.push({
97
+ field: `dependencies.${depName}`,
98
+ message: `Dependency name must match @botlearn/<kebab-case>`
99
+ });
100
+ }
101
+ if (typeof depVersion !== "string" || !SEMVER_RANGE_RE.test(depVersion)) {
102
+ errors.push({
103
+ field: `dependencies.${depName}`,
104
+ message: `Dependency version must be a valid semver range, got "${String(depVersion)}"`
105
+ });
106
+ }
107
+ if (knownSkillNames && !knownSkillNames.includes(depName)) {
108
+ errors.push({
109
+ field: `dependencies.${depName}`,
110
+ message: `Unknown dependency "${depName}" \u2014 not in known skills list`
111
+ });
112
+ }
113
+ }
114
+ }
115
+ }
116
+ if (typeof m.compatibility !== "object" || m.compatibility === null) {
117
+ errors.push({
118
+ field: "compatibility",
119
+ message: "compatibility must be an object with an openclaw field"
120
+ });
121
+ } else {
122
+ const compat = m.compatibility;
123
+ if (typeof compat.openclaw !== "string" || !SEMVER_RANGE_RE.test(compat.openclaw)) {
124
+ errors.push({
125
+ field: "compatibility.openclaw",
126
+ message: `compatibility.openclaw must be a valid semver range`
127
+ });
128
+ }
129
+ }
130
+ if (typeof m.files !== "object" || m.files === null) {
131
+ errors.push({
132
+ field: "files",
133
+ message: "files must be an object"
134
+ });
135
+ } else {
136
+ const files = m.files;
137
+ requireString(files, "skill", errors, "files.skill");
138
+ requireStringArray(files, "knowledge", errors, "files.knowledge");
139
+ requireStringArray(files, "strategies", errors, "files.strategies");
140
+ requireString(files, "smokeTest", errors, "files.smokeTest");
141
+ requireString(files, "benchmark", errors, "files.benchmark");
142
+ }
143
+ return { valid: errors.length === 0, errors };
144
+ }
145
+ function requireString(obj, field, errors, displayField) {
146
+ if (typeof obj[field] !== "string" || obj[field].length === 0) {
147
+ errors.push({
148
+ field: displayField ?? field,
149
+ message: `${displayField ?? field} is required and must be a non-empty string`
150
+ });
151
+ }
152
+ }
153
+ function requireStringArray(obj, field, errors, displayField) {
154
+ const val = obj[field];
155
+ if (!Array.isArray(val) || val.length === 0) {
156
+ errors.push({
157
+ field: displayField ?? field,
158
+ message: `${displayField ?? field} must be a non-empty array of strings`
159
+ });
160
+ } else if (val.some((item) => typeof item !== "string")) {
161
+ errors.push({
162
+ field: displayField ?? field,
163
+ message: `${displayField ?? field} must contain only strings`
164
+ });
165
+ }
166
+ }
167
+ // Annotate the CommonJS export names for ESM import in node:
168
+ 0 && (module.exports = {
169
+ VALID_CATEGORIES,
170
+ VALID_DIMENSIONS,
171
+ validateManifest
172
+ });
@@ -0,0 +1,150 @@
1
+ type SkillCategory = "information-retrieval" | "content-processing" | "programming-assistance" | "creative-generation";
2
+ type BenchmarkDimension = "information-retrieval" | "content-understanding" | "logical-reasoning" | "code-generation" | "creative-generation";
3
+ type Difficulty = "easy" | "medium" | "hard";
4
+ type Priority = "high" | "medium" | "low";
5
+ type SkillPhase = "retrieval" | "reasoning" | "verification" | "reflection";
6
+ type IssueSeverity = "critical" | "high" | "medium" | "low";
7
+ interface SkillManifest {
8
+ name: string;
9
+ version: string;
10
+ description: string;
11
+ category: SkillCategory;
12
+ author: string;
13
+ benchmarkDimension: BenchmarkDimension;
14
+ expectedImprovement: number;
15
+ dependencies: Record<string, string>;
16
+ compatibility: {
17
+ openclaw: string;
18
+ };
19
+ files: {
20
+ skill: string;
21
+ knowledge: string[];
22
+ strategies: string[];
23
+ smokeTest: string;
24
+ benchmark: string;
25
+ };
26
+ }
27
+ interface RubricItem {
28
+ criterion: string;
29
+ weight: number;
30
+ scoring: {
31
+ 5: string;
32
+ 3: string;
33
+ 1: string;
34
+ 0: string;
35
+ };
36
+ }
37
+ interface SmokeTestTask {
38
+ id: string;
39
+ description: string;
40
+ input: string;
41
+ rubric: RubricItem[];
42
+ passThreshold: number;
43
+ }
44
+ interface SmokeTest {
45
+ version: string;
46
+ timeout: number;
47
+ tasks: SmokeTestTask[];
48
+ }
49
+ interface BenchmarkTask {
50
+ id: string;
51
+ difficulty: Difficulty;
52
+ description: string;
53
+ input: string;
54
+ rubric: RubricItem[];
55
+ expectedScoreWithout: number;
56
+ expectedScoreWith: number;
57
+ }
58
+ interface BenchmarkTest {
59
+ version: string;
60
+ dimension: BenchmarkDimension;
61
+ tasks: BenchmarkTask[];
62
+ }
63
+ interface MemoryDocument {
64
+ id: string;
65
+ content: string;
66
+ metadata: {
67
+ domain: string;
68
+ topic: string;
69
+ priority: Priority;
70
+ ttl?: string;
71
+ };
72
+ }
73
+ interface MemoryInjectRequest {
74
+ skillName: string;
75
+ documents: MemoryDocument[];
76
+ }
77
+ interface MemoryInjectResponse {
78
+ injected: number;
79
+ skipped: number;
80
+ errors: string[];
81
+ }
82
+ interface MemoryRollbackRequest {
83
+ skillName: string;
84
+ }
85
+ interface StrategyDocument {
86
+ id: string;
87
+ content: string;
88
+ steps: number;
89
+ }
90
+ interface SkillRegisterRequest {
91
+ skillName: string;
92
+ definition: string;
93
+ strategies: StrategyDocument[];
94
+ triggers: string[];
95
+ }
96
+ interface SkillRegisterResponse {
97
+ registered: boolean;
98
+ activeSkills: string[];
99
+ }
100
+ interface SkillUnregisterRequest {
101
+ skillName: string;
102
+ }
103
+ interface BenchmarkRunRequest {
104
+ tasks: Array<{
105
+ id: string;
106
+ input: string;
107
+ rubric: RubricItem[];
108
+ }>;
109
+ judgeModel: string;
110
+ runs: number;
111
+ }
112
+ interface TaskResult {
113
+ taskId: string;
114
+ output: string;
115
+ scores: number[];
116
+ medianScore: number;
117
+ rubricBreakdown: Array<{
118
+ criterion: string;
119
+ score: number;
120
+ feedback: string;
121
+ }>;
122
+ }
123
+ interface BenchmarkRunResponse {
124
+ results: TaskResult[];
125
+ aggregateScore: number;
126
+ }
127
+ interface SkillError {
128
+ skill: string;
129
+ phase: SkillPhase;
130
+ message: string;
131
+ recoverable: boolean;
132
+ suggestion?: string;
133
+ }
134
+ interface ValidationResult {
135
+ valid: boolean;
136
+ errors: ValidationError[];
137
+ }
138
+ interface ValidationError {
139
+ field: string;
140
+ message: string;
141
+ }
142
+
143
+ declare const VALID_CATEGORIES: SkillCategory[];
144
+ declare const VALID_DIMENSIONS: BenchmarkDimension[];
145
+ /**
146
+ * Validate a SkillManifest object and return all discovered errors.
147
+ */
148
+ declare function validateManifest(manifest: unknown, knownSkillNames?: string[]): ValidationResult;
149
+
150
+ export { type BenchmarkDimension, type BenchmarkRunRequest, type BenchmarkRunResponse, type BenchmarkTask, type BenchmarkTest, type Difficulty, type IssueSeverity, type MemoryDocument, type MemoryInjectRequest, type MemoryInjectResponse, type MemoryRollbackRequest, type Priority, type RubricItem, type SkillCategory, type SkillError, type SkillManifest, type SkillPhase, type SkillRegisterRequest, type SkillRegisterResponse, type SkillUnregisterRequest, type SmokeTest, type SmokeTestTask, type StrategyDocument, type TaskResult, VALID_CATEGORIES, VALID_DIMENSIONS, type ValidationError, type ValidationResult, validateManifest };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,150 @@
1
+ type SkillCategory = "information-retrieval" | "content-processing" | "programming-assistance" | "creative-generation";
2
+ type BenchmarkDimension = "information-retrieval" | "content-understanding" | "logical-reasoning" | "code-generation" | "creative-generation";
3
+ type Difficulty = "easy" | "medium" | "hard";
4
+ type Priority = "high" | "medium" | "low";
5
+ type SkillPhase = "retrieval" | "reasoning" | "verification" | "reflection";
6
+ type IssueSeverity = "critical" | "high" | "medium" | "low";
7
+ interface SkillManifest {
8
+ name: string;
9
+ version: string;
10
+ description: string;
11
+ category: SkillCategory;
12
+ author: string;
13
+ benchmarkDimension: BenchmarkDimension;
14
+ expectedImprovement: number;
15
+ dependencies: Record<string, string>;
16
+ compatibility: {
17
+ openclaw: string;
18
+ };
19
+ files: {
20
+ skill: string;
21
+ knowledge: string[];
22
+ strategies: string[];
23
+ smokeTest: string;
24
+ benchmark: string;
25
+ };
26
+ }
27
+ interface RubricItem {
28
+ criterion: string;
29
+ weight: number;
30
+ scoring: {
31
+ 5: string;
32
+ 3: string;
33
+ 1: string;
34
+ 0: string;
35
+ };
36
+ }
37
+ interface SmokeTestTask {
38
+ id: string;
39
+ description: string;
40
+ input: string;
41
+ rubric: RubricItem[];
42
+ passThreshold: number;
43
+ }
44
+ interface SmokeTest {
45
+ version: string;
46
+ timeout: number;
47
+ tasks: SmokeTestTask[];
48
+ }
49
+ interface BenchmarkTask {
50
+ id: string;
51
+ difficulty: Difficulty;
52
+ description: string;
53
+ input: string;
54
+ rubric: RubricItem[];
55
+ expectedScoreWithout: number;
56
+ expectedScoreWith: number;
57
+ }
58
+ interface BenchmarkTest {
59
+ version: string;
60
+ dimension: BenchmarkDimension;
61
+ tasks: BenchmarkTask[];
62
+ }
63
+ interface MemoryDocument {
64
+ id: string;
65
+ content: string;
66
+ metadata: {
67
+ domain: string;
68
+ topic: string;
69
+ priority: Priority;
70
+ ttl?: string;
71
+ };
72
+ }
73
+ interface MemoryInjectRequest {
74
+ skillName: string;
75
+ documents: MemoryDocument[];
76
+ }
77
+ interface MemoryInjectResponse {
78
+ injected: number;
79
+ skipped: number;
80
+ errors: string[];
81
+ }
82
+ interface MemoryRollbackRequest {
83
+ skillName: string;
84
+ }
85
+ interface StrategyDocument {
86
+ id: string;
87
+ content: string;
88
+ steps: number;
89
+ }
90
+ interface SkillRegisterRequest {
91
+ skillName: string;
92
+ definition: string;
93
+ strategies: StrategyDocument[];
94
+ triggers: string[];
95
+ }
96
+ interface SkillRegisterResponse {
97
+ registered: boolean;
98
+ activeSkills: string[];
99
+ }
100
+ interface SkillUnregisterRequest {
101
+ skillName: string;
102
+ }
103
+ interface BenchmarkRunRequest {
104
+ tasks: Array<{
105
+ id: string;
106
+ input: string;
107
+ rubric: RubricItem[];
108
+ }>;
109
+ judgeModel: string;
110
+ runs: number;
111
+ }
112
+ interface TaskResult {
113
+ taskId: string;
114
+ output: string;
115
+ scores: number[];
116
+ medianScore: number;
117
+ rubricBreakdown: Array<{
118
+ criterion: string;
119
+ score: number;
120
+ feedback: string;
121
+ }>;
122
+ }
123
+ interface BenchmarkRunResponse {
124
+ results: TaskResult[];
125
+ aggregateScore: number;
126
+ }
127
+ interface SkillError {
128
+ skill: string;
129
+ phase: SkillPhase;
130
+ message: string;
131
+ recoverable: boolean;
132
+ suggestion?: string;
133
+ }
134
+ interface ValidationResult {
135
+ valid: boolean;
136
+ errors: ValidationError[];
137
+ }
138
+ interface ValidationError {
139
+ field: string;
140
+ message: string;
141
+ }
142
+
143
+ declare const VALID_CATEGORIES: SkillCategory[];
144
+ declare const VALID_DIMENSIONS: BenchmarkDimension[];
1
145
  /**
2
- * Botlearn - A Node.js toolkit for bot learning
3
- */
4
- declare const version = "0.0.1";
5
- /**
6
- * 示例函数
146
+ * Validate a SkillManifest object and return all discovered errors.
7
147
  */
8
- declare function hello(name?: string): string;
148
+ declare function validateManifest(manifest: unknown, knownSkillNames?: string[]): ValidationResult;
9
149
 
10
- export { hello, version };
150
+ export { type BenchmarkDimension, type BenchmarkRunRequest, type BenchmarkRunResponse, type BenchmarkTask, type BenchmarkTest, type Difficulty, type IssueSeverity, type MemoryDocument, type MemoryInjectRequest, type MemoryInjectResponse, type MemoryRollbackRequest, type Priority, type RubricItem, type SkillCategory, type SkillError, type SkillManifest, type SkillPhase, type SkillRegisterRequest, type SkillRegisterResponse, type SkillUnregisterRequest, type SmokeTest, type SmokeTestTask, type StrategyDocument, type TaskResult, VALID_CATEGORIES, VALID_DIMENSIONS, type ValidationError, type ValidationResult, validateManifest };
package/dist/index.js CHANGED
@@ -1,36 +1,143 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
1
+ // src/validator.ts
2
+ var VALID_CATEGORIES = [
3
+ "information-retrieval",
4
+ "content-processing",
5
+ "programming-assistance",
6
+ "creative-generation"
7
+ ];
8
+ var VALID_DIMENSIONS = [
9
+ "information-retrieval",
10
+ "content-understanding",
11
+ "logical-reasoning",
12
+ "code-generation",
13
+ "creative-generation"
14
+ ];
15
+ var SEMVER_RE = /^\d+\.\d+\.\d+(?:-[\w.]+)?(?:\+[\w.]+)?$/;
16
+ var SEMVER_RANGE_RE = /^(?:[~^]?\d+\.\d+\.\d+(?:-[\w.]+)?|>=?\d+\.\d+\.\d+)$/;
17
+ var SKILL_NAME_RE = /^@botlearn\/[a-z][a-z0-9-]*$/;
18
+ function validateManifest(manifest, knownSkillNames) {
19
+ const errors = [];
20
+ if (manifest === null || typeof manifest !== "object") {
21
+ return { valid: false, errors: [{ field: "(root)", message: "Manifest must be a non-null object" }] };
22
+ }
23
+ const m = manifest;
24
+ requireString(m, "name", errors);
25
+ requireString(m, "version", errors);
26
+ requireString(m, "description", errors);
27
+ requireString(m, "author", errors);
28
+ if (typeof m.name === "string" && !SKILL_NAME_RE.test(m.name)) {
29
+ errors.push({
30
+ field: "name",
31
+ message: `Name must match @botlearn/<kebab-case>, got "${m.name}"`
32
+ });
33
+ }
34
+ if (typeof m.version === "string" && !SEMVER_RE.test(m.version)) {
35
+ errors.push({
36
+ field: "version",
37
+ message: `Version must be valid semver, got "${m.version}"`
38
+ });
39
+ }
40
+ if (!VALID_CATEGORIES.includes(m.category)) {
41
+ errors.push({
42
+ field: "category",
43
+ message: `Category must be one of: ${VALID_CATEGORIES.join(", ")}`
44
+ });
45
+ }
46
+ if (!VALID_DIMENSIONS.includes(m.benchmarkDimension)) {
47
+ errors.push({
48
+ field: "benchmarkDimension",
49
+ message: `benchmarkDimension must be one of: ${VALID_DIMENSIONS.join(", ")}`
50
+ });
51
+ }
52
+ if (typeof m.expectedImprovement !== "number" || m.expectedImprovement < 0) {
53
+ errors.push({
54
+ field: "expectedImprovement",
55
+ message: "expectedImprovement must be a non-negative number"
56
+ });
57
+ }
58
+ if (m.dependencies !== void 0) {
59
+ if (typeof m.dependencies !== "object" || m.dependencies === null) {
60
+ errors.push({
61
+ field: "dependencies",
62
+ message: "dependencies must be an object"
63
+ });
64
+ } else {
65
+ const deps = m.dependencies;
66
+ for (const [depName, depVersion] of Object.entries(deps)) {
67
+ if (!SKILL_NAME_RE.test(depName)) {
68
+ errors.push({
69
+ field: `dependencies.${depName}`,
70
+ message: `Dependency name must match @botlearn/<kebab-case>`
71
+ });
72
+ }
73
+ if (typeof depVersion !== "string" || !SEMVER_RANGE_RE.test(depVersion)) {
74
+ errors.push({
75
+ field: `dependencies.${depName}`,
76
+ message: `Dependency version must be a valid semver range, got "${String(depVersion)}"`
77
+ });
78
+ }
79
+ if (knownSkillNames && !knownSkillNames.includes(depName)) {
80
+ errors.push({
81
+ field: `dependencies.${depName}`,
82
+ message: `Unknown dependency "${depName}" \u2014 not in known skills list`
83
+ });
84
+ }
85
+ }
86
+ }
87
+ }
88
+ if (typeof m.compatibility !== "object" || m.compatibility === null) {
89
+ errors.push({
90
+ field: "compatibility",
91
+ message: "compatibility must be an object with an openclaw field"
92
+ });
93
+ } else {
94
+ const compat = m.compatibility;
95
+ if (typeof compat.openclaw !== "string" || !SEMVER_RANGE_RE.test(compat.openclaw)) {
96
+ errors.push({
97
+ field: "compatibility.openclaw",
98
+ message: `compatibility.openclaw must be a valid semver range`
99
+ });
100
+ }
101
+ }
102
+ if (typeof m.files !== "object" || m.files === null) {
103
+ errors.push({
104
+ field: "files",
105
+ message: "files must be an object"
106
+ });
107
+ } else {
108
+ const files = m.files;
109
+ requireString(files, "skill", errors, "files.skill");
110
+ requireStringArray(files, "knowledge", errors, "files.knowledge");
111
+ requireStringArray(files, "strategies", errors, "files.strategies");
112
+ requireString(files, "smokeTest", errors, "files.smokeTest");
113
+ requireString(files, "benchmark", errors, "files.benchmark");
114
+ }
115
+ return { valid: errors.length === 0, errors };
116
+ }
117
+ function requireString(obj, field, errors, displayField) {
118
+ if (typeof obj[field] !== "string" || obj[field].length === 0) {
119
+ errors.push({
120
+ field: displayField ?? field,
121
+ message: `${displayField ?? field} is required and must be a non-empty string`
122
+ });
15
123
  }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- hello: () => hello,
24
- version: () => version
25
- });
26
- module.exports = __toCommonJS(index_exports);
27
- var version = "0.0.1";
28
- function hello(name = "World") {
29
- return `Hello, ${name}!`;
30
124
  }
31
- // Annotate the CommonJS export names for ESM import in node:
32
- 0 && (module.exports = {
33
- hello,
34
- version
35
- });
36
- //# sourceMappingURL=index.js.map
125
+ function requireStringArray(obj, field, errors, displayField) {
126
+ const val = obj[field];
127
+ if (!Array.isArray(val) || val.length === 0) {
128
+ errors.push({
129
+ field: displayField ?? field,
130
+ message: `${displayField ?? field} must be a non-empty array of strings`
131
+ });
132
+ } else if (val.some((item) => typeof item !== "string")) {
133
+ errors.push({
134
+ field: displayField ?? field,
135
+ message: `${displayField ?? field} must contain only strings`
136
+ });
137
+ }
138
+ }
139
+ export {
140
+ VALID_CATEGORIES,
141
+ VALID_DIMENSIONS,
142
+ validateManifest
143
+ };
package/package.json CHANGED
@@ -1,45 +1,48 @@
1
1
  {
2
2
  "name": "botlearn",
3
- "version": "0.0.1",
4
- "description": "Official Node.js SDK for BotLearn.ai - AI-powered bot learning platform",
5
- "homepage": "https://www.botlearn.ai",
6
- "type": "commonjs",
7
- "main": "./dist/index.js",
8
- "module": "./dist/index.mjs",
9
- "types": "./dist/index.d.ts",
3
+ "version": "0.1.0",
4
+ "description": "BotLearn OpenClaw Skills SDK types, validator, and utilities for @botlearn/* skill packages",
5
+ "type": "module",
10
6
  "exports": {
11
7
  ".": {
12
8
  "types": "./dist/index.d.ts",
13
- "require": "./dist/index.js",
14
- "import": "./dist/index.mjs",
15
- "default": "./dist/index.js"
16
- },
17
- "./package.json": "./package.json"
9
+ "import": "./dist/index.js",
10
+ "require": "./dist/index.cjs"
11
+ }
18
12
  },
13
+ "main": "./dist/index.cjs",
14
+ "module": "./dist/index.js",
15
+ "types": "./dist/index.d.ts",
19
16
  "files": [
20
17
  "dist",
21
18
  "README.md"
22
19
  ],
23
- "scripts": {
24
- "build": "tsup",
25
- "dev": "tsup --watch",
26
- "check-types": "tsc --noEmit",
27
- "prepublishOnly": "pnpm build"
28
- },
29
20
  "keywords": [
30
- "bot",
31
- "learning",
32
- "toolkit"
21
+ "botlearn",
22
+ "openclaw",
23
+ "skills",
24
+ "agent"
33
25
  ],
34
- "author": "",
26
+ "author": "BotLearn",
35
27
  "license": "MIT",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/readai-team/botlearn-awesome-skills.git",
31
+ "directory": "packages/botlearn"
32
+ },
33
+ "homepage": "https://github.com/readai-team/botlearn-awesome-skills/tree/main/packages/botlearn",
34
+ "bugs": {
35
+ "url": "https://github.com/readai-team/botlearn-awesome-skills/issues"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
36
40
  "devDependencies": {
37
- "@repo/typescript-config": "workspace:*",
38
- "@types/node": "^22.10.5",
39
- "tsup": "^8.3.5",
40
- "typescript": "^5.7.3"
41
+ "tsup": "^8.0.0",
42
+ "typescript": "^5.4.0"
41
43
  },
42
- "engines": {
43
- "node": ">=18"
44
+ "scripts": {
45
+ "build": "tsup",
46
+ "typecheck": "tsc --noEmit"
44
47
  }
45
- }
48
+ }
package/dist/index.d.mts DELETED
@@ -1,10 +0,0 @@
1
- /**
2
- * Botlearn - A Node.js toolkit for bot learning
3
- */
4
- declare const version = "0.0.1";
5
- /**
6
- * 示例函数
7
- */
8
- declare function hello(name?: string): string;
9
-
10
- export { hello, version };
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Botlearn - A Node.js toolkit for bot learning\n */\n\nexport const version = '0.0.1';\n\n/**\n * 示例函数\n */\nexport function hello(name = 'World'): string {\n return `Hello, ${name}!`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIO,IAAM,UAAU;AAKhB,SAAS,MAAM,OAAO,SAAiB;AAC5C,SAAO,UAAU,IAAI;AACvB;","names":[]}
package/dist/index.mjs DELETED
@@ -1,10 +0,0 @@
1
- // src/index.ts
2
- var version = "0.0.1";
3
- function hello(name = "World") {
4
- return `Hello, ${name}!`;
5
- }
6
- export {
7
- hello,
8
- version
9
- };
10
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Botlearn - A Node.js toolkit for bot learning\n */\n\nexport const version = '0.0.1';\n\n/**\n * 示例函数\n */\nexport function hello(name = 'World'): string {\n return `Hello, ${name}!`;\n}\n"],"mappings":";AAIO,IAAM,UAAU;AAKhB,SAAS,MAAM,OAAO,SAAiB;AAC5C,SAAO,UAAU,IAAI;AACvB;","names":[]}