@jayjiang/byoao 0.2.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/dist/cli/cli-program.js +241 -0
- package/dist/cli/cli-program.js.map +1 -0
- package/dist/cli/installer.js +226 -0
- package/dist/cli/installer.js.map +1 -0
- package/dist/cli/ui.js +157 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/hooks/idle-suggestions.js +14 -0
- package/dist/hooks/idle-suggestions.js.map +1 -0
- package/dist/hooks/system-transform.js +34 -0
- package/dist/hooks/system-transform.js.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin-config.js +57 -0
- package/dist/plugin-config.js.map +1 -0
- package/dist/tools/add-glossary-term.js +19 -0
- package/dist/tools/add-glossary-term.js.map +1 -0
- package/dist/tools/add-member.js +21 -0
- package/dist/tools/add-member.js.map +1 -0
- package/dist/tools/add-project.js +24 -0
- package/dist/tools/add-project.js.map +1 -0
- package/dist/tools/init-vault.js +82 -0
- package/dist/tools/init-vault.js.map +1 -0
- package/dist/tools/vault-doctor.js +38 -0
- package/dist/tools/vault-doctor.js.map +1 -0
- package/dist/tools/vault-status.js +18 -0
- package/dist/tools/vault-status.js.map +1 -0
- package/dist/vault/create.js +230 -0
- package/dist/vault/create.js.map +1 -0
- package/dist/vault/doctor.js +148 -0
- package/dist/vault/doctor.js.map +1 -0
- package/dist/vault/glossary.js +33 -0
- package/dist/vault/glossary.js.map +1 -0
- package/dist/vault/member.js +67 -0
- package/dist/vault/member.js.map +1 -0
- package/dist/vault/obsidian-check.js +125 -0
- package/dist/vault/obsidian-check.js.map +1 -0
- package/dist/vault/obsidian-cli.js +47 -0
- package/dist/vault/obsidian-cli.js.map +1 -0
- package/dist/vault/opencode-check.js +65 -0
- package/dist/vault/opencode-check.js.map +1 -0
- package/dist/vault/preset.js +48 -0
- package/dist/vault/preset.js.map +1 -0
- package/dist/vault/project.js +68 -0
- package/dist/vault/project.js.map +1 -0
- package/dist/vault/status.js +135 -0
- package/dist/vault/status.js.map +1 -0
- package/dist/vault/template.js +14 -0
- package/dist/vault/template.js.map +1 -0
- package/package.json +58 -0
- package/src/assets/obsidian-skills/defuddle.md +41 -0
- package/src/assets/obsidian-skills/json-canvas.md +244 -0
- package/src/assets/obsidian-skills/obsidian-bases.md +497 -0
- package/src/assets/obsidian-skills/obsidian-cli.md +106 -0
- package/src/assets/obsidian-skills/obsidian-markdown.md +196 -0
- package/src/assets/presets/common/AGENT.md.hbs +29 -0
- package/src/assets/presets/common/Glossary.md.hbs +44 -0
- package/src/assets/presets/common/Start Here.md.hbs +95 -0
- package/src/assets/presets/common/obsidian/core-plugins.json +33 -0
- package/src/assets/presets/common/obsidian/daily-notes.json +5 -0
- package/src/assets/presets/common/obsidian/templates.json +3 -0
- package/src/assets/presets/common/templates/Daily Note.md +19 -0
- package/src/assets/presets/common/templates/Decision Record.md +32 -0
- package/src/assets/presets/common/templates/Investigation.md +34 -0
- package/src/assets/presets/common/templates/Meeting Notes.md +25 -0
- package/src/assets/presets/pm-tpm/agent-section.hbs +15 -0
- package/src/assets/presets/pm-tpm/preset.json +12 -0
- package/src/assets/presets/pm-tpm/templates/Feature Doc.md +45 -0
- package/src/assets/presets/pm-tpm/templates/Sprint Handoff.md +38 -0
- package/src/assets/web-clipper/confluence-page.json +63 -0
- package/src/assets/web-clipper/general-article.json +53 -0
- package/src/assets/web-clipper/jira-issue.json +68 -0
- package/src/assets/web-clipper/meeting-notes.json +53 -0
- package/src/skills/enrich-document.md +52 -0
- package/src/skills/init-knowledge-base.md +85 -0
- package/src/skills/system-explainer.md +58 -0
- package/src/skills/vault-doctor.md +73 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { install } from "./installer.js";
|
|
4
|
+
import { printLogo, printVersion, printEvent, printEventDetail, printEventDone } from "./ui.js";
|
|
5
|
+
import { createVault } from "../vault/create.js";
|
|
6
|
+
import { getVaultStatus, formatVaultStatus } from "../vault/status.js";
|
|
7
|
+
import { checkObsidian, formatObsidianStatus } from "../vault/obsidian-check.js";
|
|
8
|
+
import { listPresets } from "../vault/preset.js";
|
|
9
|
+
import { VaultConfigSchema } from "../plugin-config.js";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import os from "node:os";
|
|
12
|
+
const program = new Command();
|
|
13
|
+
program
|
|
14
|
+
.name("byoao")
|
|
15
|
+
.description("Build Your Own AI OS — Obsidian + AI Agent")
|
|
16
|
+
.version("0.2.0");
|
|
17
|
+
// ── byoao install ────────────────────────────────────────────────
|
|
18
|
+
program
|
|
19
|
+
.command("install")
|
|
20
|
+
.description("Install BYOAO plugin into OpenCode")
|
|
21
|
+
.option("-g, --global", "Install globally (all projects)", false)
|
|
22
|
+
.option("-y, --yes", "Skip interactive prompts, use defaults/flags", false)
|
|
23
|
+
.option("--no-skills", "Skip installing Obsidian Skills")
|
|
24
|
+
.option("--project-dir <path>", "Project directory (default: current directory)")
|
|
25
|
+
.action(async (opts) => {
|
|
26
|
+
printLogo();
|
|
27
|
+
printVersion("0.2.0");
|
|
28
|
+
let installGlobal = opts.global;
|
|
29
|
+
let installSkills = opts.skills !== false;
|
|
30
|
+
// Interactive prompts unless --yes flag is set
|
|
31
|
+
if (!opts.yes)
|
|
32
|
+
try {
|
|
33
|
+
const { default: inquirer } = await import("inquirer");
|
|
34
|
+
const answers = await inquirer.prompt([
|
|
35
|
+
{
|
|
36
|
+
type: "list",
|
|
37
|
+
name: "location",
|
|
38
|
+
message: "Install location:",
|
|
39
|
+
choices: [
|
|
40
|
+
{ name: "global (all projects)", value: "global" },
|
|
41
|
+
{ name: "project-only (current directory)", value: "project" },
|
|
42
|
+
],
|
|
43
|
+
default: installGlobal ? "global" : "project",
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
type: "confirm",
|
|
47
|
+
name: "skills",
|
|
48
|
+
message: "Install Obsidian Skills? (obsidian-cli, obsidian-markdown, etc.)",
|
|
49
|
+
default: true,
|
|
50
|
+
},
|
|
51
|
+
]);
|
|
52
|
+
installGlobal = answers.location === "global";
|
|
53
|
+
installSkills = answers.skills;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// inquirer not available — use CLI flags
|
|
57
|
+
}
|
|
58
|
+
await install({
|
|
59
|
+
global: installGlobal,
|
|
60
|
+
installSkills,
|
|
61
|
+
projectDir: opts.projectDir,
|
|
62
|
+
}, !opts.yes);
|
|
63
|
+
});
|
|
64
|
+
// ── byoao vault init ────────────────────────────────────────────
|
|
65
|
+
program
|
|
66
|
+
.command("vault")
|
|
67
|
+
.description("Vault management commands")
|
|
68
|
+
.command("init")
|
|
69
|
+
.description("Create a new Obsidian vault for a team")
|
|
70
|
+
.option("--team <name>", "Team name")
|
|
71
|
+
.option("--path <path>", "Vault location")
|
|
72
|
+
.option("--preset <name>", "Role preset (default: pm-tpm)")
|
|
73
|
+
.action(async (opts) => {
|
|
74
|
+
// Check Obsidian first
|
|
75
|
+
const obsidianStatus = checkObsidian();
|
|
76
|
+
if (!obsidianStatus.installed) {
|
|
77
|
+
console.log(formatObsidianStatus(obsidianStatus));
|
|
78
|
+
console.log("\nPlease install Obsidian first, then try again.");
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
let teamName = opts.team;
|
|
82
|
+
let vaultPath = opts.path;
|
|
83
|
+
let presetName = opts.preset || "pm-tpm";
|
|
84
|
+
let members = [];
|
|
85
|
+
let projects = [];
|
|
86
|
+
// Interactive TUI when --team is not provided and stdout is TTY
|
|
87
|
+
if (!teamName && process.stdout.isTTY) {
|
|
88
|
+
try {
|
|
89
|
+
const { default: inquirer } = await import("inquirer");
|
|
90
|
+
printEvent("Creating a new knowledge base");
|
|
91
|
+
console.log();
|
|
92
|
+
// 1. Role selection
|
|
93
|
+
const presets = listPresets();
|
|
94
|
+
const { selectedPreset } = await inquirer.prompt([{
|
|
95
|
+
type: "list",
|
|
96
|
+
name: "selectedPreset",
|
|
97
|
+
message: "Choose your role",
|
|
98
|
+
choices: [
|
|
99
|
+
...presets.map(p => ({
|
|
100
|
+
name: `${p.displayName} — ${p.description}`,
|
|
101
|
+
value: p.name,
|
|
102
|
+
})),
|
|
103
|
+
new inquirer.Separator(),
|
|
104
|
+
{ name: "Engineer (coming soon)", disabled: true },
|
|
105
|
+
{ name: "Designer (coming soon)", disabled: true },
|
|
106
|
+
],
|
|
107
|
+
}]);
|
|
108
|
+
presetName = selectedPreset;
|
|
109
|
+
// 2. Team name
|
|
110
|
+
const teamAnswer = await inquirer.prompt([{
|
|
111
|
+
type: "input",
|
|
112
|
+
name: "teamName",
|
|
113
|
+
message: "Team name:",
|
|
114
|
+
validate: (v) => v.trim() ? true : "Team name is required",
|
|
115
|
+
}]);
|
|
116
|
+
teamName = teamAnswer.teamName;
|
|
117
|
+
// 3. Vault path
|
|
118
|
+
const defaultPath = path.join(os.homedir(), "Documents", `${teamName} Workspace`);
|
|
119
|
+
const { pathChoice } = await inquirer.prompt([{
|
|
120
|
+
type: "list",
|
|
121
|
+
name: "pathChoice",
|
|
122
|
+
message: "Vault location",
|
|
123
|
+
choices: [
|
|
124
|
+
{ name: `Use default (${defaultPath})`, value: "default" },
|
|
125
|
+
{ name: "Choose custom path", value: "custom" },
|
|
126
|
+
],
|
|
127
|
+
}]);
|
|
128
|
+
vaultPath = defaultPath;
|
|
129
|
+
if (pathChoice === "custom") {
|
|
130
|
+
const { customPath } = await inquirer.prompt([{
|
|
131
|
+
type: "input",
|
|
132
|
+
name: "customPath",
|
|
133
|
+
message: "Custom path:",
|
|
134
|
+
}]);
|
|
135
|
+
vaultPath = customPath;
|
|
136
|
+
}
|
|
137
|
+
// 4. Members loop
|
|
138
|
+
let addingMembers = true;
|
|
139
|
+
while (addingMembers) {
|
|
140
|
+
const { action } = await inquirer.prompt([{
|
|
141
|
+
type: "list",
|
|
142
|
+
name: "action",
|
|
143
|
+
message: `Team members (${members.length} added)`,
|
|
144
|
+
choices: [
|
|
145
|
+
{ name: "Add a member", value: "add" },
|
|
146
|
+
{ name: "Done", value: "done" },
|
|
147
|
+
],
|
|
148
|
+
}]);
|
|
149
|
+
if (action === "done")
|
|
150
|
+
break;
|
|
151
|
+
const { name, role } = await inquirer.prompt([
|
|
152
|
+
{ type: "input", name: "name", message: "Name:" },
|
|
153
|
+
{ type: "input", name: "role", message: "Role:", default: "" },
|
|
154
|
+
]);
|
|
155
|
+
if (name.trim())
|
|
156
|
+
members.push({ name: name.trim(), role: role.trim() || "Team Member" });
|
|
157
|
+
}
|
|
158
|
+
// 5. Projects loop
|
|
159
|
+
let addingProjects = true;
|
|
160
|
+
while (addingProjects) {
|
|
161
|
+
const { action } = await inquirer.prompt([{
|
|
162
|
+
type: "list",
|
|
163
|
+
name: "action",
|
|
164
|
+
message: `Projects (${projects.length} added)`,
|
|
165
|
+
choices: [
|
|
166
|
+
{ name: "Add a project", value: "add" },
|
|
167
|
+
{ name: "Done", value: "done" },
|
|
168
|
+
],
|
|
169
|
+
}]);
|
|
170
|
+
if (action === "done")
|
|
171
|
+
break;
|
|
172
|
+
const { name, description } = await inquirer.prompt([
|
|
173
|
+
{ type: "input", name: "name", message: "Project name:" },
|
|
174
|
+
{ type: "input", name: "description", message: "Description:", default: "" },
|
|
175
|
+
]);
|
|
176
|
+
if (name.trim())
|
|
177
|
+
projects.push({ name: name.trim(), description: description.trim() || "" });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
// inquirer not available — fall through to require --team
|
|
182
|
+
if (!teamName) {
|
|
183
|
+
console.error("Error: --team flag is required in non-interactive mode");
|
|
184
|
+
process.exit(1);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (!teamName) {
|
|
189
|
+
console.error("Error: --team flag is required");
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
vaultPath = vaultPath || path.join(os.homedir(), "Documents", `${teamName} Workspace`);
|
|
193
|
+
const config = VaultConfigSchema.parse({
|
|
194
|
+
teamName,
|
|
195
|
+
vaultPath,
|
|
196
|
+
members,
|
|
197
|
+
projects,
|
|
198
|
+
preset: presetName,
|
|
199
|
+
});
|
|
200
|
+
printEvent(`Creating vault for "${teamName}"`);
|
|
201
|
+
const result = await createVault(config);
|
|
202
|
+
console.log();
|
|
203
|
+
printEventDone("Vault created");
|
|
204
|
+
printEventDetail(`Path: ${result.vaultPath}`);
|
|
205
|
+
printEventDetail(`Files: ${result.filesCreated}`);
|
|
206
|
+
printEventDetail(`Wikilinks: ${result.wikilinksCreated}`);
|
|
207
|
+
printEventDetail(`Directories: ${result.directories.length}`);
|
|
208
|
+
if (!obsidianStatus.running) {
|
|
209
|
+
console.log();
|
|
210
|
+
console.log(formatObsidianStatus(obsidianStatus));
|
|
211
|
+
}
|
|
212
|
+
console.log(`\nNext: Open Obsidian → "Open folder as vault" → select "${result.vaultPath}"`);
|
|
213
|
+
});
|
|
214
|
+
// ── byoao vault status ──────────────────────────────────────────
|
|
215
|
+
// We need to add status as a sibling command under vault
|
|
216
|
+
// Commander's nested commands require a parent command object
|
|
217
|
+
const vaultCmd = program.commands.find((c) => c.name() === "vault");
|
|
218
|
+
if (vaultCmd) {
|
|
219
|
+
vaultCmd
|
|
220
|
+
.command("status")
|
|
221
|
+
.description("Check vault health")
|
|
222
|
+
.argument("<path>", "Path to the vault")
|
|
223
|
+
.action(async (vaultPath) => {
|
|
224
|
+
const resolvedPath = path.resolve(vaultPath);
|
|
225
|
+
const status = await getVaultStatus(resolvedPath);
|
|
226
|
+
console.log(formatVaultStatus(status));
|
|
227
|
+
console.log("\n--- Obsidian ---");
|
|
228
|
+
const obsidianStatus = checkObsidian();
|
|
229
|
+
console.log(formatObsidianStatus(obsidianStatus));
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
// ── byoao check-obsidian ────────────────────────────────────────
|
|
233
|
+
program
|
|
234
|
+
.command("check-obsidian")
|
|
235
|
+
.description("Check if Obsidian is installed and running")
|
|
236
|
+
.action(() => {
|
|
237
|
+
const status = checkObsidian();
|
|
238
|
+
console.log(formatObsidianStatus(status));
|
|
239
|
+
});
|
|
240
|
+
program.parse();
|
|
241
|
+
//# sourceMappingURL=cli-program.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-program.js","sourceRoot":"","sources":["../../src/cli/cli-program.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import fs from "fs-extra";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import { execSync } from "node:child_process";
|
|
5
|
+
import { checkObsidian } from "../vault/obsidian-check.js";
|
|
6
|
+
import { checkOpenCode } from "../vault/opencode-check.js";
|
|
7
|
+
import { printSectionHeader, printProgress, printProgressWithBar, printGettingStarted, printFooter, printBlank, printWarning, printInfo, } from "./ui.js";
|
|
8
|
+
const OPENCODE_CONFIG_PATHS = [
|
|
9
|
+
// Global config
|
|
10
|
+
path.join(os.homedir(), ".config/opencode/opencode.json"),
|
|
11
|
+
// Legacy path
|
|
12
|
+
path.join(os.homedir(), ".config/opencode/.opencode.json"),
|
|
13
|
+
];
|
|
14
|
+
function findOpencodeConfig() {
|
|
15
|
+
for (const p of OPENCODE_CONFIG_PATHS) {
|
|
16
|
+
if (fs.existsSync(p))
|
|
17
|
+
return p;
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
/** Prompt user to install a missing dependency. Returns true if installed successfully. */
|
|
22
|
+
async function promptInstallDependency(name, installCommands, interactive) {
|
|
23
|
+
if (!interactive)
|
|
24
|
+
return false;
|
|
25
|
+
try {
|
|
26
|
+
const { default: inquirer } = await import("inquirer");
|
|
27
|
+
const { shouldInstall } = await inquirer.prompt([
|
|
28
|
+
{
|
|
29
|
+
type: "confirm",
|
|
30
|
+
name: "shouldInstall",
|
|
31
|
+
message: `${name} is not installed. Would you like to install it now?`,
|
|
32
|
+
default: true,
|
|
33
|
+
},
|
|
34
|
+
]);
|
|
35
|
+
if (!shouldInstall)
|
|
36
|
+
return false;
|
|
37
|
+
// Let user pick install method if there are multiple options
|
|
38
|
+
let command;
|
|
39
|
+
if (installCommands.length === 1) {
|
|
40
|
+
command = installCommands[0].command;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const { method } = await inquirer.prompt([
|
|
44
|
+
{
|
|
45
|
+
type: "list",
|
|
46
|
+
name: "method",
|
|
47
|
+
message: "Install method:",
|
|
48
|
+
choices: installCommands.map((c) => ({
|
|
49
|
+
name: `${c.label}: ${c.command}`,
|
|
50
|
+
value: c.command,
|
|
51
|
+
})),
|
|
52
|
+
},
|
|
53
|
+
]);
|
|
54
|
+
command = method;
|
|
55
|
+
}
|
|
56
|
+
console.log(`\nRunning: ${command}\n`);
|
|
57
|
+
execSync(command, { stdio: "inherit", timeout: 120_000 });
|
|
58
|
+
console.log("");
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export async function install(options, interactive = true) {
|
|
66
|
+
// ── 1. Check dependencies ─────────────────────────────────────
|
|
67
|
+
printSectionHeader("Checking dependencies...");
|
|
68
|
+
const openCodeStatus = checkOpenCode();
|
|
69
|
+
if (!openCodeStatus.installed) {
|
|
70
|
+
printProgress("OpenCode", "warn", "not installed");
|
|
71
|
+
const installed = await promptInstallDependency("OpenCode", openCodeStatus.installCommands, interactive);
|
|
72
|
+
if (installed) {
|
|
73
|
+
printProgress("OpenCode", "ok", "installed");
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
printWarning("OpenCode is required for the plugin to work.");
|
|
77
|
+
printInfo("You can still use the standalone CLI (byoao vault init, byoao vault status).");
|
|
78
|
+
printInfo("To install OpenCode later, run one of:");
|
|
79
|
+
for (const cmd of openCodeStatus.installCommands) {
|
|
80
|
+
printInfo(` ${cmd.label}: ${cmd.command}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
const version = openCodeStatus.version
|
|
86
|
+
? `v${openCodeStatus.version}`
|
|
87
|
+
: "installed";
|
|
88
|
+
printProgressWithBar(`OpenCode ${version}`, "ok", 100);
|
|
89
|
+
}
|
|
90
|
+
const obsidianStatus = checkObsidian();
|
|
91
|
+
if (!obsidianStatus.installed) {
|
|
92
|
+
printProgress("Obsidian", "warn", "not installed");
|
|
93
|
+
const installed = await promptInstallDependency("Obsidian", [{ label: "Download", command: `open ${obsidianStatus.downloadUrl}` }], interactive);
|
|
94
|
+
if (installed) {
|
|
95
|
+
printProgress("Obsidian", "ok", "download page opened — install it, then re-run `byoao install`");
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
printWarning(`Obsidian is required for vault operations. Install from: ${obsidianStatus.downloadUrl}`);
|
|
99
|
+
}
|
|
100
|
+
printBlank();
|
|
101
|
+
printInfo("Re-run `byoao install` after installing Obsidian.");
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const obsidianDetail = obsidianStatus.running ? "running" : "installed, not running";
|
|
105
|
+
printProgress(`Obsidian`, "ok", obsidianDetail);
|
|
106
|
+
printBlank();
|
|
107
|
+
// ── 2. Install components ─────────────────────────────────────
|
|
108
|
+
printSectionHeader("Installing components...");
|
|
109
|
+
let totalSteps = 2; // plugin + byoao skills
|
|
110
|
+
if (options.installSkills)
|
|
111
|
+
totalSteps++;
|
|
112
|
+
let completedSteps = 0;
|
|
113
|
+
// ── 2a. Register plugin in opencode.json ──────────────────────
|
|
114
|
+
if (openCodeStatus.installed) {
|
|
115
|
+
let configPath;
|
|
116
|
+
if (options.global) {
|
|
117
|
+
configPath =
|
|
118
|
+
findOpencodeConfig() ||
|
|
119
|
+
path.join(os.homedir(), ".config/opencode/opencode.json");
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
const dir = options.projectDir || process.cwd();
|
|
123
|
+
configPath = path.join(dir, ".opencode.json");
|
|
124
|
+
}
|
|
125
|
+
await fs.ensureDir(path.dirname(configPath));
|
|
126
|
+
let config = {};
|
|
127
|
+
if (await fs.pathExists(configPath)) {
|
|
128
|
+
try {
|
|
129
|
+
config = await fs.readJson(configPath);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// Invalid JSON — start fresh
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const plugins = config.plugin || [];
|
|
136
|
+
if (!plugins.includes("byoao")) {
|
|
137
|
+
plugins.push("byoao");
|
|
138
|
+
config.plugin = plugins;
|
|
139
|
+
await fs.writeJson(configPath, config, { spaces: 2 });
|
|
140
|
+
}
|
|
141
|
+
completedSteps++;
|
|
142
|
+
const pct = Math.round((completedSteps / totalSteps) * 100);
|
|
143
|
+
printProgressWithBar("Plugin registered", "ok", pct);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
completedSteps++;
|
|
147
|
+
printProgress("Plugin registration", "skip", "OpenCode not installed");
|
|
148
|
+
}
|
|
149
|
+
// ── 2b. Install Obsidian Skills ───────────────────────────────
|
|
150
|
+
if (options.installSkills) {
|
|
151
|
+
const skillsDir = options.global
|
|
152
|
+
? path.join(os.homedir(), ".config/opencode/skills")
|
|
153
|
+
: path.join(options.projectDir || process.cwd(), ".opencode/skills");
|
|
154
|
+
await fs.ensureDir(skillsDir);
|
|
155
|
+
const assetsDir = resolveAssetsDir();
|
|
156
|
+
const obsidianSkillsSrc = path.join(assetsDir, "obsidian-skills");
|
|
157
|
+
if (await fs.pathExists(obsidianSkillsSrc)) {
|
|
158
|
+
const skillFiles = await fs.readdir(obsidianSkillsSrc);
|
|
159
|
+
let installedCount = 0;
|
|
160
|
+
for (const file of skillFiles) {
|
|
161
|
+
if (file.endsWith(".md")) {
|
|
162
|
+
await fs.copy(path.join(obsidianSkillsSrc, file), path.join(skillsDir, file), { overwrite: false });
|
|
163
|
+
installedCount++;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
completedSteps++;
|
|
167
|
+
const pct = Math.round((completedSteps / totalSteps) * 100);
|
|
168
|
+
printProgressWithBar("Obsidian Skills", "ok", pct, `${installedCount} files`);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
completedSteps++;
|
|
172
|
+
printProgress("Obsidian Skills", "warn", "not found in assets");
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// ── 2c. Install BYOAO skills ─────────────────────────────────
|
|
176
|
+
const skillsDestDir = options.global
|
|
177
|
+
? path.join(os.homedir(), ".config/opencode/commands")
|
|
178
|
+
: path.join(options.projectDir || process.cwd(), ".opencode/commands");
|
|
179
|
+
await fs.ensureDir(skillsDestDir);
|
|
180
|
+
const byoaoSkillsSrc = path.join(resolveAssetsDir(), "..", "skills");
|
|
181
|
+
if (await fs.pathExists(byoaoSkillsSrc)) {
|
|
182
|
+
const skillFiles = await fs.readdir(byoaoSkillsSrc);
|
|
183
|
+
let installedCount = 0;
|
|
184
|
+
for (const file of skillFiles) {
|
|
185
|
+
if (file.endsWith(".md")) {
|
|
186
|
+
await fs.copy(path.join(byoaoSkillsSrc, file), path.join(skillsDestDir, file), { overwrite: false });
|
|
187
|
+
installedCount++;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
completedSteps++;
|
|
191
|
+
printProgressWithBar("BYOAO skills", "ok", 100, `${installedCount} commands`);
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
completedSteps++;
|
|
195
|
+
printProgressWithBar("BYOAO skills", "ok", 100, "0 commands");
|
|
196
|
+
}
|
|
197
|
+
// ── Getting Started ───────────────────────────────────────────
|
|
198
|
+
const gettingStartedItems = [];
|
|
199
|
+
if (openCodeStatus.installed) {
|
|
200
|
+
gettingStartedItems.push({ cmd: "opencode", desc: "# Launch OpenCode" }, { cmd: "/init-knowledge-base", desc: "# Create your first knowledge base" });
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
gettingStartedItems.push({
|
|
204
|
+
cmd: "npx opencode@latest",
|
|
205
|
+
desc: "# Install & launch OpenCode",
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
gettingStartedItems.push({ cmd: "byoao vault init", desc: "# Create a knowledge base" }, { cmd: "byoao vault status <path>", desc: "# Check vault health" });
|
|
209
|
+
printGettingStarted(gettingStartedItems);
|
|
210
|
+
printInfo("Recommended: Obsidian Web Clipper → https://obsidian.md/clipper");
|
|
211
|
+
printFooter("https://github.com/JayJiangCT/BYOAO");
|
|
212
|
+
if (!obsidianStatus.running) {
|
|
213
|
+
printWarning("Don't forget to open Obsidian before creating a vault.");
|
|
214
|
+
printBlank();
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function resolveAssetsDir() {
|
|
218
|
+
const srcAssets = path.resolve(import.meta.dirname, "..", "assets");
|
|
219
|
+
const distAssets = path.resolve(import.meta.dirname, "..", "..", "src", "assets");
|
|
220
|
+
if (fs.existsSync(srcAssets))
|
|
221
|
+
return srcAssets;
|
|
222
|
+
if (fs.existsSync(distAssets))
|
|
223
|
+
return distAssets;
|
|
224
|
+
return srcAssets;
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/cli/installer.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/ui.js
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
// B and Y use standard gradient; OΛO uses a warm accent to hint at the "face"
|
|
3
|
+
//
|
|
4
|
+
// B Y O Λ O
|
|
5
|
+
// 👁 👄 👁 ← the hidden face
|
|
6
|
+
//
|
|
7
|
+
// Λ = pointed top, no crossbar (unlike A). Two open legs = cat-mouth vibe.
|
|
8
|
+
// Column index where OΛO begins (after " " prefix + BY columns)
|
|
9
|
+
const FACE_START = 20;
|
|
10
|
+
// Full logo as single block for precise alignment.
|
|
11
|
+
// The A column is replaced with a symmetric Λ:
|
|
12
|
+
// pointed top (██╗), widening (████╗), open legs, no crossbar.
|
|
13
|
+
const LOGO_LINES = [
|
|
14
|
+
" ██████╗ ██╗ ██╗ ██████╗ ██╗ ██████╗ ",
|
|
15
|
+
" ██╔══██╗╚██╗ ██╔╝██╔═══██╗ ████╗ ██╔═══██╗",
|
|
16
|
+
" ██████╔╝ ╚████╔╝ ██║ ██║██╔══██╗██║ ██║",
|
|
17
|
+
" ██╔══██╗ ╚██╔╝ ██║ ██║██║ ██║██║ ██║",
|
|
18
|
+
" ██████╔╝ ██║ ╚██████╔╝██║ ██║╚██████╔╝",
|
|
19
|
+
" ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ",
|
|
20
|
+
];
|
|
21
|
+
const TAGLINE = "Build Your Own AI OS";
|
|
22
|
+
// BY gradient: purple → blue
|
|
23
|
+
const GRADIENT_BY = [
|
|
24
|
+
[138, 92, 246], // purple
|
|
25
|
+
[99, 144, 255], // blue
|
|
26
|
+
];
|
|
27
|
+
// OΛO gradient: cyan → mint → green (warmer, eye-catching)
|
|
28
|
+
const GRADIENT_FACE = [
|
|
29
|
+
[34, 211, 238], // cyan
|
|
30
|
+
[52, 211, 153], // mint
|
|
31
|
+
[16, 185, 129], // green
|
|
32
|
+
];
|
|
33
|
+
// Tagline: full spectrum
|
|
34
|
+
const GRADIENT_FULL = [
|
|
35
|
+
[138, 92, 246],
|
|
36
|
+
[99, 144, 255],
|
|
37
|
+
[34, 211, 238],
|
|
38
|
+
[52, 211, 153],
|
|
39
|
+
[16, 185, 129],
|
|
40
|
+
];
|
|
41
|
+
function lerpColor(c1, c2, t) {
|
|
42
|
+
return [
|
|
43
|
+
Math.round(c1[0] + (c2[0] - c1[0]) * t),
|
|
44
|
+
Math.round(c1[1] + (c2[1] - c1[1]) * t),
|
|
45
|
+
Math.round(c1[2] + (c2[2] - c1[2]) * t),
|
|
46
|
+
];
|
|
47
|
+
}
|
|
48
|
+
function colorize(text, gradient, row, totalRows) {
|
|
49
|
+
const chars = [...text];
|
|
50
|
+
return chars
|
|
51
|
+
.map((ch, i) => {
|
|
52
|
+
const colT = chars.length > 1 ? i / (chars.length - 1) : 0;
|
|
53
|
+
const rowT = totalRows > 1 ? row / (totalRows - 1) : 0;
|
|
54
|
+
const t = colT * 0.7 + rowT * 0.3;
|
|
55
|
+
const seg = t * (gradient.length - 1);
|
|
56
|
+
const idx = Math.min(Math.floor(seg), gradient.length - 2);
|
|
57
|
+
const [r, g, b] = lerpColor(gradient[idx], gradient[idx + 1], seg - idx);
|
|
58
|
+
return chalk.rgb(r, g, b)(ch);
|
|
59
|
+
})
|
|
60
|
+
.join("");
|
|
61
|
+
}
|
|
62
|
+
const BAR_WIDTH = 22;
|
|
63
|
+
export function printLogo() {
|
|
64
|
+
const totalRows = LOGO_LINES.length;
|
|
65
|
+
console.log();
|
|
66
|
+
for (let i = 0; i < totalRows; i++) {
|
|
67
|
+
const chars = [...LOGO_LINES[i]];
|
|
68
|
+
const byPart = chars.slice(0, FACE_START).join("");
|
|
69
|
+
const facePart = chars.slice(FACE_START).join("");
|
|
70
|
+
const by = colorize(byPart, GRADIENT_BY, i, totalRows);
|
|
71
|
+
const face = colorize(facePart, GRADIENT_FACE, i, totalRows);
|
|
72
|
+
console.log(by + face);
|
|
73
|
+
}
|
|
74
|
+
console.log();
|
|
75
|
+
const pad = " ".repeat(6);
|
|
76
|
+
console.log(pad + colorize(`~ ${TAGLINE} ~`, GRADIENT_FULL, 1, 3));
|
|
77
|
+
console.log();
|
|
78
|
+
}
|
|
79
|
+
export function printVersion(version) {
|
|
80
|
+
console.log(chalk.dim(` Installing byoao version: ${version}`));
|
|
81
|
+
console.log();
|
|
82
|
+
}
|
|
83
|
+
export function printSectionHeader(title) {
|
|
84
|
+
console.log(chalk.dim(` ${title}`));
|
|
85
|
+
}
|
|
86
|
+
export function printProgress(label, status, detail) {
|
|
87
|
+
const markers = {
|
|
88
|
+
ok: chalk.green("✓"),
|
|
89
|
+
warn: chalk.yellow("⚠"),
|
|
90
|
+
skip: chalk.dim("⏭"),
|
|
91
|
+
fail: chalk.red("✗"),
|
|
92
|
+
};
|
|
93
|
+
const marker = markers[status];
|
|
94
|
+
const text = detail ? `${label} ${chalk.dim(`(${detail})`)}` : label;
|
|
95
|
+
console.log(` ${marker} ${text}`);
|
|
96
|
+
}
|
|
97
|
+
export function printProgressBar(percent) {
|
|
98
|
+
const filled = Math.round((percent / 100) * BAR_WIDTH);
|
|
99
|
+
const empty = BAR_WIDTH - filled;
|
|
100
|
+
const bar = "█".repeat(filled) + "░".repeat(empty);
|
|
101
|
+
const pct = `${Math.round(percent)}%`;
|
|
102
|
+
console.log(chalk.dim(` ${bar} ${pct}`));
|
|
103
|
+
}
|
|
104
|
+
export function printProgressWithBar(label, status, percent, detail) {
|
|
105
|
+
const markers = {
|
|
106
|
+
ok: chalk.green("✓"),
|
|
107
|
+
warn: chalk.yellow("⚠"),
|
|
108
|
+
skip: chalk.dim("⏭"),
|
|
109
|
+
fail: chalk.red("✗"),
|
|
110
|
+
};
|
|
111
|
+
const marker = markers[status];
|
|
112
|
+
const text = detail ? `${label} ${chalk.dim(`(${detail})`)}` : label;
|
|
113
|
+
const filled = Math.round((percent / 100) * BAR_WIDTH);
|
|
114
|
+
const empty = BAR_WIDTH - filled;
|
|
115
|
+
const bar = "█".repeat(filled) + "░".repeat(empty);
|
|
116
|
+
const pct = `${Math.round(percent)}%`;
|
|
117
|
+
// Pad label to align bars
|
|
118
|
+
const padded = text.padEnd(36);
|
|
119
|
+
console.log(` ${marker} ${padded} ${chalk.dim(`${bar} ${pct}`)}`);
|
|
120
|
+
}
|
|
121
|
+
export function printGettingStarted(items) {
|
|
122
|
+
console.log();
|
|
123
|
+
console.log(chalk.bold(" Build Your Own AI OS — Obsidian + AI Agent"));
|
|
124
|
+
console.log();
|
|
125
|
+
for (const item of items) {
|
|
126
|
+
const cmd = chalk.cyan(item.cmd.padEnd(28));
|
|
127
|
+
const desc = chalk.dim(item.desc);
|
|
128
|
+
console.log(` ${cmd}${desc}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export function printFooter(url) {
|
|
132
|
+
console.log();
|
|
133
|
+
console.log(chalk.dim(` For more info visit ${url}`));
|
|
134
|
+
console.log();
|
|
135
|
+
}
|
|
136
|
+
export function printBlank() {
|
|
137
|
+
console.log();
|
|
138
|
+
}
|
|
139
|
+
export function printWarning(message) {
|
|
140
|
+
console.log(` ${chalk.yellow("⚠")} ${chalk.yellow(message)}`);
|
|
141
|
+
}
|
|
142
|
+
export function printInfo(message) {
|
|
143
|
+
console.log(chalk.dim(` ${message}`));
|
|
144
|
+
}
|
|
145
|
+
/** Print an event-line marker: ● label */
|
|
146
|
+
export function printEvent(label) {
|
|
147
|
+
console.log(` ${chalk.cyan("●")} ${chalk.bold(label)}`);
|
|
148
|
+
}
|
|
149
|
+
/** Print event-line detail (indented under event) */
|
|
150
|
+
export function printEventDetail(text) {
|
|
151
|
+
console.log(` ${text}`);
|
|
152
|
+
}
|
|
153
|
+
/** Print a completed event: ◆ label */
|
|
154
|
+
export function printEventDone(label) {
|
|
155
|
+
console.log(` ${chalk.green("◆")} ${chalk.bold(label)}`);
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=ui.js.map
|