clawpad 0.3.1 → 0.3.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/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +9 -9
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/react-loadable-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +2 -2
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +4 -4
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/api/ai/write/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/changes/[id]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/changes/record/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/changes/revert/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/changes/run/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/chat/abort/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/chat/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/files/pages/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/files/recent/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/files/search/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/files/spaces/[space]/pages/route.js +1 -1
- package/.next/standalone/.next/server/app/api/files/spaces/[space]/pages/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/files/spaces/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/files/watch/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/gateway/detect/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/gateway/events/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/gateway/features/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/gateway/history/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/gateway/resolve/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/gateway/sessions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/gateway/status/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/openclaw/commands/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/settings/search-status/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/setup/bootstrap/route.js +83 -1
- package/.next/standalone/.next/server/app/api/setup/bootstrap/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/setup/bootstrap-workspace/route.js +1 -1
- package/.next/standalone/.next/server/app/api/setup/bootstrap-workspace/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/setup/status/route.js +1 -1
- package/.next/standalone/.next/server/app/api/setup/status/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/setup/trigger-onboarding/route.js +123 -10
- package/.next/standalone/.next/server/app/api/setup/trigger-onboarding/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/setup/trigger-onboarding/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +4 -4
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/connection/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/connection.html +1 -1
- package/.next/standalone/.next/server/app/settings/connection.rsc +4 -4
- package/.next/standalone/.next/server/app/settings/connection.segments/_full.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/settings/connection.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/connection.segments/_index.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/settings/connection.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/settings/connection.segments/settings/connection/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/connection.segments/settings/connection.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/connection.segments/settings.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings.html +1 -1
- package/.next/standalone/.next/server/app/settings.rsc +4 -4
- package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings.segments/_index.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings.segments/settings.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/setup/page.js +2 -2
- package/.next/standalone/.next/server/app/setup/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/setup.html +1 -1
- package/.next/standalone/.next/server/app/setup.rsc +5 -5
- package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +5 -5
- package/.next/standalone/.next/server/app/setup.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/setup.segments/_index.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/setup.segments/setup.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/workspace/[...path]/page.js +1 -1
- package/.next/standalone/.next/server/app/workspace/[...path]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/workspace/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workspace/page.js +2 -2
- package/.next/standalone/.next/server/app/workspace/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/workspace/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workspace/search/page.js +2 -2
- package/.next/standalone/.next/server/app/workspace/search/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/workspace/search/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workspace/search.html +2 -2
- package/.next/standalone/.next/server/app/workspace/search.rsc +6 -6
- package/.next/standalone/.next/server/app/workspace/search.segments/_full.segment.rsc +6 -6
- package/.next/standalone/.next/server/app/workspace/search.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/workspace/search.segments/_index.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/workspace/search.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/workspace/search.segments/workspace/search/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/workspace/search.segments/workspace/search.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/workspace/search.segments/workspace.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/workspace.html +2 -2
- package/.next/standalone/.next/server/app/workspace.rsc +6 -6
- package/.next/standalone/.next/server/app/workspace.segments/_full.segment.rsc +6 -6
- package/.next/standalone/.next/server/app/workspace.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/workspace.segments/_index.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/workspace.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/workspace.segments/workspace/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/workspace.segments/workspace.segment.rsc +2 -2
- package/.next/standalone/.next/server/app-paths-manifest.json +9 -9
- package/.next/standalone/.next/server/chunks/2470.js +3 -3
- package/.next/standalone/.next/server/chunks/3251.js +2 -3
- package/.next/standalone/.next/server/chunks/4098.js +9 -0
- package/.next/standalone/.next/server/chunks/{9703.js → 7035.js} +3 -3
- package/.next/standalone/.next/server/chunks/7772.js +1 -0
- package/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/.next/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +2 -2
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/package.json +2 -1
- package/.next/static/chunks/1178-f2f0bd687a63b9f8.js +4 -0
- package/.next/static/chunks/1592-8d48cfb007c02ef4.js +9 -0
- package/.next/static/chunks/{4839-8d9e473f5fea81c8.js → 20-4cfa0dd1c497eee3.js} +8 -8
- package/.next/static/chunks/3505-9fff91cc0bc3d611.js +1 -0
- package/.next/static/chunks/3678.620cb571eead466f.js +1 -0
- package/.next/static/chunks/385-4c7c8d3ad3b6b7db.js +1 -0
- package/.next/static/chunks/4559-722e02df6a03e69f.js +1 -0
- package/.next/static/chunks/6217-dcce2b95259e116b.js +1 -0
- package/.next/static/chunks/app/layout-c12666d2d05cce33.js +1 -0
- package/.next/static/chunks/app/setup/page-7eac0e007d7fcd58.js +1 -0
- package/.next/static/chunks/app/workspace/[...path]/page-5c4919e22385a024.js +1 -0
- package/.next/static/chunks/app/workspace/layout-9717963f2fdd1346.js +6 -0
- package/.next/static/chunks/app/workspace/page-3869e183f908f2fc.js +1 -0
- package/.next/static/chunks/app/workspace/search/page-d50c5815a7c7dc09.js +1 -0
- package/.next/static/chunks/{ba12c10f-9f20c2943b757ccd.js → ba12c10f-d2d630b861c021fb.js} +1 -1
- package/.next/static/chunks/{webpack-4017efb7c7e87263.js → webpack-2f676db6328b0d7d.js} +1 -1
- package/.next/static/css/a44c237eaaac8354.css +1 -0
- package/bin/clawpad.js +174 -9
- package/package.json +2 -1
- package/public/install.sh +32 -4
- package/skills/README.md +40 -0
- package/skills/workspace-manager/SKILL.md +449 -0
- package/.next/standalone/.next/server/chunks/8385.js +0 -9
- package/.next/static/chunks/3016-27e0c450e2ada8a3.js +0 -1
- package/.next/static/chunks/3678.7aa2a1e7fc03b615.js +0 -1
- package/.next/static/chunks/5488-cb187354d8aaa3d6.js +0 -1
- package/.next/static/chunks/7005-2786bffdf3d8496e.js +0 -9
- package/.next/static/chunks/8485-4d3e303f8e277e8d.js +0 -1
- package/.next/static/chunks/app/layout-8a46ab4a3e2d5cb0.js +0 -4
- package/.next/static/chunks/app/setup/page-a2a70f253bbf4382.js +0 -1
- package/.next/static/chunks/app/workspace/[...path]/page-d59a1f3dbc96308f.js +0 -4
- package/.next/static/chunks/app/workspace/layout-504ed80ab2d05d25.js +0 -10
- package/.next/static/chunks/app/workspace/page-677a7fccfea3cce2.js +0 -4
- package/.next/static/chunks/app/workspace/search/page-c00e5c231c4a1fdd.js +0 -1
- package/.next/static/css/3084c1365b9c9e06.css +0 -1
- /package/.next/static/{wrTc1IgxHQI9epHN29OBD → WjQpy-wj7aRX-ddVHKjXc}/_buildManifest.js +0 -0
- /package/.next/static/{wrTc1IgxHQI9epHN29OBD → WjQpy-wj7aRX-ddVHKjXc}/_ssgManifest.js +0 -0
package/bin/clawpad.js
CHANGED
|
@@ -20,6 +20,8 @@ const CRASH_RESTART_WINDOW_MS = 60_000;
|
|
|
20
20
|
const MAX_CRASH_RESTARTS = 3;
|
|
21
21
|
const CRASH_LOG_DIR = path.join(os.homedir(), ".clawpad", "logs");
|
|
22
22
|
const CRASH_LOG_PATH = path.join(CRASH_LOG_DIR, "launcher-crashes.log");
|
|
23
|
+
const QMD_INSTALL_SCRIPT_URL =
|
|
24
|
+
"https://raw.githubusercontent.com/tobi/qmd/main/install.sh";
|
|
23
25
|
|
|
24
26
|
// ─── Arg Parsing ─────────────────────────────────────────
|
|
25
27
|
const args = process.argv.slice(2);
|
|
@@ -37,6 +39,7 @@ let port =
|
|
|
37
39
|
const portExplicit = portIdx !== -1 || Boolean(process.env.PORT);
|
|
38
40
|
|
|
39
41
|
const shouldOpen = !args.includes("--no-open");
|
|
42
|
+
const shouldSetup = args.includes("--setup");
|
|
40
43
|
const shouldIntegrate = !args.includes("--no-integrate");
|
|
41
44
|
const autoYes = args.includes("--yes");
|
|
42
45
|
const noPrompt = args.includes("--no-prompt");
|
|
@@ -72,6 +75,7 @@ function printHelp() {
|
|
|
72
75
|
--no-open Don't auto-open the browser
|
|
73
76
|
--pages-dir <dir> Override docs directory (default: auto)
|
|
74
77
|
--migrate[=mode] Migrate legacy docs (mode: move|copy)
|
|
78
|
+
--setup Open setup onboarding flow on launch
|
|
75
79
|
--no-integrate Skip OpenClaw integration prompt
|
|
76
80
|
--yes Auto-approve integration steps
|
|
77
81
|
--no-prompt Disable integration prompt (skip changes)
|
|
@@ -82,6 +86,7 @@ function printHelp() {
|
|
|
82
86
|
clawpad Start on port ${DEFAULT_PORT}
|
|
83
87
|
clawpad -p 4000 Start on port 4000
|
|
84
88
|
clawpad --no-open Start without opening browser
|
|
89
|
+
clawpad --setup Start and open setup onboarding
|
|
85
90
|
clawpad --yes Auto-integrate with OpenClaw if detected
|
|
86
91
|
`);
|
|
87
92
|
}
|
|
@@ -676,6 +681,73 @@ function hasOpenClawBinary() {
|
|
|
676
681
|
}
|
|
677
682
|
}
|
|
678
683
|
|
|
684
|
+
function detectQmdBinary() {
|
|
685
|
+
try {
|
|
686
|
+
const qmdPath = execSync("command -v qmd", {
|
|
687
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
688
|
+
})
|
|
689
|
+
.toString()
|
|
690
|
+
.trim();
|
|
691
|
+
if (qmdPath) return qmdPath;
|
|
692
|
+
} catch {
|
|
693
|
+
// ignore
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
if (process.platform === "darwin") {
|
|
697
|
+
const candidate = "/opt/homebrew/bin/qmd";
|
|
698
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
return null;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
function ensureQmdInstalled() {
|
|
705
|
+
if (process.env.CLAWPAD_SKIP_QMD === "1") {
|
|
706
|
+
console.log(" ↩︎ Skipping QMD install (CLAWPAD_SKIP_QMD=1).");
|
|
707
|
+
return { installed: false, path: detectQmdBinary() };
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
const existing = detectQmdBinary();
|
|
711
|
+
if (existing) {
|
|
712
|
+
return { installed: true, path: existing };
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
if (process.platform === "darwin") {
|
|
716
|
+
try {
|
|
717
|
+
execSync("brew --version", { stdio: "ignore" });
|
|
718
|
+
console.log(" ⏳ Installing QMD with Homebrew...");
|
|
719
|
+
execSync("brew install qmd", { stdio: "inherit" });
|
|
720
|
+
} catch (err) {
|
|
721
|
+
const message = err && err.message ? err.message : String(err);
|
|
722
|
+
console.warn(` ⚠️ QMD Homebrew install failed: ${message}`);
|
|
723
|
+
}
|
|
724
|
+
} else if (process.platform === "linux") {
|
|
725
|
+
try {
|
|
726
|
+
console.log(" ⏳ Installing QMD from upstream installer...");
|
|
727
|
+
execSync(`curl -fsSL ${QMD_INSTALL_SCRIPT_URL} | bash`, { stdio: "inherit" });
|
|
728
|
+
} catch (err) {
|
|
729
|
+
const message = err && err.message ? err.message : String(err);
|
|
730
|
+
console.warn(` ⚠️ QMD installer failed: ${message}`);
|
|
731
|
+
}
|
|
732
|
+
} else {
|
|
733
|
+
console.log(` ↩︎ QMD auto-install not supported on ${process.platform}.`);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
const afterInstall = detectQmdBinary();
|
|
737
|
+
if (afterInstall) {
|
|
738
|
+
return { installed: true, path: afterInstall };
|
|
739
|
+
}
|
|
740
|
+
return { installed: false, path: null };
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
function getOnboardingSentinelPath() {
|
|
744
|
+
return path.join(resolveOpenClawStateDir(), "clawpad", "onboarding-complete.json");
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
function hasCompletedOnboarding() {
|
|
748
|
+
return fs.existsSync(getOnboardingSentinelPath());
|
|
749
|
+
}
|
|
750
|
+
|
|
679
751
|
function resolveWorkspaceDir(config) {
|
|
680
752
|
const workspace = config?.agents?.defaults?.workspace;
|
|
681
753
|
if (typeof workspace === "string" && workspace.trim()) {
|
|
@@ -719,6 +791,32 @@ function copyDir(src, dest) {
|
|
|
719
791
|
}
|
|
720
792
|
}
|
|
721
793
|
|
|
794
|
+
function ensureBundledSkillInstalled(workspaceDir, skillName) {
|
|
795
|
+
if (!workspaceDir || !skillName) {
|
|
796
|
+
return { installed: false, reason: "invalid-input" };
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
const bundledSkillPath = path.join(ROOT_DIR, "skills", skillName);
|
|
800
|
+
if (!fs.existsSync(bundledSkillPath)) {
|
|
801
|
+
return { installed: false, reason: "missing-bundled-skill" };
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
const skillsDir = path.join(workspaceDir, "skills");
|
|
805
|
+
const targetSkillPath = path.join(skillsDir, skillName);
|
|
806
|
+
|
|
807
|
+
if (fs.existsSync(targetSkillPath)) {
|
|
808
|
+
return { installed: false, reason: "already-installed" };
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
try {
|
|
812
|
+
fs.mkdirSync(skillsDir, { recursive: true });
|
|
813
|
+
copyDir(bundledSkillPath, targetSkillPath);
|
|
814
|
+
return { installed: true, reason: "installed" };
|
|
815
|
+
} catch (err) {
|
|
816
|
+
return { installed: false, reason: (err && err.message) || "copy-failed" };
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
|
|
722
820
|
function migrateLegacyPages(fromDir, toDir, mode) {
|
|
723
821
|
if (!fs.existsSync(fromDir)) {
|
|
724
822
|
return { ok: false, reason: "missing" };
|
|
@@ -794,7 +892,7 @@ async function maybeMigrateLegacyPages(config, resolvedPagesDir) {
|
|
|
794
892
|
return { pagesDir: targetDir, migrated: migrated.ok };
|
|
795
893
|
}
|
|
796
894
|
|
|
797
|
-
function applyIntegrationConfig(config, pagesDir) {
|
|
895
|
+
function applyIntegrationConfig(config, pagesDir, qmdPath) {
|
|
798
896
|
const next = config && typeof config === "object" ? config : {};
|
|
799
897
|
next.plugins = next.plugins || {};
|
|
800
898
|
next.plugins.entries = next.plugins.entries || {};
|
|
@@ -810,6 +908,17 @@ function applyIntegrationConfig(config, pagesDir) {
|
|
|
810
908
|
|
|
811
909
|
next.agents = next.agents || {};
|
|
812
910
|
next.agents.defaults = next.agents.defaults || {};
|
|
911
|
+
const memory = next.agents.defaults.memory || {};
|
|
912
|
+
const memoryQmd = memory.qmd || {};
|
|
913
|
+
next.agents.defaults.memory = {
|
|
914
|
+
...memory,
|
|
915
|
+
backend: "qmd",
|
|
916
|
+
qmd: {
|
|
917
|
+
...memoryQmd,
|
|
918
|
+
...(qmdPath ? { bin: qmdPath } : {}),
|
|
919
|
+
},
|
|
920
|
+
};
|
|
921
|
+
|
|
813
922
|
const memorySearch = next.agents.defaults.memorySearch || {};
|
|
814
923
|
const extraPaths = Array.isArray(memorySearch.extraPaths) ? [...memorySearch.extraPaths] : [];
|
|
815
924
|
if (!extraPaths.includes(pagesDir)) {
|
|
@@ -823,18 +932,21 @@ function applyIntegrationConfig(config, pagesDir) {
|
|
|
823
932
|
return next;
|
|
824
933
|
}
|
|
825
934
|
|
|
826
|
-
function needsIntegrationPatch(config, pagesDir) {
|
|
827
|
-
const entry = config?.plugins?.entries?.
|
|
935
|
+
function needsIntegrationPatch(config, pagesDir, qmdPath) {
|
|
936
|
+
const entry = config?.plugins?.entries?.["openclaw-plugin"];
|
|
828
937
|
const configuredPages =
|
|
829
938
|
entry?.config?.pagesDir || entry?.config?.pages_dir;
|
|
830
939
|
const pluginEnabled = entry?.enabled === true;
|
|
831
940
|
const extraPaths = config?.agents?.defaults?.memorySearch?.extraPaths;
|
|
832
941
|
const hasExtraPath = Array.isArray(extraPaths) && extraPaths.includes(pagesDir);
|
|
942
|
+
const memoryBackend = config?.agents?.defaults?.memory?.backend;
|
|
943
|
+
const configuredQmdBin = config?.agents?.defaults?.memory?.qmd?.bin;
|
|
944
|
+
const qmdConfigured = memoryBackend === "qmd" && (!qmdPath || configuredQmdBin === qmdPath);
|
|
833
945
|
|
|
834
|
-
return !(pluginEnabled && configuredPages === pagesDir && hasExtraPath);
|
|
946
|
+
return !(pluginEnabled && configuredPages === pagesDir && hasExtraPath && qmdConfigured);
|
|
835
947
|
}
|
|
836
948
|
|
|
837
|
-
async function integrateWithOpenClaw(pagesDir) {
|
|
949
|
+
async function integrateWithOpenClaw(pagesDir, qmdPath) {
|
|
838
950
|
if (!shouldIntegrate) return;
|
|
839
951
|
if (!hasOpenClawBinary()) return;
|
|
840
952
|
|
|
@@ -842,7 +954,12 @@ async function integrateWithOpenClaw(pagesDir) {
|
|
|
842
954
|
const pluginInstalled = isPluginInstalled(config);
|
|
843
955
|
const workspaceDir = resolveWorkspaceDir(config);
|
|
844
956
|
|
|
845
|
-
const
|
|
957
|
+
const workspaceManagerSkill = ensureBundledSkillInstalled(workspaceDir, "workspace-manager");
|
|
958
|
+
if (workspaceManagerSkill.installed) {
|
|
959
|
+
console.log(" ✅ Installed workspace-manager skill in OpenClaw workspace.");
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
const needsConfigPatch = needsIntegrationPatch(config, pagesDir, qmdPath);
|
|
846
963
|
const needsAgentsNote = fs.existsSync(path.join(workspaceDir, "AGENTS.md"));
|
|
847
964
|
|
|
848
965
|
if (!pluginInstalled && noPrompt && !autoYes) {
|
|
@@ -867,7 +984,7 @@ async function integrateWithOpenClaw(pagesDir) {
|
|
|
867
984
|
}
|
|
868
985
|
|
|
869
986
|
if (needsConfigPatch) {
|
|
870
|
-
const patched = applyIntegrationConfig(config, pagesDir);
|
|
987
|
+
const patched = applyIntegrationConfig(config, pagesDir, qmdPath);
|
|
871
988
|
writeOpenClawConfig(configPath, patched);
|
|
872
989
|
}
|
|
873
990
|
|
|
@@ -878,6 +995,43 @@ async function integrateWithOpenClaw(pagesDir) {
|
|
|
878
995
|
console.log(" ✅ OpenClaw integration configured. Restart the gateway to apply.");
|
|
879
996
|
}
|
|
880
997
|
|
|
998
|
+
function isWorkspaceEmpty(pagesDir) {
|
|
999
|
+
try {
|
|
1000
|
+
const entries = fs
|
|
1001
|
+
.readdirSync(pagesDir, { withFileTypes: true })
|
|
1002
|
+
.filter((entry) => !entry.name.startsWith("."));
|
|
1003
|
+
return entries.length === 0;
|
|
1004
|
+
} catch {
|
|
1005
|
+
return true;
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
function ensureSetupSignal(pagesDir, options = {}) {
|
|
1010
|
+
const signalPath = path.join(pagesDir, ".clawpad-needs-setup");
|
|
1011
|
+
const force = options.force === true;
|
|
1012
|
+
|
|
1013
|
+
try {
|
|
1014
|
+
fs.mkdirSync(pagesDir, { recursive: true });
|
|
1015
|
+
|
|
1016
|
+
if (!force && hasCompletedOnboarding()) {
|
|
1017
|
+
return false;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
if (!force && !isWorkspaceEmpty(pagesDir)) {
|
|
1021
|
+
return false;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
const payload = {
|
|
1025
|
+
created: new Date().toISOString(),
|
|
1026
|
+
reason: force ? "cli-setup-flag" : "first-run-empty-workspace",
|
|
1027
|
+
};
|
|
1028
|
+
fs.writeFileSync(signalPath, JSON.stringify(payload, null, 2), "utf-8");
|
|
1029
|
+
return true;
|
|
1030
|
+
} catch {
|
|
1031
|
+
return false;
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
|
|
881
1035
|
// ─── Build Check ─────────────────────────────────────────
|
|
882
1036
|
function isBuilt() {
|
|
883
1037
|
const standaloneServer = path.join(ROOT_DIR, ".next", "standalone", "server.js");
|
|
@@ -973,7 +1127,17 @@ async function main() {
|
|
|
973
1127
|
if (!process.env.CLAWPAD_PAGES_DIR && pagesDir) {
|
|
974
1128
|
process.env.CLAWPAD_PAGES_DIR = pagesDir;
|
|
975
1129
|
}
|
|
976
|
-
|
|
1130
|
+
const qmd = ensureQmdInstalled();
|
|
1131
|
+
if (qmd.installed && qmd.path) {
|
|
1132
|
+
console.log(` ✅ QMD available at ${qmd.path}`);
|
|
1133
|
+
} else {
|
|
1134
|
+
console.log(" ⚠️ QMD unavailable. Semantic search and QMD memory backend may be limited.");
|
|
1135
|
+
}
|
|
1136
|
+
await integrateWithOpenClaw(pagesDir, qmd.path);
|
|
1137
|
+
const setupSignalCreated = ensureSetupSignal(pagesDir, { force: shouldSetup });
|
|
1138
|
+
if (setupSignalCreated) {
|
|
1139
|
+
console.log(" 📝 Setup signal detected. ClawPad will open onboarding.");
|
|
1140
|
+
}
|
|
977
1141
|
|
|
978
1142
|
// Build if needed
|
|
979
1143
|
if (!isBuilt()) {
|
|
@@ -1071,7 +1235,8 @@ async function main() {
|
|
|
1071
1235
|
const launchServer = (nextPort) => {
|
|
1072
1236
|
port = nextPort;
|
|
1073
1237
|
const runningPort = nextPort;
|
|
1074
|
-
const
|
|
1238
|
+
const setupPath = shouldSetup || setupSignalCreated ? "/setup" : "";
|
|
1239
|
+
const url = `http://localhost:${port}${setupPath}`;
|
|
1075
1240
|
console.log(` 🚀 Starting ClawPad at ${url}\n`);
|
|
1076
1241
|
|
|
1077
1242
|
let sawAddrInUse = false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clawpad",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "A file-based, Notion-style document workspace for OpenClaw",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openclaw",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"files": [
|
|
28
28
|
"bin/",
|
|
29
|
+
"skills/",
|
|
29
30
|
".next/standalone/",
|
|
30
31
|
".next/static/",
|
|
31
32
|
"public/",
|
package/public/install.sh
CHANGED
|
@@ -9,7 +9,7 @@ INSTALL_PREFIX="${CLAWPAD_PREFIX:-$HOME/.local}"
|
|
|
9
9
|
INSTALL_TIMEOUT_SECONDS="${CLAWPAD_INSTALL_TIMEOUT_SECONDS:-180}"
|
|
10
10
|
|
|
11
11
|
echo "ClawPad installer"
|
|
12
|
-
echo "[1/
|
|
12
|
+
echo "[1/5] Checking Node.js..."
|
|
13
13
|
|
|
14
14
|
if ! command -v node >/dev/null 2>&1; then
|
|
15
15
|
echo "ClawPad requires Node.js ${MIN_NODE_MAJOR}+." >&2
|
|
@@ -28,7 +28,7 @@ if ! command -v npm >/dev/null 2>&1; then
|
|
|
28
28
|
exit 1
|
|
29
29
|
fi
|
|
30
30
|
|
|
31
|
-
echo "[2/
|
|
31
|
+
echo "[2/5] Preparing install prefix: ${INSTALL_PREFIX}"
|
|
32
32
|
mkdir -p "${INSTALL_PREFIX}/bin"
|
|
33
33
|
|
|
34
34
|
# Make npm quieter and avoid long post-install checks
|
|
@@ -37,7 +37,7 @@ export NPM_CONFIG_AUDIT=false
|
|
|
37
37
|
export NPM_CONFIG_UPDATE_NOTIFIER=false
|
|
38
38
|
export NPM_CONFIG_PROGRESS=false
|
|
39
39
|
|
|
40
|
-
echo "[3/
|
|
40
|
+
echo "[3/5] Installing ClawPad (this can take a minute)..."
|
|
41
41
|
|
|
42
42
|
# Install clawpad CLI into user prefix
|
|
43
43
|
install_args=(install -g clawpad --prefix "${INSTALL_PREFIX}")
|
|
@@ -65,8 +65,36 @@ if [ "${install_exit}" -ne 0 ]; then
|
|
|
65
65
|
exit "${install_exit}"
|
|
66
66
|
fi
|
|
67
67
|
|
|
68
|
+
# Best-effort QMD install
|
|
69
|
+
echo "[4/5] Checking QMD (best-effort)"
|
|
70
|
+
if [ "${CLAWPAD_SKIP_QMD:-0}" = "1" ]; then
|
|
71
|
+
echo "Skipping QMD install (CLAWPAD_SKIP_QMD=1)."
|
|
72
|
+
elif command -v qmd >/dev/null 2>&1; then
|
|
73
|
+
echo "QMD already installed."
|
|
74
|
+
elif [ "$(uname -s)" = "Darwin" ] && command -v brew >/dev/null 2>&1; then
|
|
75
|
+
if brew install qmd; then
|
|
76
|
+
echo "QMD installed with Homebrew."
|
|
77
|
+
else
|
|
78
|
+
echo "QMD install failed via Homebrew (continuing)." >&2
|
|
79
|
+
fi
|
|
80
|
+
elif [ "$(uname -s)" = "Linux" ] && command -v curl >/dev/null 2>&1; then
|
|
81
|
+
if curl -fsSL https://raw.githubusercontent.com/tobi/qmd/main/install.sh | bash; then
|
|
82
|
+
echo "QMD installed from upstream installer."
|
|
83
|
+
else
|
|
84
|
+
echo "QMD install failed via upstream script (continuing)." >&2
|
|
85
|
+
fi
|
|
86
|
+
else
|
|
87
|
+
echo "QMD auto-install skipped: unsupported platform or missing installer dependency."
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
if command -v qmd >/dev/null 2>&1; then
|
|
91
|
+
echo "QMD ready: $(qmd --version 2>/dev/null || echo qmd)"
|
|
92
|
+
else
|
|
93
|
+
echo "QMD unavailable. You can install it later for semantic search."
|
|
94
|
+
fi
|
|
95
|
+
|
|
68
96
|
# Add prefix bin to PATH if needed
|
|
69
|
-
echo "[
|
|
97
|
+
echo "[5/5] Finalizing PATH setup"
|
|
70
98
|
if ! echo "$PATH" | grep -q "${INSTALL_PREFIX}/bin"; then
|
|
71
99
|
if [ -f "$HOME/.bashrc" ]; then
|
|
72
100
|
echo "export PATH=\"${INSTALL_PREFIX}/bin:\$PATH\"" >> "$HOME/.bashrc"
|
package/skills/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# ClawPad Skills
|
|
2
|
+
|
|
3
|
+
Community skills for enhancing ClawPad workspaces.
|
|
4
|
+
|
|
5
|
+
## Available Skills
|
|
6
|
+
|
|
7
|
+
| Skill | Description |
|
|
8
|
+
|-------|-------------|
|
|
9
|
+
| [workspace-manager](./workspace-manager/) | Workspace setup and organization assistant. Helps users create personalized folder structures based on their domain (engineering, research, business, creative, personal). |
|
|
10
|
+
|
|
11
|
+
## Installing Skills
|
|
12
|
+
|
|
13
|
+
Skills are automatically discovered by OpenClaw from `~/.openclaw/workspace/skills/`.
|
|
14
|
+
|
|
15
|
+
To install a skill:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Copy the skill folder to your OpenClaw workspace
|
|
19
|
+
cp -r skills/workspace-manager ~/.openclaw/workspace/skills/
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or symlink for development:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
ln -s $(pwd)/skills/workspace-manager ~/.openclaw/workspace/skills/workspace-manager
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Creating Skills
|
|
29
|
+
|
|
30
|
+
See [OpenClaw Skills Documentation](https://docs.openclaw.ai/skills) for the full guide.
|
|
31
|
+
|
|
32
|
+
Basic structure:
|
|
33
|
+
```
|
|
34
|
+
skills/
|
|
35
|
+
└── your-skill/
|
|
36
|
+
├── SKILL.md # Main skill definition (required)
|
|
37
|
+
└── references/ # Optional supporting files
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The `SKILL.md` file should have YAML frontmatter with `name` and `description`, followed by markdown instructions for the agent.
|