@openclawcity/become 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 +21 -0
- package/README.md +133 -0
- package/dist/cli.cjs +113 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +89 -0
- package/dist/cli.js.map +1 -0
- package/dist/dashboard.cjs +806 -0
- package/dist/dashboard.cjs.map +1 -0
- package/dist/dashboard.d.cts +92 -0
- package/dist/dashboard.d.ts +92 -0
- package/dist/dashboard.js +767 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/index.cjs +2760 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +670 -0
- package/dist/index.d.ts +670 -0
- package/dist/index.js +2696 -0
- package/dist/index.js.map +1 -0
- package/dist/types-DzOc15AL.d.cts +273 -0
- package/dist/types-DzOc15AL.d.ts +273 -0
- package/migrations/001_initial.sql +128 -0
- package/package.json +85 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OpenClawCity
|
|
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
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# @openclaw/become
|
|
2
|
+
|
|
3
|
+
**Agents get smarter together.**
|
|
4
|
+
|
|
5
|
+
An open-source framework for multi-agent evolutionary learning. Track skills, measure growth, and enable agents to learn from each other.
|
|
6
|
+
|
|
7
|
+
## Two ways agents learn
|
|
8
|
+
|
|
9
|
+
**From their humans** — every conversation is a learning signal. Good responses reinforce skills. Failed responses generate corrective ones.
|
|
10
|
+
|
|
11
|
+
**From each other** — peer review, collaboration, observation, teaching. When one agent masters a skill, others learn from its work. The whole group gets smarter.
|
|
12
|
+
|
|
13
|
+
## Quickstart
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @openclaw/become
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { Become, MemoryStore } from '@openclaw/become';
|
|
21
|
+
import { computeFullScore } from '@openclaw/become';
|
|
22
|
+
|
|
23
|
+
// 1. Initialize
|
|
24
|
+
const become = new Become({ store: new MemoryStore() });
|
|
25
|
+
|
|
26
|
+
// 2. Register a skill
|
|
27
|
+
await become.skills.upsert('agent-1', {
|
|
28
|
+
name: 'debugging',
|
|
29
|
+
category: 'coding',
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// 3. Score it based on evidence
|
|
33
|
+
const score = computeFullScore('debugging', {
|
|
34
|
+
artifact_count: 5,
|
|
35
|
+
total_reactions: 12,
|
|
36
|
+
recent_reaction_avg: 4,
|
|
37
|
+
older_reaction_avg: 2,
|
|
38
|
+
unique_types: 3,
|
|
39
|
+
collab_count: 1,
|
|
40
|
+
peer_reviews_given: 0,
|
|
41
|
+
peer_reviews_received: 1,
|
|
42
|
+
follower_count: 2,
|
|
43
|
+
teaching_events: 0,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
console.log(score.score); // 28
|
|
47
|
+
console.log(score.dreyfus_stage); // 'beginner'
|
|
48
|
+
console.log(score.blooms_level); // 'analyze'
|
|
49
|
+
|
|
50
|
+
// 4. Reflect on growth
|
|
51
|
+
await become.reflector.reflect('agent-1', {
|
|
52
|
+
skill: 'debugging',
|
|
53
|
+
reflection: 'Print statements help me trace issues faster than step-through debugging.',
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// 5. Check milestones
|
|
57
|
+
const milestones = await become.milestones.check('agent-1', [score]);
|
|
58
|
+
// [{ milestone_type: 'skill_discovered:debugging', ... }]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Scoring Model
|
|
62
|
+
|
|
63
|
+
Skills are scored 0-100 using a weighted formula grounded in cognitive science:
|
|
64
|
+
|
|
65
|
+
| Component | Weight | What it measures |
|
|
66
|
+
|-----------|--------|-----------------|
|
|
67
|
+
| Artifacts | 30% | Volume + quality of outputs |
|
|
68
|
+
| Feedback | 20% | Peer reviews received |
|
|
69
|
+
| Improvement | 20% | Are recent outputs better than older ones? |
|
|
70
|
+
| Depth | 15% | Bloom's taxonomy level (remember → create) |
|
|
71
|
+
| Social | 10% | Collaborations, followers, reactions |
|
|
72
|
+
| Teaching | 5% | Knowledge shared with other agents |
|
|
73
|
+
|
|
74
|
+
### Dreyfus Stages
|
|
75
|
+
|
|
76
|
+
| Stage | Score | Meaning |
|
|
77
|
+
|-------|-------|---------|
|
|
78
|
+
| Novice | 0-15 | Following rules |
|
|
79
|
+
| Beginner | 16-35 | Applying in familiar contexts |
|
|
80
|
+
| Competent | 36-55 | Planning and prioritizing |
|
|
81
|
+
| Proficient | 56-75 | Seeing the big picture |
|
|
82
|
+
| Expert | 76-100 | Deep intuition, teaches others |
|
|
83
|
+
|
|
84
|
+
## Observation Rules
|
|
85
|
+
|
|
86
|
+
The reflector detects 10 behavioral patterns from agent data — no LLM calls needed:
|
|
87
|
+
|
|
88
|
+
- **Creative Mismatch** — output type diverges from declared role
|
|
89
|
+
- **Collaboration Gap** — many started, few completed
|
|
90
|
+
- **Quest Streak** — persistence signal from 3+ completions
|
|
91
|
+
- **Solo Creator** — lots of output, no collaboration
|
|
92
|
+
- **Symbolic Vocabulary** — shared tags emerging across agents
|
|
93
|
+
- And 5 more...
|
|
94
|
+
|
|
95
|
+
## Storage
|
|
96
|
+
|
|
97
|
+
Ships with an in-memory adapter for testing. Supabase adapter for production:
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
import { Become } from '@openclaw/become';
|
|
101
|
+
import { SupabaseStore } from '@openclaw/become'; // coming in v0.1
|
|
102
|
+
|
|
103
|
+
const become = new Become({
|
|
104
|
+
store: new SupabaseStore({
|
|
105
|
+
url: process.env.SUPABASE_URL,
|
|
106
|
+
key: process.env.SUPABASE_KEY,
|
|
107
|
+
}),
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Initialize tables:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npx become init
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Two Learning Modes
|
|
118
|
+
|
|
119
|
+
**Context-based (default)** — works with any model (Claude, GPT, Gemini, local). Learning happens through enriched prompts. No GPU needed.
|
|
120
|
+
|
|
121
|
+
**Weight-based (local models)** — for self-hosted models (Llama, Mistral, Qwen). Exports scored conversation turns as fine-tuning datasets. LoRA training produces a small adapter file (10-50MB). Coming in v0.5.
|
|
122
|
+
|
|
123
|
+
## Roadmap
|
|
124
|
+
|
|
125
|
+
- **v0.1** (current) — Core: skills, scorer, reflector, milestones, storage adapters
|
|
126
|
+
- **v0.2** — Learning: conversation scoring, skill evolution, peer review, teaching
|
|
127
|
+
- **v0.3** — Dashboard: React components for visualizing agent growth
|
|
128
|
+
- **v0.4** — Observation: cultural norm detection, awareness index
|
|
129
|
+
- **v0.5** — Integrations: LoRA training, OpenClaw plugin, Python client
|
|
130
|
+
|
|
131
|
+
## License
|
|
132
|
+
|
|
133
|
+
MIT — [OpenClawCity](https://github.com/openclawcity)
|
package/dist/cli.cjs
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
+
mod
|
|
24
|
+
));
|
|
25
|
+
|
|
26
|
+
// src/cli/init.ts
|
|
27
|
+
var import_node_fs = require("fs");
|
|
28
|
+
var import_node_path = require("path");
|
|
29
|
+
var import_node_url = require("url");
|
|
30
|
+
var import_meta = {};
|
|
31
|
+
var __dirname = (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
32
|
+
async function main() {
|
|
33
|
+
const args = process.argv.slice(2);
|
|
34
|
+
const command = args[0];
|
|
35
|
+
if (command === "init") {
|
|
36
|
+
await init(args.slice(1));
|
|
37
|
+
} else {
|
|
38
|
+
console.log(`
|
|
39
|
+
@openclaw/become \u2014 Agents get smarter together.
|
|
40
|
+
|
|
41
|
+
Commands:
|
|
42
|
+
become init Initialize become tables
|
|
43
|
+
become init --supabase Force Supabase mode
|
|
44
|
+
become init --sqlite Force local SQLite mode
|
|
45
|
+
|
|
46
|
+
Options:
|
|
47
|
+
--help Show this help
|
|
48
|
+
`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async function init(args) {
|
|
52
|
+
const forceSupabase = args.includes("--supabase");
|
|
53
|
+
const forceSqlite = args.includes("--sqlite");
|
|
54
|
+
const supabaseUrl = process.env.SUPABASE_URL ?? process.env.NEXT_PUBLIC_SUPABASE_URL;
|
|
55
|
+
const supabaseKey = process.env.SUPABASE_SERVICE_ROLE_KEY ?? process.env.SUPABASE_KEY;
|
|
56
|
+
const useSupabase = forceSupabase || !forceSqlite && supabaseUrl && supabaseKey;
|
|
57
|
+
if (useSupabase) {
|
|
58
|
+
if (!supabaseUrl || !supabaseKey) {
|
|
59
|
+
console.error("Error: SUPABASE_URL and SUPABASE_KEY (or SUPABASE_SERVICE_ROLE_KEY) must be set.");
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
console.log("Initializing become tables in Supabase...");
|
|
63
|
+
try {
|
|
64
|
+
const { createClient } = await import("@supabase/supabase-js");
|
|
65
|
+
const supabase = createClient(supabaseUrl, supabaseKey);
|
|
66
|
+
const migrationPath = (0, import_node_path.join)(__dirname, "..", "migrations", "001_initial.sql");
|
|
67
|
+
let sql;
|
|
68
|
+
try {
|
|
69
|
+
sql = (0, import_node_fs.readFileSync)(migrationPath, "utf-8");
|
|
70
|
+
} catch {
|
|
71
|
+
const altPath = (0, import_node_path.join)(__dirname, "..", "..", "migrations", "001_initial.sql");
|
|
72
|
+
sql = (0, import_node_fs.readFileSync)(altPath, "utf-8");
|
|
73
|
+
}
|
|
74
|
+
const { error } = await supabase.rpc("exec_sql", { sql_query: sql }).single();
|
|
75
|
+
if (error) {
|
|
76
|
+
console.log("Note: Run the migration SQL manually if RPC is not available.");
|
|
77
|
+
console.log(`Migration file: migrations/001_initial.sql`);
|
|
78
|
+
} else {
|
|
79
|
+
console.log("Done! Tables created successfully.");
|
|
80
|
+
}
|
|
81
|
+
} catch (err) {
|
|
82
|
+
console.error("Failed to initialize:", err.message);
|
|
83
|
+
console.log("\nYou can run the migration manually:");
|
|
84
|
+
console.log(" migrations/001_initial.sql");
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
console.log("No Supabase credentials found. Using in-memory store for now.");
|
|
89
|
+
console.log("Set SUPABASE_URL and SUPABASE_KEY to use Supabase, or use --sqlite for local storage.");
|
|
90
|
+
}
|
|
91
|
+
console.log(`
|
|
92
|
+
Quickstart:
|
|
93
|
+
|
|
94
|
+
import { Become, MemoryStore } from '@openclaw/become';
|
|
95
|
+
|
|
96
|
+
const become = new Become({ store: new MemoryStore() });
|
|
97
|
+
|
|
98
|
+
// Register a skill
|
|
99
|
+
await become.skills.upsert('agent-1', { name: 'debugging', category: 'coding' });
|
|
100
|
+
|
|
101
|
+
// Score it
|
|
102
|
+
const score = become.scorer.computeFullScore('debugging', {
|
|
103
|
+
artifact_count: 5, total_reactions: 12, recent_reaction_avg: 4,
|
|
104
|
+
older_reaction_avg: 2, unique_types: 3, collab_count: 1,
|
|
105
|
+
peer_reviews_given: 0, peer_reviews_received: 1,
|
|
106
|
+
follower_count: 2, teaching_events: 0,
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
console.log(score.dreyfus_stage); // 'beginner'
|
|
110
|
+
`);
|
|
111
|
+
}
|
|
112
|
+
main().catch(console.error);
|
|
113
|
+
//# sourceMappingURL=cli.cjs.map
|
package/dist/cli.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/init.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { readFileSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nasync function main() {\n const args = process.argv.slice(2);\n const command = args[0];\n\n if (command === 'init') {\n await init(args.slice(1));\n } else {\n console.log(`\n@openclaw/become — Agents get smarter together.\n\nCommands:\n become init Initialize become tables\n become init --supabase Force Supabase mode\n become init --sqlite Force local SQLite mode\n\nOptions:\n --help Show this help\n`);\n }\n}\n\nasync function init(args: string[]) {\n const forceSupabase = args.includes('--supabase');\n const forceSqlite = args.includes('--sqlite');\n\n const supabaseUrl = process.env.SUPABASE_URL ?? process.env.NEXT_PUBLIC_SUPABASE_URL;\n const supabaseKey = process.env.SUPABASE_SERVICE_ROLE_KEY ?? process.env.SUPABASE_KEY;\n\n const useSupabase = forceSupabase || (!forceSqlite && supabaseUrl && supabaseKey);\n\n if (useSupabase) {\n if (!supabaseUrl || !supabaseKey) {\n console.error('Error: SUPABASE_URL and SUPABASE_KEY (or SUPABASE_SERVICE_ROLE_KEY) must be set.');\n process.exit(1);\n }\n\n console.log('Initializing become tables in Supabase...');\n\n try {\n const { createClient } = await import('@supabase/supabase-js');\n const supabase = createClient(supabaseUrl, supabaseKey);\n\n // Read migration SQL\n const migrationPath = join(__dirname, '..', 'migrations', '001_initial.sql');\n let sql: string;\n try {\n sql = readFileSync(migrationPath, 'utf-8');\n } catch {\n // Fallback for bundled dist\n const altPath = join(__dirname, '..', '..', 'migrations', '001_initial.sql');\n sql = readFileSync(altPath, 'utf-8');\n }\n\n const { error } = await supabase.rpc('exec_sql', { sql_query: sql }).single();\n if (error) {\n // Try direct SQL if RPC not available\n console.log('Note: Run the migration SQL manually if RPC is not available.');\n console.log(`Migration file: migrations/001_initial.sql`);\n } else {\n console.log('Done! Tables created successfully.');\n }\n } catch (err: any) {\n console.error('Failed to initialize:', err.message);\n console.log('\\nYou can run the migration manually:');\n console.log(' migrations/001_initial.sql');\n process.exit(1);\n }\n } else {\n console.log('No Supabase credentials found. Using in-memory store for now.');\n console.log('Set SUPABASE_URL and SUPABASE_KEY to use Supabase, or use --sqlite for local storage.');\n }\n\n console.log(`\nQuickstart:\n\n import { Become, MemoryStore } from '@openclaw/become';\n\n const become = new Become({ store: new MemoryStore() });\n\n // Register a skill\n await become.skills.upsert('agent-1', { name: 'debugging', category: 'coding' });\n\n // Score it\n const score = become.scorer.computeFullScore('debugging', {\n artifact_count: 5, total_reactions: 12, recent_reaction_avg: 4,\n older_reaction_avg: 2, unique_types: 3, collab_count: 1,\n peer_reviews_given: 0, peer_reviews_received: 1,\n follower_count: 2, teaching_events: 0,\n });\n\n console.log(score.dreyfus_stage); // 'beginner'\n`);\n}\n\nmain().catch(console.error);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,qBAA6B;AAC7B,uBAA8B;AAC9B,sBAA8B;AAJ9B;AAMA,IAAM,gBAAY,8BAAQ,+BAAc,YAAY,GAAG,CAAC;AAExD,eAAe,OAAO;AACpB,QAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,QAAM,UAAU,KAAK,CAAC;AAEtB,MAAI,YAAY,QAAQ;AACtB,UAAM,KAAK,KAAK,MAAM,CAAC,CAAC;AAAA,EAC1B,OAAO;AACL,YAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAUf;AAAA,EACC;AACF;AAEA,eAAe,KAAK,MAAgB;AAClC,QAAM,gBAAgB,KAAK,SAAS,YAAY;AAChD,QAAM,cAAc,KAAK,SAAS,UAAU;AAE5C,QAAM,cAAc,QAAQ,IAAI,gBAAgB,QAAQ,IAAI;AAC5D,QAAM,cAAc,QAAQ,IAAI,6BAA6B,QAAQ,IAAI;AAEzE,QAAM,cAAc,iBAAkB,CAAC,eAAe,eAAe;AAErE,MAAI,aAAa;AACf,QAAI,CAAC,eAAe,CAAC,aAAa;AAChC,cAAQ,MAAM,kFAAkF;AAChG,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,YAAQ,IAAI,2CAA2C;AAEvD,QAAI;AACF,YAAM,EAAE,aAAa,IAAI,MAAM,OAAO,uBAAuB;AAC7D,YAAM,WAAW,aAAa,aAAa,WAAW;AAGtD,YAAM,oBAAgB,uBAAK,WAAW,MAAM,cAAc,iBAAiB;AAC3E,UAAI;AACJ,UAAI;AACF,kBAAM,6BAAa,eAAe,OAAO;AAAA,MAC3C,QAAQ;AAEN,cAAM,cAAU,uBAAK,WAAW,MAAM,MAAM,cAAc,iBAAiB;AAC3E,kBAAM,6BAAa,SAAS,OAAO;AAAA,MACrC;AAEA,YAAM,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,YAAY,EAAE,WAAW,IAAI,CAAC,EAAE,OAAO;AAC5E,UAAI,OAAO;AAET,gBAAQ,IAAI,+DAA+D;AAC3E,gBAAQ,IAAI,4CAA4C;AAAA,MAC1D,OAAO;AACL,gBAAQ,IAAI,oCAAoC;AAAA,MAClD;AAAA,IACF,SAAS,KAAU;AACjB,cAAQ,MAAM,yBAAyB,IAAI,OAAO;AAClD,cAAQ,IAAI,uCAAuC;AACnD,cAAQ,IAAI,8BAA8B;AAC1C,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,OAAO;AACL,YAAQ,IAAI,+DAA+D;AAC3E,YAAQ,IAAI,uFAAuF;AAAA,EACrG;AAEA,UAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAmBb;AACD;AAEA,KAAK,EAAE,MAAM,QAAQ,KAAK;","names":[]}
|
package/dist/cli.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/cli/init.ts
|
|
4
|
+
import { readFileSync } from "fs";
|
|
5
|
+
import { join, dirname } from "path";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
async function main() {
|
|
9
|
+
const args = process.argv.slice(2);
|
|
10
|
+
const command = args[0];
|
|
11
|
+
if (command === "init") {
|
|
12
|
+
await init(args.slice(1));
|
|
13
|
+
} else {
|
|
14
|
+
console.log(`
|
|
15
|
+
@openclaw/become \u2014 Agents get smarter together.
|
|
16
|
+
|
|
17
|
+
Commands:
|
|
18
|
+
become init Initialize become tables
|
|
19
|
+
become init --supabase Force Supabase mode
|
|
20
|
+
become init --sqlite Force local SQLite mode
|
|
21
|
+
|
|
22
|
+
Options:
|
|
23
|
+
--help Show this help
|
|
24
|
+
`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function init(args) {
|
|
28
|
+
const forceSupabase = args.includes("--supabase");
|
|
29
|
+
const forceSqlite = args.includes("--sqlite");
|
|
30
|
+
const supabaseUrl = process.env.SUPABASE_URL ?? process.env.NEXT_PUBLIC_SUPABASE_URL;
|
|
31
|
+
const supabaseKey = process.env.SUPABASE_SERVICE_ROLE_KEY ?? process.env.SUPABASE_KEY;
|
|
32
|
+
const useSupabase = forceSupabase || !forceSqlite && supabaseUrl && supabaseKey;
|
|
33
|
+
if (useSupabase) {
|
|
34
|
+
if (!supabaseUrl || !supabaseKey) {
|
|
35
|
+
console.error("Error: SUPABASE_URL and SUPABASE_KEY (or SUPABASE_SERVICE_ROLE_KEY) must be set.");
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
console.log("Initializing become tables in Supabase...");
|
|
39
|
+
try {
|
|
40
|
+
const { createClient } = await import("@supabase/supabase-js");
|
|
41
|
+
const supabase = createClient(supabaseUrl, supabaseKey);
|
|
42
|
+
const migrationPath = join(__dirname, "..", "migrations", "001_initial.sql");
|
|
43
|
+
let sql;
|
|
44
|
+
try {
|
|
45
|
+
sql = readFileSync(migrationPath, "utf-8");
|
|
46
|
+
} catch {
|
|
47
|
+
const altPath = join(__dirname, "..", "..", "migrations", "001_initial.sql");
|
|
48
|
+
sql = readFileSync(altPath, "utf-8");
|
|
49
|
+
}
|
|
50
|
+
const { error } = await supabase.rpc("exec_sql", { sql_query: sql }).single();
|
|
51
|
+
if (error) {
|
|
52
|
+
console.log("Note: Run the migration SQL manually if RPC is not available.");
|
|
53
|
+
console.log(`Migration file: migrations/001_initial.sql`);
|
|
54
|
+
} else {
|
|
55
|
+
console.log("Done! Tables created successfully.");
|
|
56
|
+
}
|
|
57
|
+
} catch (err) {
|
|
58
|
+
console.error("Failed to initialize:", err.message);
|
|
59
|
+
console.log("\nYou can run the migration manually:");
|
|
60
|
+
console.log(" migrations/001_initial.sql");
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
console.log("No Supabase credentials found. Using in-memory store for now.");
|
|
65
|
+
console.log("Set SUPABASE_URL and SUPABASE_KEY to use Supabase, or use --sqlite for local storage.");
|
|
66
|
+
}
|
|
67
|
+
console.log(`
|
|
68
|
+
Quickstart:
|
|
69
|
+
|
|
70
|
+
import { Become, MemoryStore } from '@openclaw/become';
|
|
71
|
+
|
|
72
|
+
const become = new Become({ store: new MemoryStore() });
|
|
73
|
+
|
|
74
|
+
// Register a skill
|
|
75
|
+
await become.skills.upsert('agent-1', { name: 'debugging', category: 'coding' });
|
|
76
|
+
|
|
77
|
+
// Score it
|
|
78
|
+
const score = become.scorer.computeFullScore('debugging', {
|
|
79
|
+
artifact_count: 5, total_reactions: 12, recent_reaction_avg: 4,
|
|
80
|
+
older_reaction_avg: 2, unique_types: 3, collab_count: 1,
|
|
81
|
+
peer_reviews_given: 0, peer_reviews_received: 1,
|
|
82
|
+
follower_count: 2, teaching_events: 0,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
console.log(score.dreyfus_stage); // 'beginner'
|
|
86
|
+
`);
|
|
87
|
+
}
|
|
88
|
+
main().catch(console.error);
|
|
89
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/init.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { readFileSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nasync function main() {\n const args = process.argv.slice(2);\n const command = args[0];\n\n if (command === 'init') {\n await init(args.slice(1));\n } else {\n console.log(`\n@openclaw/become — Agents get smarter together.\n\nCommands:\n become init Initialize become tables\n become init --supabase Force Supabase mode\n become init --sqlite Force local SQLite mode\n\nOptions:\n --help Show this help\n`);\n }\n}\n\nasync function init(args: string[]) {\n const forceSupabase = args.includes('--supabase');\n const forceSqlite = args.includes('--sqlite');\n\n const supabaseUrl = process.env.SUPABASE_URL ?? process.env.NEXT_PUBLIC_SUPABASE_URL;\n const supabaseKey = process.env.SUPABASE_SERVICE_ROLE_KEY ?? process.env.SUPABASE_KEY;\n\n const useSupabase = forceSupabase || (!forceSqlite && supabaseUrl && supabaseKey);\n\n if (useSupabase) {\n if (!supabaseUrl || !supabaseKey) {\n console.error('Error: SUPABASE_URL and SUPABASE_KEY (or SUPABASE_SERVICE_ROLE_KEY) must be set.');\n process.exit(1);\n }\n\n console.log('Initializing become tables in Supabase...');\n\n try {\n const { createClient } = await import('@supabase/supabase-js');\n const supabase = createClient(supabaseUrl, supabaseKey);\n\n // Read migration SQL\n const migrationPath = join(__dirname, '..', 'migrations', '001_initial.sql');\n let sql: string;\n try {\n sql = readFileSync(migrationPath, 'utf-8');\n } catch {\n // Fallback for bundled dist\n const altPath = join(__dirname, '..', '..', 'migrations', '001_initial.sql');\n sql = readFileSync(altPath, 'utf-8');\n }\n\n const { error } = await supabase.rpc('exec_sql', { sql_query: sql }).single();\n if (error) {\n // Try direct SQL if RPC not available\n console.log('Note: Run the migration SQL manually if RPC is not available.');\n console.log(`Migration file: migrations/001_initial.sql`);\n } else {\n console.log('Done! Tables created successfully.');\n }\n } catch (err: any) {\n console.error('Failed to initialize:', err.message);\n console.log('\\nYou can run the migration manually:');\n console.log(' migrations/001_initial.sql');\n process.exit(1);\n }\n } else {\n console.log('No Supabase credentials found. Using in-memory store for now.');\n console.log('Set SUPABASE_URL and SUPABASE_KEY to use Supabase, or use --sqlite for local storage.');\n }\n\n console.log(`\nQuickstart:\n\n import { Become, MemoryStore } from '@openclaw/become';\n\n const become = new Become({ store: new MemoryStore() });\n\n // Register a skill\n await become.skills.upsert('agent-1', { name: 'debugging', category: 'coding' });\n\n // Score it\n const score = become.scorer.computeFullScore('debugging', {\n artifact_count: 5, total_reactions: 12, recent_reaction_avg: 4,\n older_reaction_avg: 2, unique_types: 3, collab_count: 1,\n peer_reviews_given: 0, peer_reviews_received: 1,\n follower_count: 2, teaching_events: 0,\n });\n\n console.log(score.dreyfus_stage); // 'beginner'\n`);\n}\n\nmain().catch(console.error);\n"],"mappings":";;;AAEA,SAAS,oBAAoB;AAC7B,SAAS,MAAM,eAAe;AAC9B,SAAS,qBAAqB;AAE9B,IAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AAExD,eAAe,OAAO;AACpB,QAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,QAAM,UAAU,KAAK,CAAC;AAEtB,MAAI,YAAY,QAAQ;AACtB,UAAM,KAAK,KAAK,MAAM,CAAC,CAAC;AAAA,EAC1B,OAAO;AACL,YAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAUf;AAAA,EACC;AACF;AAEA,eAAe,KAAK,MAAgB;AAClC,QAAM,gBAAgB,KAAK,SAAS,YAAY;AAChD,QAAM,cAAc,KAAK,SAAS,UAAU;AAE5C,QAAM,cAAc,QAAQ,IAAI,gBAAgB,QAAQ,IAAI;AAC5D,QAAM,cAAc,QAAQ,IAAI,6BAA6B,QAAQ,IAAI;AAEzE,QAAM,cAAc,iBAAkB,CAAC,eAAe,eAAe;AAErE,MAAI,aAAa;AACf,QAAI,CAAC,eAAe,CAAC,aAAa;AAChC,cAAQ,MAAM,kFAAkF;AAChG,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,YAAQ,IAAI,2CAA2C;AAEvD,QAAI;AACF,YAAM,EAAE,aAAa,IAAI,MAAM,OAAO,uBAAuB;AAC7D,YAAM,WAAW,aAAa,aAAa,WAAW;AAGtD,YAAM,gBAAgB,KAAK,WAAW,MAAM,cAAc,iBAAiB;AAC3E,UAAI;AACJ,UAAI;AACF,cAAM,aAAa,eAAe,OAAO;AAAA,MAC3C,QAAQ;AAEN,cAAM,UAAU,KAAK,WAAW,MAAM,MAAM,cAAc,iBAAiB;AAC3E,cAAM,aAAa,SAAS,OAAO;AAAA,MACrC;AAEA,YAAM,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,YAAY,EAAE,WAAW,IAAI,CAAC,EAAE,OAAO;AAC5E,UAAI,OAAO;AAET,gBAAQ,IAAI,+DAA+D;AAC3E,gBAAQ,IAAI,4CAA4C;AAAA,MAC1D,OAAO;AACL,gBAAQ,IAAI,oCAAoC;AAAA,MAClD;AAAA,IACF,SAAS,KAAU;AACjB,cAAQ,MAAM,yBAAyB,IAAI,OAAO;AAClD,cAAQ,IAAI,uCAAuC;AACnD,cAAQ,IAAI,8BAA8B;AAC1C,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,OAAO;AACL,YAAQ,IAAI,+DAA+D;AAC3E,YAAQ,IAAI,uFAAuF;AAAA,EACrG;AAEA,UAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAmBb;AACD;AAEA,KAAK,EAAE,MAAM,QAAQ,KAAK;","names":[]}
|