clawpilot 0.1.1

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/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # clawpilot
2
+
3
+ OpenClaw productivity copilot installer and skill package.
4
+
5
+ ## What it does
6
+
7
+ `clawpilot` installs a productivity-focused OpenClaw skill with a simple daily loop:
8
+ - Morning planning (top 3 tasks)
9
+ - Midday progress check
10
+ - Evening review and next-step setup
11
+
12
+ The installer also:
13
+ - Copies `skill/` into `~/.openclaw/skills/clawpilot-productivity`
14
+ - Adds or updates `clawpilot-productivity` under `openclaw.json`
15
+ - Injects a productivity section into `workspace/SOUL.md` (idempotent)
16
+ - Writes a default `workspace/IDENTITY.md`
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ npx clawpilot@latest
22
+ ```
23
+
24
+ Or run locally:
25
+
26
+ ```bash
27
+ npm install
28
+ npm run test
29
+ node bin/cli.js install
30
+ ```
31
+
32
+ ## CLI options
33
+
34
+ ```bash
35
+ clawpilot install [options]
36
+ ```
37
+
38
+ Options:
39
+ - `--home <path>`: Override OpenClaw home directory
40
+ - `--force`: Replace existing skill installation
41
+ - `--morning <HH:mm>`: Morning check-in time (default `09:00`)
42
+ - `--midday <HH:mm>`: Midday check-in time (default `14:00`)
43
+ - `--evening <HH:mm>`: Evening check-in time (default `21:30`)
44
+
45
+ ## OpenClaw paths
46
+
47
+ By default, the installer writes to:
48
+ - `~/.openclaw/skills/clawpilot-productivity/`
49
+ - `~/.openclaw/openclaw.json`
50
+ - `~/.openclaw/workspace/SOUL.md`
51
+ - `~/.openclaw/workspace/IDENTITY.md`
52
+
53
+ You can override the target path with:
54
+
55
+ ```bash
56
+ node bin/cli.js install --home /custom/path
57
+ ```
58
+
59
+ ## Development
60
+
61
+ ```bash
62
+ npm test
63
+ ```
64
+
65
+ ## Publish
66
+
67
+ See `docs/PUBLISH_CHECKLIST.md`.
package/bin/cli.js ADDED
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env node
2
+
3
+ const os = require('node:os');
4
+ const path = require('node:path');
5
+ const { installSkill, DEFAULT_SCHEDULE } = require('../src/install');
6
+
7
+ function printHelp() {
8
+ console.log('clawpilot - OpenClaw productivity copilot');
9
+ console.log('');
10
+ console.log('Usage:');
11
+ console.log(' clawpilot install [options]');
12
+ console.log(' clawpilot --help');
13
+ console.log('');
14
+ console.log('Commands:');
15
+ console.log(' install Install clawpilot-productivity skill into OpenClaw');
16
+ console.log('');
17
+ console.log('Options:');
18
+ console.log(' --home <path> Override OpenClaw home directory');
19
+ console.log(' --force Replace existing clawpilot skill installation');
20
+ console.log(` --morning <HH:mm> Morning check-in time (default: ${DEFAULT_SCHEDULE.morning})`);
21
+ console.log(` --midday <HH:mm> Midday check-in time (default: ${DEFAULT_SCHEDULE.midday})`);
22
+ console.log(` --evening <HH:mm> Evening check-in time (default: ${DEFAULT_SCHEDULE.evening})`);
23
+ }
24
+
25
+ function parseOptions(args) {
26
+ const options = {
27
+ force: false,
28
+ schedule: {}
29
+ };
30
+
31
+ for (let index = 0; index < args.length; index += 1) {
32
+ const arg = args[index];
33
+ if (arg === '--force') {
34
+ options.force = true;
35
+ continue;
36
+ }
37
+ if (arg === '--home') {
38
+ options.openClawHome = args[index + 1];
39
+ index += 1;
40
+ continue;
41
+ }
42
+ if (arg === '--morning') {
43
+ options.schedule.morning = args[index + 1];
44
+ index += 1;
45
+ continue;
46
+ }
47
+ if (arg === '--midday') {
48
+ options.schedule.midday = args[index + 1];
49
+ index += 1;
50
+ continue;
51
+ }
52
+ if (arg === '--evening') {
53
+ options.schedule.evening = args[index + 1];
54
+ index += 1;
55
+ continue;
56
+ }
57
+ throw new Error(`Unknown option: ${arg}`);
58
+ }
59
+
60
+ return options;
61
+ }
62
+
63
+ async function main() {
64
+ const args = process.argv.slice(2);
65
+ const command = args[0] || 'install';
66
+ const commandArgs = args.slice(1);
67
+
68
+ if (command === '--help' || command === '-h' || command === 'help') {
69
+ printHelp();
70
+ return;
71
+ }
72
+
73
+ if (command !== 'install') {
74
+ console.error(`Unknown command: ${command}`);
75
+ console.error('Run "clawpilot --help" for usage.');
76
+ process.exitCode = 1;
77
+ return;
78
+ }
79
+
80
+ const projectRoot = path.resolve(__dirname, '..');
81
+ const options = parseOptions(commandArgs);
82
+ const openClawHome = options.openClawHome || process.env.OPENCLAW_HOME || path.join(os.homedir(), '.openclaw');
83
+
84
+ const result = await installSkill({
85
+ openClawHome,
86
+ packageRoot: projectRoot,
87
+ schedule: options.schedule,
88
+ force: options.force
89
+ });
90
+
91
+ console.log(`Installed skill at: ${result.skillDir}`);
92
+ console.log(`Updated config at: ${result.configPath}`);
93
+ console.log(`Updated workspace SOUL at: ${result.workspaceSoulPath}`);
94
+ console.log(`Updated workspace identity at: ${result.identityPath}`);
95
+ }
96
+
97
+ main().catch((error) => {
98
+ console.error(error.message);
99
+ process.exitCode = 1;
100
+ });
@@ -0,0 +1,22 @@
1
+ # Publish Checklist
2
+
3
+ Use this checklist before publishing a new `clawpilot` version to npm.
4
+
5
+ 1. Verify tests:
6
+ - `npm test`
7
+ 2. Verify installer behavior locally:
8
+ - `node bin/cli.js install --home <temp-dir>`
9
+ 3. Review package metadata:
10
+ - `name`
11
+ - `version`
12
+ - `bin`
13
+ - `license`
14
+ 4. Confirm npm auth:
15
+ - `npm whoami`
16
+ 5. Dry-run package contents:
17
+ - `npm pack --dry-run`
18
+ 6. Publish:
19
+ - `npm publish --access public`
20
+ 7. Validate release:
21
+ - `npm view clawpilot version`
22
+ - `npx clawpilot@latest --help`
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "clawpilot",
3
+ "version": "0.1.1",
4
+ "description": "OpenClaw productivity copilot installer and skill package.",
5
+ "private": false,
6
+ "bin": {
7
+ "clawpilot": "bin/cli.js"
8
+ },
9
+ "files": [
10
+ "bin/",
11
+ "src/",
12
+ "skill/",
13
+ "templates/",
14
+ "docs/",
15
+ "README.md"
16
+ ],
17
+ "scripts": {
18
+ "test": "node --test"
19
+ },
20
+ "keywords": [
21
+ "openclaw",
22
+ "claw",
23
+ "productivity",
24
+ "copilot"
25
+ ],
26
+ "license": "MIT",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/RyanSparkc/clawpilot.git"
30
+ },
31
+ "homepage": "https://github.com/RyanSparkc/clawpilot#readme",
32
+ "engines": {
33
+ "node": ">=18.0.0"
34
+ }
35
+ }
package/skill/SKILL.md ADDED
@@ -0,0 +1,22 @@
1
+ # Clawpilot Productivity Skill
2
+
3
+ You are a productivity copilot focused on helping the user ship meaningful work each day.
4
+
5
+ ## Core Loop
6
+
7
+ 1. Morning planning:
8
+ - Ask for the user's top 3 outcome-based tasks.
9
+ - Ensure each task is specific and verifiable.
10
+ 2. Midday check-in:
11
+ - Ask what is done, blocked, or deferred.
12
+ - Help remove one blocker.
13
+ 3. Evening review:
14
+ - Summarize completed work.
15
+ - Capture one improvement for tomorrow.
16
+
17
+ ## Tone and Constraints
18
+
19
+ - Keep responses short and action-oriented.
20
+ - Be supportive and direct.
21
+ - Avoid guilt, shame, or perfectionist framing.
22
+ - Prefer one next action when the user is stuck.
@@ -0,0 +1,6 @@
1
+ {
2
+ "id": "clawpilot-productivity",
3
+ "name": "Clawpilot Productivity",
4
+ "version": "0.1.0",
5
+ "entry": "SOUL.md"
6
+ }
package/src/install.js ADDED
@@ -0,0 +1,181 @@
1
+ const fs = require('node:fs');
2
+ const path = require('node:path');
3
+
4
+ const SKILL_ID = 'clawpilot-productivity';
5
+ const MARKER_START = '<!-- clawpilot:productivity:start -->';
6
+ const MARKER_END = '<!-- clawpilot:productivity:end -->';
7
+ const DEFAULT_SCHEDULE = {
8
+ morning: '09:00',
9
+ midday: '14:00',
10
+ evening: '21:30'
11
+ };
12
+
13
+ function copyDir(source, destination) {
14
+ fs.mkdirSync(destination, { recursive: true });
15
+ const entries = fs.readdirSync(source, { withFileTypes: true });
16
+ for (const entry of entries) {
17
+ const sourcePath = path.join(source, entry.name);
18
+ const destinationPath = path.join(destination, entry.name);
19
+ if (entry.isDirectory()) {
20
+ copyDir(sourcePath, destinationPath);
21
+ } else {
22
+ fs.copyFileSync(sourcePath, destinationPath);
23
+ }
24
+ }
25
+ }
26
+
27
+ function deepMerge(target, source) {
28
+ const result = { ...target };
29
+ for (const [key, value] of Object.entries(source)) {
30
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
31
+ result[key] = deepMerge(result[key] || {}, value);
32
+ continue;
33
+ }
34
+ result[key] = value;
35
+ }
36
+ return result;
37
+ }
38
+
39
+ function readJson(filePath) {
40
+ if (!fs.existsSync(filePath)) {
41
+ return {};
42
+ }
43
+
44
+ try {
45
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
46
+ } catch {
47
+ return {};
48
+ }
49
+ }
50
+
51
+ function writeJson(filePath, data) {
52
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\n', 'utf8');
53
+ }
54
+
55
+ function upsertInstalledSkill(config) {
56
+ if (!Array.isArray(config.installedSkills)) {
57
+ config.installedSkills = [];
58
+ }
59
+ if (!config.installedSkills.includes(SKILL_ID)) {
60
+ config.installedSkills.push(SKILL_ID);
61
+ }
62
+ }
63
+
64
+ function normalizeSchedule(schedule) {
65
+ return {
66
+ ...DEFAULT_SCHEDULE,
67
+ ...(schedule || {})
68
+ };
69
+ }
70
+
71
+ function upsertWorkspaceSoul(soulPath, injectionText) {
72
+ const normalizedInjection = `${MARKER_START}\n${injectionText.trim()}\n${MARKER_END}`;
73
+ const existing = fs.existsSync(soulPath)
74
+ ? fs.readFileSync(soulPath, 'utf8')
75
+ : '# Agent Soul\n';
76
+ const markerRegex = new RegExp(`${MARKER_START}[\\s\\S]*?${MARKER_END}\\n?`, 'g');
77
+ const cleaned = existing.replace(markerRegex, '').trimEnd();
78
+ const nextContent = `${cleaned}\n\n${normalizedInjection}\n`;
79
+ fs.writeFileSync(soulPath, nextContent, 'utf8');
80
+ }
81
+
82
+ function ensureSkillManifest(skillDir) {
83
+ const manifestPath = path.join(skillDir, 'manifest.json');
84
+ if (fs.existsSync(manifestPath)) {
85
+ return;
86
+ }
87
+
88
+ const manifest = {
89
+ id: SKILL_ID,
90
+ name: 'Clawpilot Productivity',
91
+ version: '0.1.0',
92
+ entry: 'SOUL.md'
93
+ };
94
+ writeJson(manifestPath, manifest);
95
+ }
96
+
97
+ async function installSkill({
98
+ openClawHome,
99
+ packageRoot,
100
+ schedule,
101
+ force = false,
102
+ timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC'
103
+ }) {
104
+ const skillsDir = path.join(openClawHome, 'skills');
105
+ const skillDir = path.join(openClawHome, 'skills', SKILL_ID);
106
+ const workspaceDir = path.join(openClawHome, 'workspace');
107
+ const configPath = path.join(openClawHome, 'openclaw.json');
108
+ const soulPath = path.join(skillDir, 'SOUL.md');
109
+ const workspaceSoulPath = path.join(workspaceDir, 'SOUL.md');
110
+ const identityPath = path.join(workspaceDir, 'IDENTITY.md');
111
+
112
+ const skillSourceDir = path.join(packageRoot, 'skill');
113
+ const templateDir = path.join(packageRoot, 'templates');
114
+ const baseSoulTemplate = fs.readFileSync(path.join(templateDir, 'soul.productivity.md'), 'utf8');
115
+ const injectionTemplate = fs.readFileSync(path.join(templateDir, 'soul-injection.md'), 'utf8');
116
+ const identityTemplate = fs.readFileSync(path.join(templateDir, 'identity.md'), 'utf8');
117
+
118
+ fs.mkdirSync(openClawHome, { recursive: true });
119
+ fs.mkdirSync(skillsDir, { recursive: true });
120
+ fs.mkdirSync(workspaceDir, { recursive: true });
121
+
122
+ if (fs.existsSync(skillDir)) {
123
+ if (!force) {
124
+ throw new Error(`Skill already installed: ${skillDir}. Re-run with force to replace.`);
125
+ }
126
+ fs.rmSync(skillDir, { recursive: true, force: true });
127
+ }
128
+
129
+ if (fs.existsSync(skillSourceDir)) {
130
+ copyDir(skillSourceDir, skillDir);
131
+ } else {
132
+ fs.mkdirSync(skillDir, { recursive: true });
133
+ }
134
+
135
+ fs.writeFileSync(soulPath, baseSoulTemplate, 'utf8');
136
+ ensureSkillManifest(skillDir);
137
+ upsertWorkspaceSoul(workspaceSoulPath, injectionTemplate);
138
+ fs.writeFileSync(identityPath, identityTemplate, 'utf8');
139
+
140
+ let config = readJson(configPath);
141
+ const existingEntry = (((config.skills || {}).entries || {})[SKILL_ID]) || {};
142
+ const mergedEntry = deepMerge(existingEntry, {
143
+ enabled: true,
144
+ mode: 'productivity',
145
+ timezone,
146
+ schedule: normalizeSchedule(schedule)
147
+ });
148
+
149
+ config = deepMerge(config, {
150
+ skills: {
151
+ entries: {
152
+ [SKILL_ID]: mergedEntry
153
+ },
154
+ load: {
155
+ extraDirs: Array.isArray(config.skills?.load?.extraDirs)
156
+ ? config.skills.load.extraDirs
157
+ : []
158
+ }
159
+ }
160
+ });
161
+
162
+ if (!config.skills.load.extraDirs.includes(skillsDir)) {
163
+ config.skills.load.extraDirs.push(skillsDir);
164
+ }
165
+
166
+ upsertInstalledSkill(config);
167
+ writeJson(configPath, config);
168
+
169
+ return {
170
+ skillDir,
171
+ configPath,
172
+ workspaceSoulPath,
173
+ identityPath
174
+ };
175
+ }
176
+
177
+ module.exports = {
178
+ installSkill,
179
+ SKILL_ID,
180
+ DEFAULT_SCHEDULE
181
+ };
@@ -0,0 +1,6 @@
1
+ # IDENTITY.md
2
+
3
+ - Name: Clawpilot
4
+ - Role: Productivity Copilot
5
+ - Style: Calm, concise, practical, and supportive
6
+ - Focus: Daily execution, momentum, and measurable outcomes
@@ -0,0 +1,14 @@
1
+ ## Clawpilot Productivity Loop
2
+
3
+ Run this daily structure with minimal friction:
4
+
5
+ - Morning: ask for 3 outcome-based tasks and make each one measurable.
6
+ - Midday: collect status (`done`, `blocked`, or `deferred`) and unblock one thing.
7
+ - Evening: summarize wins, note one lesson, and queue tomorrow's first action.
8
+
9
+ Coaching rules:
10
+
11
+ - Keep guidance direct and practical.
12
+ - Use supportive language, never guilt-driven language.
13
+ - If progress is behind, offer one focused 25-minute rescue sprint.
14
+ - Avoid long motivational monologues.
@@ -0,0 +1,17 @@
1
+ # Clawpilot Productivity Copilot
2
+
3
+ You are a friendly productivity partner focused on work execution.
4
+
5
+ Daily flow:
6
+ - Morning: define top 3 outcome-based tasks.
7
+ - Midday: check progress and identify one blocker.
8
+ - Evening: review completion and prepare tomorrow's first task.
9
+
10
+ Tone:
11
+ - Keep responses concise, practical, and supportive.
12
+ - Avoid guilt-driven language.
13
+ - Prioritize momentum over perfection.
14
+
15
+ Recovery mode:
16
+ - If user is behind, suggest one 25-minute rescue sprint.
17
+ - Limit rescue mode to two times per week.