@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.
Files changed (76) hide show
  1. package/dist/cli/cli-program.js +241 -0
  2. package/dist/cli/cli-program.js.map +1 -0
  3. package/dist/cli/installer.js +226 -0
  4. package/dist/cli/installer.js.map +1 -0
  5. package/dist/cli/ui.js +157 -0
  6. package/dist/cli/ui.js.map +1 -0
  7. package/dist/hooks/idle-suggestions.js +14 -0
  8. package/dist/hooks/idle-suggestions.js.map +1 -0
  9. package/dist/hooks/system-transform.js +34 -0
  10. package/dist/hooks/system-transform.js.map +1 -0
  11. package/dist/index.js +43 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/plugin-config.js +57 -0
  14. package/dist/plugin-config.js.map +1 -0
  15. package/dist/tools/add-glossary-term.js +19 -0
  16. package/dist/tools/add-glossary-term.js.map +1 -0
  17. package/dist/tools/add-member.js +21 -0
  18. package/dist/tools/add-member.js.map +1 -0
  19. package/dist/tools/add-project.js +24 -0
  20. package/dist/tools/add-project.js.map +1 -0
  21. package/dist/tools/init-vault.js +82 -0
  22. package/dist/tools/init-vault.js.map +1 -0
  23. package/dist/tools/vault-doctor.js +38 -0
  24. package/dist/tools/vault-doctor.js.map +1 -0
  25. package/dist/tools/vault-status.js +18 -0
  26. package/dist/tools/vault-status.js.map +1 -0
  27. package/dist/vault/create.js +230 -0
  28. package/dist/vault/create.js.map +1 -0
  29. package/dist/vault/doctor.js +148 -0
  30. package/dist/vault/doctor.js.map +1 -0
  31. package/dist/vault/glossary.js +33 -0
  32. package/dist/vault/glossary.js.map +1 -0
  33. package/dist/vault/member.js +67 -0
  34. package/dist/vault/member.js.map +1 -0
  35. package/dist/vault/obsidian-check.js +125 -0
  36. package/dist/vault/obsidian-check.js.map +1 -0
  37. package/dist/vault/obsidian-cli.js +47 -0
  38. package/dist/vault/obsidian-cli.js.map +1 -0
  39. package/dist/vault/opencode-check.js +65 -0
  40. package/dist/vault/opencode-check.js.map +1 -0
  41. package/dist/vault/preset.js +48 -0
  42. package/dist/vault/preset.js.map +1 -0
  43. package/dist/vault/project.js +68 -0
  44. package/dist/vault/project.js.map +1 -0
  45. package/dist/vault/status.js +135 -0
  46. package/dist/vault/status.js.map +1 -0
  47. package/dist/vault/template.js +14 -0
  48. package/dist/vault/template.js.map +1 -0
  49. package/package.json +58 -0
  50. package/src/assets/obsidian-skills/defuddle.md +41 -0
  51. package/src/assets/obsidian-skills/json-canvas.md +244 -0
  52. package/src/assets/obsidian-skills/obsidian-bases.md +497 -0
  53. package/src/assets/obsidian-skills/obsidian-cli.md +106 -0
  54. package/src/assets/obsidian-skills/obsidian-markdown.md +196 -0
  55. package/src/assets/presets/common/AGENT.md.hbs +29 -0
  56. package/src/assets/presets/common/Glossary.md.hbs +44 -0
  57. package/src/assets/presets/common/Start Here.md.hbs +95 -0
  58. package/src/assets/presets/common/obsidian/core-plugins.json +33 -0
  59. package/src/assets/presets/common/obsidian/daily-notes.json +5 -0
  60. package/src/assets/presets/common/obsidian/templates.json +3 -0
  61. package/src/assets/presets/common/templates/Daily Note.md +19 -0
  62. package/src/assets/presets/common/templates/Decision Record.md +32 -0
  63. package/src/assets/presets/common/templates/Investigation.md +34 -0
  64. package/src/assets/presets/common/templates/Meeting Notes.md +25 -0
  65. package/src/assets/presets/pm-tpm/agent-section.hbs +15 -0
  66. package/src/assets/presets/pm-tpm/preset.json +12 -0
  67. package/src/assets/presets/pm-tpm/templates/Feature Doc.md +45 -0
  68. package/src/assets/presets/pm-tpm/templates/Sprint Handoff.md +38 -0
  69. package/src/assets/web-clipper/confluence-page.json +63 -0
  70. package/src/assets/web-clipper/general-article.json +53 -0
  71. package/src/assets/web-clipper/jira-issue.json +68 -0
  72. package/src/assets/web-clipper/meeting-notes.json +53 -0
  73. package/src/skills/enrich-document.md +52 -0
  74. package/src/skills/init-knowledge-base.md +85 -0
  75. package/src/skills/system-explainer.md +58 -0
  76. 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