@datacore-one/cli 1.0.3 → 1.0.5
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/index.js +679 -365
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7015,12 +7015,12 @@ async function invokeAgent(invocation, options = {}) {
|
|
|
7015
7015
|
error: `Working directory not found: ${cwd}`
|
|
7016
7016
|
};
|
|
7017
7017
|
}
|
|
7018
|
-
const
|
|
7018
|
+
const prompt2 = buildAgentPrompt(invocation);
|
|
7019
7019
|
return new Promise((resolve) => {
|
|
7020
7020
|
const chunks = [];
|
|
7021
7021
|
let errorChunks = [];
|
|
7022
7022
|
let timedOut = false;
|
|
7023
|
-
const proc = spawn2("claude", ["--print",
|
|
7023
|
+
const proc = spawn2("claude", ["--print", prompt2], {
|
|
7024
7024
|
cwd,
|
|
7025
7025
|
stdio: ["ignore", "pipe", "pipe"],
|
|
7026
7026
|
env: {
|
|
@@ -7107,9 +7107,9 @@ function listAgents() {
|
|
|
7107
7107
|
return [];
|
|
7108
7108
|
}
|
|
7109
7109
|
try {
|
|
7110
|
-
const { readFileSync:
|
|
7110
|
+
const { readFileSync: readFileSync5 } = __require("fs");
|
|
7111
7111
|
const { parse: parse3 } = require_dist();
|
|
7112
|
-
const content =
|
|
7112
|
+
const content = readFileSync5(registryPath, "utf-8");
|
|
7113
7113
|
const registry = parse3(content);
|
|
7114
7114
|
return registry.agents?.map((a) => a.name) || [];
|
|
7115
7115
|
} catch {
|
|
@@ -7991,21 +7991,63 @@ function getVersion(cmd, versionFlag = "--version") {
|
|
|
7991
7991
|
return;
|
|
7992
7992
|
}
|
|
7993
7993
|
}
|
|
7994
|
-
function
|
|
7994
|
+
function getGitConfig(key) {
|
|
7995
|
+
try {
|
|
7996
|
+
return execSync2(`git config --global ${key}`, { encoding: "utf-8", stdio: "pipe" }).trim();
|
|
7997
|
+
} catch {
|
|
7998
|
+
return;
|
|
7999
|
+
}
|
|
8000
|
+
}
|
|
8001
|
+
function checkGitHubAuth() {
|
|
8002
|
+
try {
|
|
8003
|
+
const output2 = execSync2("gh auth status 2>&1", { encoding: "utf-8", stdio: "pipe" });
|
|
8004
|
+
const userMatch = output2.match(/Logged in to github\.com.*account (\S+)/i);
|
|
8005
|
+
return { authenticated: true, user: userMatch?.[1] };
|
|
8006
|
+
} catch {
|
|
8007
|
+
return { authenticated: false };
|
|
8008
|
+
}
|
|
8009
|
+
}
|
|
8010
|
+
function checkGitDetailed() {
|
|
7995
8011
|
const installed = commandExists("git");
|
|
8012
|
+
if (!installed) {
|
|
8013
|
+
return { installed: false, configured: false, githubAuth: false };
|
|
8014
|
+
}
|
|
8015
|
+
const userName = getGitConfig("user.name");
|
|
8016
|
+
const userEmail = getGitConfig("user.email");
|
|
8017
|
+
const configured = !!(userName && userEmail);
|
|
8018
|
+
const ghInstalled = commandExists("gh");
|
|
8019
|
+
let githubAuth = false;
|
|
8020
|
+
let githubUser;
|
|
8021
|
+
if (ghInstalled) {
|
|
8022
|
+
const ghStatus = checkGitHubAuth();
|
|
8023
|
+
githubAuth = ghStatus.authenticated;
|
|
8024
|
+
githubUser = ghStatus.user;
|
|
8025
|
+
}
|
|
8026
|
+
return {
|
|
8027
|
+
installed: true,
|
|
8028
|
+
version: getVersion("git"),
|
|
8029
|
+
configured,
|
|
8030
|
+
userName,
|
|
8031
|
+
userEmail,
|
|
8032
|
+
githubAuth,
|
|
8033
|
+
githubUser
|
|
8034
|
+
};
|
|
8035
|
+
}
|
|
8036
|
+
function checkGit(platform2) {
|
|
8037
|
+
const status = checkGitDetailed();
|
|
7996
8038
|
return {
|
|
7997
8039
|
name: "git",
|
|
7998
8040
|
required: true,
|
|
7999
|
-
installed,
|
|
8000
|
-
version:
|
|
8001
|
-
installCommand: installed ? undefined : getInstallCommand("git", platform2) ?? undefined
|
|
8041
|
+
installed: status.installed,
|
|
8042
|
+
version: status.version,
|
|
8043
|
+
installCommand: status.installed ? undefined : getInstallCommand("git", platform2) ?? undefined
|
|
8002
8044
|
};
|
|
8003
8045
|
}
|
|
8004
8046
|
function checkGitLfs(platform2) {
|
|
8005
8047
|
const installed = commandExists("git-lfs");
|
|
8006
8048
|
return {
|
|
8007
8049
|
name: "git-lfs",
|
|
8008
|
-
required:
|
|
8050
|
+
required: false,
|
|
8009
8051
|
installed,
|
|
8010
8052
|
version: installed ? getVersion("git-lfs") : undefined,
|
|
8011
8053
|
installCommand: installed ? undefined : getInstallCommand("git-lfs", platform2) ?? undefined
|
|
@@ -8320,7 +8362,21 @@ function createSpace(name, type = "team") {
|
|
|
8320
8362
|
throw new Error(`Space already exists: ${folderName}`);
|
|
8321
8363
|
}
|
|
8322
8364
|
mkdirSync2(spacePath, { recursive: true });
|
|
8323
|
-
const dirs = [
|
|
8365
|
+
const dirs = type === "personal" ? [
|
|
8366
|
+
".datacore",
|
|
8367
|
+
".datacore/commands",
|
|
8368
|
+
".datacore/agents",
|
|
8369
|
+
".datacore/learning",
|
|
8370
|
+
".datacore/state",
|
|
8371
|
+
".datacore/env",
|
|
8372
|
+
"org",
|
|
8373
|
+
"0-inbox",
|
|
8374
|
+
"notes",
|
|
8375
|
+
"notes/journals",
|
|
8376
|
+
"notes/pages",
|
|
8377
|
+
"notes/zettel",
|
|
8378
|
+
"journal"
|
|
8379
|
+
] : [
|
|
8324
8380
|
".datacore",
|
|
8325
8381
|
".datacore/commands",
|
|
8326
8382
|
".datacore/agents",
|
|
@@ -8331,6 +8387,11 @@ function createSpace(name, type = "team") {
|
|
|
8331
8387
|
"0-inbox",
|
|
8332
8388
|
"journal",
|
|
8333
8389
|
"1-tracks",
|
|
8390
|
+
"1-tracks/ops",
|
|
8391
|
+
"1-tracks/product",
|
|
8392
|
+
"1-tracks/dev",
|
|
8393
|
+
"1-tracks/research",
|
|
8394
|
+
"1-tracks/comms",
|
|
8334
8395
|
"2-projects",
|
|
8335
8396
|
"3-knowledge",
|
|
8336
8397
|
"3-knowledge/pages",
|
|
@@ -8342,20 +8403,87 @@ function createSpace(name, type = "team") {
|
|
|
8342
8403
|
for (const dir of dirs) {
|
|
8343
8404
|
mkdirSync2(join3(spacePath, dir), { recursive: true });
|
|
8344
8405
|
}
|
|
8345
|
-
|
|
8406
|
+
if (type === "personal") {
|
|
8407
|
+
writeFileSync2(join3(spacePath, "org", "inbox.org"), `#+TITLE: Inbox
|
|
8408
|
+
#+FILETAGS: :inbox:
|
|
8409
|
+
|
|
8410
|
+
Capture everything here. Process daily to zero.
|
|
8411
|
+
|
|
8412
|
+
* Inbox
|
|
8413
|
+
`);
|
|
8414
|
+
writeFileSync2(join3(spacePath, "org", "next_actions.org"), `#+TITLE: Next Actions
|
|
8415
|
+
#+FILETAGS: :tasks:
|
|
8416
|
+
|
|
8417
|
+
Tasks organized by context. Tag with :AI: to delegate to agents.
|
|
8418
|
+
|
|
8419
|
+
* @computer
|
|
8420
|
+
* @phone
|
|
8421
|
+
* @errands
|
|
8422
|
+
* @home
|
|
8423
|
+
* @office
|
|
8424
|
+
* @waiting
|
|
8425
|
+
`);
|
|
8426
|
+
writeFileSync2(join3(spacePath, "org", "projects.org"), `#+TITLE: Projects
|
|
8427
|
+
#+FILETAGS: :projects:
|
|
8428
|
+
|
|
8429
|
+
Active projects (outcomes requiring multiple actions).
|
|
8430
|
+
|
|
8431
|
+
* Projects
|
|
8432
|
+
`);
|
|
8433
|
+
writeFileSync2(join3(spacePath, "org", "someday.org"), `#+TITLE: Someday/Maybe
|
|
8434
|
+
#+FILETAGS: :someday:
|
|
8435
|
+
|
|
8436
|
+
Ideas and projects for the future. Review monthly.
|
|
8437
|
+
|
|
8438
|
+
* Someday
|
|
8439
|
+
`);
|
|
8440
|
+
} else {
|
|
8441
|
+
writeFileSync2(join3(spacePath, "org", "inbox.org"), `#+TITLE: Inbox
|
|
8346
8442
|
#+FILETAGS: :inbox:
|
|
8347
8443
|
|
|
8348
8444
|
* Capture items here
|
|
8349
8445
|
`);
|
|
8350
|
-
|
|
8446
|
+
writeFileSync2(join3(spacePath, "org", "next_actions.org"), `#+TITLE: Next Actions
|
|
8351
8447
|
#+FILETAGS: :tasks:
|
|
8352
8448
|
|
|
8353
8449
|
* Tasks
|
|
8354
8450
|
** TODO items go here
|
|
8355
8451
|
`);
|
|
8356
|
-
|
|
8452
|
+
}
|
|
8453
|
+
if (type === "personal") {
|
|
8454
|
+
writeFileSync2(join3(spacePath, "_index.md"), `# Personal Space
|
|
8455
|
+
|
|
8456
|
+
Your personal knowledge base and GTD system.
|
|
8457
|
+
|
|
8458
|
+
## GTD Workflow
|
|
8459
|
+
|
|
8460
|
+
1. **Capture** → \`org/inbox.org\` - dump everything here
|
|
8461
|
+
2. **Clarify** → Is it actionable? What's the next action?
|
|
8462
|
+
3. **Organize** → Move to \`next_actions.org\` by context
|
|
8463
|
+
4. **Reflect** → Weekly review, monthly strategic
|
|
8464
|
+
5. **Engage** → Do the work, delegate with :AI: tags
|
|
8465
|
+
|
|
8466
|
+
## Quick Links
|
|
8467
|
+
|
|
8468
|
+
- [Inbox](org/inbox.org) - Capture here
|
|
8469
|
+
- [Next Actions](org/next_actions.org) - Today's work
|
|
8470
|
+
- [Projects](org/projects.org) - Active projects
|
|
8471
|
+
- [Someday](org/someday.org) - Future ideas
|
|
8472
|
+
- [Notes](notes/) - Knowledge base
|
|
8473
|
+
- [Journal](journal/) - Daily entries
|
|
8474
|
+
`);
|
|
8475
|
+
} else {
|
|
8476
|
+
writeFileSync2(join3(spacePath, "_index.md"), `# ${name}
|
|
8477
|
+
|
|
8478
|
+
Team space.
|
|
8479
|
+
|
|
8480
|
+
## Structure
|
|
8357
8481
|
|
|
8358
|
-
|
|
8482
|
+
- \`org/\` - Task coordination
|
|
8483
|
+
- \`1-tracks/\` - Department work
|
|
8484
|
+
- \`2-projects/\` - Code repositories
|
|
8485
|
+
- \`3-knowledge/\` - Shared knowledge
|
|
8486
|
+
- \`4-archive/\` - Historical content
|
|
8359
8487
|
|
|
8360
8488
|
## Quick Links
|
|
8361
8489
|
|
|
@@ -8364,14 +8492,46 @@ ${type === "personal" ? "Personal" : "Team"} space.
|
|
|
8364
8492
|
- [Journal](journal/)
|
|
8365
8493
|
- [Knowledge](3-knowledge/)
|
|
8366
8494
|
`);
|
|
8367
|
-
|
|
8495
|
+
}
|
|
8496
|
+
if (type === "personal") {
|
|
8497
|
+
writeFileSync2(join3(spacePath, "CLAUDE.base.md"), `# Personal Space
|
|
8498
|
+
|
|
8499
|
+
Personal GTD system and knowledge base.
|
|
8500
|
+
|
|
8501
|
+
## GTD Workflow
|
|
8368
8502
|
|
|
8369
|
-
|
|
8503
|
+
- \`org/inbox.org\` - Single capture point, process to zero daily
|
|
8504
|
+
- \`org/next_actions.org\` - Tasks by context (@computer, @phone, etc.)
|
|
8505
|
+
- \`org/projects.org\` - Active multi-step outcomes
|
|
8506
|
+
- \`org/someday.org\` - Future ideas, review monthly
|
|
8507
|
+
|
|
8508
|
+
## AI Delegation
|
|
8509
|
+
|
|
8510
|
+
Tag tasks with \`:AI:\` to delegate to agents:
|
|
8511
|
+
- \`:AI:research:\` - Research and summarize
|
|
8512
|
+
- \`:AI:content:\` - Draft content
|
|
8513
|
+
- \`:AI:data:\` - Analyze data
|
|
8514
|
+
|
|
8515
|
+
## Knowledge
|
|
8516
|
+
|
|
8517
|
+
- \`notes/\` - Personal knowledge base (Obsidian)
|
|
8518
|
+
- \`notes/journals/\` - Daily reflections
|
|
8519
|
+
- \`notes/zettel/\` - Atomic concept notes
|
|
8520
|
+
|
|
8521
|
+
## See Also
|
|
8522
|
+
|
|
8523
|
+
Parent: ~/Data/CLAUDE.md
|
|
8524
|
+
`);
|
|
8525
|
+
} else {
|
|
8526
|
+
writeFileSync2(join3(spacePath, "CLAUDE.base.md"), `# ${name} Space
|
|
8527
|
+
|
|
8528
|
+
Team space for ${name}.
|
|
8370
8529
|
|
|
8371
8530
|
## Structure
|
|
8372
8531
|
|
|
8373
8532
|
See parent CLAUDE.md for full documentation.
|
|
8374
8533
|
`);
|
|
8534
|
+
}
|
|
8375
8535
|
writeFileSync2(join3(spacePath, ".datacore", "config.yaml"), `# Space configuration
|
|
8376
8536
|
name: ${normalizedName}
|
|
8377
8537
|
type: ${type}
|
|
@@ -8388,7 +8548,11 @@ Human feedback log.
|
|
|
8388
8548
|
|
|
8389
8549
|
Style and preference notes.
|
|
8390
8550
|
`);
|
|
8391
|
-
writeFileSync2(join3(spacePath, ".gitignore"), `.datacore/state/
|
|
8551
|
+
writeFileSync2(join3(spacePath, ".gitignore"), type === "personal" ? `.datacore/state/
|
|
8552
|
+
.datacore/env/
|
|
8553
|
+
CLAUDE.md
|
|
8554
|
+
CLAUDE.local.md
|
|
8555
|
+
` : `.datacore/state/
|
|
8392
8556
|
.datacore/env/
|
|
8393
8557
|
CLAUDE.md
|
|
8394
8558
|
CLAUDE.local.md
|
|
@@ -8539,26 +8703,193 @@ function getGitRepos() {
|
|
|
8539
8703
|
}
|
|
8540
8704
|
|
|
8541
8705
|
// src/lib/init.ts
|
|
8542
|
-
import { existsSync as
|
|
8543
|
-
import { join as
|
|
8706
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4, symlinkSync } from "fs";
|
|
8707
|
+
import { join as join7 } from "path";
|
|
8708
|
+
import { createInterface } from "readline";
|
|
8709
|
+
|
|
8710
|
+
// src/lib/module.ts
|
|
8711
|
+
import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync2, rmSync } from "fs";
|
|
8712
|
+
import { join as join5, basename as basename3 } from "path";
|
|
8713
|
+
import { execSync as execSync4 } from "child_process";
|
|
8714
|
+
var DATA_DIR4 = join5(process.env.HOME || "~", "Data");
|
|
8715
|
+
var MODULES_DIR = join5(DATA_DIR4, ".datacore", "modules");
|
|
8716
|
+
var AVAILABLE_MODULES = [
|
|
8717
|
+
{
|
|
8718
|
+
name: "nightshift",
|
|
8719
|
+
description: "Overnight AI task execution",
|
|
8720
|
+
repo: "https://github.com/datacore-one/module-nightshift",
|
|
8721
|
+
features: ["Queues :AI: tasks for overnight processing", "Morning briefing with results", "Remote server support"]
|
|
8722
|
+
},
|
|
8723
|
+
{
|
|
8724
|
+
name: "crm",
|
|
8725
|
+
description: "Contact relationship management",
|
|
8726
|
+
repo: "https://github.com/datacore-one/module-crm",
|
|
8727
|
+
features: ["Contact profiles", "Interaction history", "Relationship tracking"]
|
|
8728
|
+
},
|
|
8729
|
+
{
|
|
8730
|
+
name: "meetings",
|
|
8731
|
+
description: "Meeting preparation and follow-up",
|
|
8732
|
+
repo: "https://github.com/datacore-one/module-meetings",
|
|
8733
|
+
features: ["Pre-meeting briefs", "Transcript processing", "Action item extraction"]
|
|
8734
|
+
},
|
|
8735
|
+
{
|
|
8736
|
+
name: "health",
|
|
8737
|
+
description: "Personal health and wellness tracking",
|
|
8738
|
+
repo: "https://github.com/datacore-one/module-health",
|
|
8739
|
+
features: ["Health metrics", "Habit tracking", "Wellness insights"]
|
|
8740
|
+
}
|
|
8741
|
+
];
|
|
8742
|
+
function getAvailableModules() {
|
|
8743
|
+
const installed = listModules().map((m) => m.name);
|
|
8744
|
+
return AVAILABLE_MODULES.filter((m) => !installed.includes(m.name));
|
|
8745
|
+
}
|
|
8746
|
+
function listModules() {
|
|
8747
|
+
if (!existsSync5(MODULES_DIR)) {
|
|
8748
|
+
return [];
|
|
8749
|
+
}
|
|
8750
|
+
const entries = readdirSync2(MODULES_DIR, { withFileTypes: true });
|
|
8751
|
+
const modules = [];
|
|
8752
|
+
for (const entry of entries) {
|
|
8753
|
+
if (!entry.isDirectory())
|
|
8754
|
+
continue;
|
|
8755
|
+
if (entry.name.startsWith("."))
|
|
8756
|
+
continue;
|
|
8757
|
+
const modulePath = join5(MODULES_DIR, entry.name);
|
|
8758
|
+
const info2 = getModuleInfo(modulePath);
|
|
8759
|
+
if (info2) {
|
|
8760
|
+
modules.push(info2);
|
|
8761
|
+
}
|
|
8762
|
+
}
|
|
8763
|
+
return modules;
|
|
8764
|
+
}
|
|
8765
|
+
function getModuleInfo(modulePath) {
|
|
8766
|
+
const name = basename3(modulePath);
|
|
8767
|
+
const yamlPath = join5(modulePath, "module.yaml");
|
|
8768
|
+
const ymlPath = join5(modulePath, "module.yml");
|
|
8769
|
+
const configPath = existsSync5(yamlPath) ? yamlPath : existsSync5(ymlPath) ? ymlPath : null;
|
|
8770
|
+
let version;
|
|
8771
|
+
let description;
|
|
8772
|
+
if (configPath) {
|
|
8773
|
+
try {
|
|
8774
|
+
const { parse: parse2 } = require_dist();
|
|
8775
|
+
const content = readFileSync2(configPath, "utf-8");
|
|
8776
|
+
const config = parse2(content);
|
|
8777
|
+
version = config.version;
|
|
8778
|
+
description = config.description;
|
|
8779
|
+
} catch {}
|
|
8780
|
+
}
|
|
8781
|
+
const agentsDir = join5(modulePath, "agents");
|
|
8782
|
+
const agents = [];
|
|
8783
|
+
if (existsSync5(agentsDir)) {
|
|
8784
|
+
const agentFiles = readdirSync2(agentsDir);
|
|
8785
|
+
for (const file of agentFiles) {
|
|
8786
|
+
if (file.endsWith(".md")) {
|
|
8787
|
+
agents.push(file.replace(".md", ""));
|
|
8788
|
+
}
|
|
8789
|
+
}
|
|
8790
|
+
}
|
|
8791
|
+
const commandsDir = join5(modulePath, "commands");
|
|
8792
|
+
const commands = [];
|
|
8793
|
+
if (existsSync5(commandsDir)) {
|
|
8794
|
+
const cmdFiles = readdirSync2(commandsDir);
|
|
8795
|
+
for (const file of cmdFiles) {
|
|
8796
|
+
if (file.endsWith(".md")) {
|
|
8797
|
+
commands.push(file.replace(".md", ""));
|
|
8798
|
+
}
|
|
8799
|
+
}
|
|
8800
|
+
}
|
|
8801
|
+
return {
|
|
8802
|
+
name,
|
|
8803
|
+
path: modulePath,
|
|
8804
|
+
version,
|
|
8805
|
+
description,
|
|
8806
|
+
agents,
|
|
8807
|
+
commands
|
|
8808
|
+
};
|
|
8809
|
+
}
|
|
8810
|
+
function installModule(source) {
|
|
8811
|
+
if (!existsSync5(MODULES_DIR)) {
|
|
8812
|
+
const { mkdirSync: mkdirSync3 } = __require("fs");
|
|
8813
|
+
mkdirSync3(MODULES_DIR, { recursive: true });
|
|
8814
|
+
}
|
|
8815
|
+
let name;
|
|
8816
|
+
let isGit = false;
|
|
8817
|
+
if (source.includes("github.com") || source.startsWith("git@") || source.endsWith(".git")) {
|
|
8818
|
+
isGit = true;
|
|
8819
|
+
const match = source.match(/([^/]+?)(?:\.git)?$/);
|
|
8820
|
+
name = match?.[1] ?? source.split("/").pop() ?? "unknown";
|
|
8821
|
+
name = name.replace(/^module-/, "");
|
|
8822
|
+
} else if (source.startsWith("@")) {
|
|
8823
|
+
name = source.split("/").pop()?.replace(/^datacore-/, "") ?? "unknown";
|
|
8824
|
+
} else {
|
|
8825
|
+
name = source.replace(/^datacore-/, "").replace(/^module-/, "");
|
|
8826
|
+
}
|
|
8827
|
+
const modulePath = join5(MODULES_DIR, name);
|
|
8828
|
+
if (existsSync5(modulePath)) {
|
|
8829
|
+
throw new Error(`Module already installed: ${name}`);
|
|
8830
|
+
}
|
|
8831
|
+
if (isGit) {
|
|
8832
|
+
execSync4(`git clone ${source} "${modulePath}"`, { stdio: "pipe" });
|
|
8833
|
+
} else {
|
|
8834
|
+
const gitUrl = `https://github.com/datacore/module-${name}.git`;
|
|
8835
|
+
try {
|
|
8836
|
+
execSync4(`git clone ${gitUrl} "${modulePath}"`, { stdio: "pipe" });
|
|
8837
|
+
} catch {
|
|
8838
|
+
throw new Error(`Could not install module: ${source}`);
|
|
8839
|
+
}
|
|
8840
|
+
}
|
|
8841
|
+
const info2 = getModuleInfo(modulePath);
|
|
8842
|
+
if (!info2) {
|
|
8843
|
+
rmSync(modulePath, { recursive: true, force: true });
|
|
8844
|
+
throw new Error("Invalid module: missing module.yaml");
|
|
8845
|
+
}
|
|
8846
|
+
return info2;
|
|
8847
|
+
}
|
|
8848
|
+
function updateModules(name) {
|
|
8849
|
+
const modules = listModules();
|
|
8850
|
+
const results = [];
|
|
8851
|
+
const toUpdate = name ? modules.filter((m) => m.name === name) : modules;
|
|
8852
|
+
for (const mod of toUpdate) {
|
|
8853
|
+
try {
|
|
8854
|
+
const gitDir = join5(mod.path, ".git");
|
|
8855
|
+
if (existsSync5(gitDir)) {
|
|
8856
|
+
execSync4("git pull", { cwd: mod.path, stdio: "pipe" });
|
|
8857
|
+
results.push({ name: mod.name, updated: true });
|
|
8858
|
+
} else {
|
|
8859
|
+
results.push({ name: mod.name, updated: false, error: "Not a git repository" });
|
|
8860
|
+
}
|
|
8861
|
+
} catch (err) {
|
|
8862
|
+
results.push({ name: mod.name, updated: false, error: err.message });
|
|
8863
|
+
}
|
|
8864
|
+
}
|
|
8865
|
+
return results;
|
|
8866
|
+
}
|
|
8867
|
+
function removeModule(name) {
|
|
8868
|
+
const modulePath = join5(MODULES_DIR, name);
|
|
8869
|
+
if (!existsSync5(modulePath)) {
|
|
8870
|
+
return false;
|
|
8871
|
+
}
|
|
8872
|
+
rmSync(modulePath, { recursive: true, force: true });
|
|
8873
|
+
return true;
|
|
8874
|
+
}
|
|
8544
8875
|
|
|
8545
8876
|
// src/state.ts
|
|
8546
|
-
import { existsSync as
|
|
8547
|
-
import { join as
|
|
8548
|
-
var STATE_DIR =
|
|
8549
|
-
var STATE_FILE =
|
|
8877
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
8878
|
+
import { join as join6 } from "path";
|
|
8879
|
+
var STATE_DIR = join6(process.env.HOME || "~", "Data", ".datacore", "state");
|
|
8880
|
+
var STATE_FILE = join6(STATE_DIR, "operations.json");
|
|
8550
8881
|
function ensureStateDir() {
|
|
8551
|
-
if (!
|
|
8882
|
+
if (!existsSync6(STATE_DIR)) {
|
|
8552
8883
|
mkdirSync3(STATE_DIR, { recursive: true });
|
|
8553
8884
|
}
|
|
8554
8885
|
}
|
|
8555
8886
|
function loadState() {
|
|
8556
8887
|
ensureStateDir();
|
|
8557
|
-
if (!
|
|
8888
|
+
if (!existsSync6(STATE_FILE)) {
|
|
8558
8889
|
return { operations: [] };
|
|
8559
8890
|
}
|
|
8560
8891
|
try {
|
|
8561
|
-
const content =
|
|
8892
|
+
const content = readFileSync3(STATE_FILE, "utf-8");
|
|
8562
8893
|
return JSON.parse(content);
|
|
8563
8894
|
} catch {
|
|
8564
8895
|
return { operations: [] };
|
|
@@ -8652,7 +8983,6 @@ function startOperation(operation, params = {}) {
|
|
|
8652
8983
|
|
|
8653
8984
|
// src/lib/animation.ts
|
|
8654
8985
|
var SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
8655
|
-
var MATRIX_CHARS = "アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン0123456789";
|
|
8656
8986
|
var c = {
|
|
8657
8987
|
reset: "\x1B[0m",
|
|
8658
8988
|
bright: "\x1B[1m",
|
|
@@ -8691,13 +9021,6 @@ ${c.reset}
|
|
|
8691
9021
|
function sleep(ms) {
|
|
8692
9022
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
8693
9023
|
}
|
|
8694
|
-
async function typewrite(text, speed = 30) {
|
|
8695
|
-
for (const char of text) {
|
|
8696
|
-
process.stdout.write(char);
|
|
8697
|
-
await sleep(speed);
|
|
8698
|
-
}
|
|
8699
|
-
console.log();
|
|
8700
|
-
}
|
|
8701
9024
|
class Spinner {
|
|
8702
9025
|
interval = null;
|
|
8703
9026
|
frame = 0;
|
|
@@ -8733,82 +9056,60 @@ class Spinner {
|
|
|
8733
9056
|
process.stdout.write("\r" + " ".repeat(this.message.length + 10) + "\r");
|
|
8734
9057
|
}
|
|
8735
9058
|
}
|
|
8736
|
-
function step(num, total, message) {
|
|
8737
|
-
console.log(`${c.dim}[${num}/${total}]${c.reset} ${message}`);
|
|
8738
|
-
}
|
|
8739
9059
|
function section(title) {
|
|
8740
9060
|
console.log();
|
|
8741
9061
|
console.log(`${c.cyan}${c.bright}▸ ${title}${c.reset}`);
|
|
8742
9062
|
console.log(`${c.dim}${"─".repeat(50)}${c.reset}`);
|
|
8743
9063
|
}
|
|
8744
|
-
async function matrixRain(duration = 500) {
|
|
8745
|
-
const cols = process.stdout.columns || 80;
|
|
8746
|
-
const rows = 3;
|
|
8747
|
-
const drops = Array(cols).fill(0).map(() => Math.floor(Math.random() * rows));
|
|
8748
|
-
const startTime = Date.now();
|
|
8749
|
-
while (Date.now() - startTime < duration) {
|
|
8750
|
-
let frame = "";
|
|
8751
|
-
for (let y = 0;y < rows; y++) {
|
|
8752
|
-
for (let x = 0;x < cols; x++) {
|
|
8753
|
-
const drop = drops[x] ?? 0;
|
|
8754
|
-
if (drop === y) {
|
|
8755
|
-
frame += `${c.green}${c.bright}${MATRIX_CHARS[Math.floor(Math.random() * MATRIX_CHARS.length)]}${c.reset}`;
|
|
8756
|
-
} else if (drop === y - 1) {
|
|
8757
|
-
frame += `${c.green}${MATRIX_CHARS[Math.floor(Math.random() * MATRIX_CHARS.length)]}${c.reset}`;
|
|
8758
|
-
} else {
|
|
8759
|
-
frame += " ";
|
|
8760
|
-
}
|
|
8761
|
-
}
|
|
8762
|
-
frame += `
|
|
8763
|
-
`;
|
|
8764
|
-
}
|
|
8765
|
-
process.stdout.write(frame);
|
|
8766
|
-
for (let i = 0;i < drops.length; i++) {
|
|
8767
|
-
if (Math.random() > 0.9)
|
|
8768
|
-
drops[i] = 0;
|
|
8769
|
-
else
|
|
8770
|
-
drops[i] = (drops[i] ?? 0) + 1;
|
|
8771
|
-
}
|
|
8772
|
-
await sleep(50);
|
|
8773
|
-
process.stdout.write(`\x1B[${rows}A`);
|
|
8774
|
-
}
|
|
8775
|
-
for (let y = 0;y < rows; y++) {
|
|
8776
|
-
console.log(" ".repeat(cols));
|
|
8777
|
-
}
|
|
8778
|
-
process.stdout.write(`\x1B[${rows}A`);
|
|
8779
|
-
}
|
|
8780
|
-
async function bootSequence() {
|
|
8781
|
-
const lines = [
|
|
8782
|
-
"Initializing neural pathways...",
|
|
8783
|
-
"Loading cognitive frameworks...",
|
|
8784
|
-
"Establishing knowledge graph...",
|
|
8785
|
-
"Calibrating AI agents...",
|
|
8786
|
-
"Synchronizing memory banks..."
|
|
8787
|
-
];
|
|
8788
|
-
for (const line of lines) {
|
|
8789
|
-
process.stdout.write(`${c.dim}> ${line}${c.reset}`);
|
|
8790
|
-
await sleep(100 + Math.random() * 200);
|
|
8791
|
-
process.stdout.write(` ${c.green}OK${c.reset}
|
|
8792
|
-
`);
|
|
8793
|
-
await sleep(50);
|
|
8794
|
-
}
|
|
8795
|
-
}
|
|
8796
9064
|
|
|
8797
9065
|
// src/lib/init.ts
|
|
8798
|
-
var
|
|
8799
|
-
var DATACORE_DIR =
|
|
9066
|
+
var DATA_DIR5 = join7(process.env.HOME || "~", "Data");
|
|
9067
|
+
var DATACORE_DIR = join7(DATA_DIR5, ".datacore");
|
|
9068
|
+
var c2 = {
|
|
9069
|
+
reset: "\x1B[0m",
|
|
9070
|
+
bold: "\x1B[1m",
|
|
9071
|
+
dim: "\x1B[2m",
|
|
9072
|
+
green: "\x1B[32m",
|
|
9073
|
+
yellow: "\x1B[33m",
|
|
9074
|
+
red: "\x1B[31m",
|
|
9075
|
+
cyan: "\x1B[36m",
|
|
9076
|
+
magenta: "\x1B[35m"
|
|
9077
|
+
};
|
|
9078
|
+
async function prompt(question, defaultValue) {
|
|
9079
|
+
const rl = createInterface({
|
|
9080
|
+
input: process.stdin,
|
|
9081
|
+
output: process.stdout
|
|
9082
|
+
});
|
|
9083
|
+
return new Promise((resolve) => {
|
|
9084
|
+
const defaultHint = defaultValue ? ` [${defaultValue}]` : "";
|
|
9085
|
+
rl.question(`${question}${defaultHint}: `, (answer) => {
|
|
9086
|
+
rl.close();
|
|
9087
|
+
resolve(answer.trim() || defaultValue || "");
|
|
9088
|
+
});
|
|
9089
|
+
});
|
|
9090
|
+
}
|
|
9091
|
+
async function confirm(question, defaultYes = true) {
|
|
9092
|
+
const hint = defaultYes ? "[Y/n]" : "[y/N]";
|
|
9093
|
+
const answer = await prompt(`${question} ${hint}`);
|
|
9094
|
+
if (!answer)
|
|
9095
|
+
return defaultYes;
|
|
9096
|
+
return answer.toLowerCase().startsWith("y");
|
|
9097
|
+
}
|
|
8800
9098
|
function isInitialized() {
|
|
8801
|
-
return
|
|
9099
|
+
return existsSync7(DATACORE_DIR);
|
|
8802
9100
|
}
|
|
8803
9101
|
async function initDatacore(options = {}) {
|
|
8804
9102
|
const { nonInteractive = false, skipChecks = false, stream = false } = options;
|
|
8805
9103
|
const isTTY = stream && process.stdout.isTTY;
|
|
9104
|
+
const interactive = isTTY && !nonInteractive;
|
|
8806
9105
|
const result = {
|
|
8807
9106
|
success: false,
|
|
8808
9107
|
created: [],
|
|
8809
9108
|
warnings: [],
|
|
8810
9109
|
errors: [],
|
|
8811
|
-
nextSteps: []
|
|
9110
|
+
nextSteps: [],
|
|
9111
|
+
spacesCreated: [],
|
|
9112
|
+
modulesInstalled: []
|
|
8812
9113
|
};
|
|
8813
9114
|
const op = startOperation("init", { options });
|
|
8814
9115
|
op.start();
|
|
@@ -8816,54 +9117,87 @@ async function initDatacore(options = {}) {
|
|
|
8816
9117
|
if (isTTY) {
|
|
8817
9118
|
console.clear();
|
|
8818
9119
|
console.log(BANNER);
|
|
8819
|
-
|
|
8820
|
-
|
|
8821
|
-
await bootSequence();
|
|
9120
|
+
console.log(` ${c2.dim}Setting up your AI-powered second brain...${c2.reset}`);
|
|
9121
|
+
console.log();
|
|
8822
9122
|
await sleep(300);
|
|
8823
9123
|
}
|
|
8824
|
-
const TOTAL_STEPS = 6;
|
|
8825
9124
|
op.addStep("check_dependencies");
|
|
8826
9125
|
op.startStep("check_dependencies");
|
|
8827
9126
|
if (!skipChecks) {
|
|
8828
|
-
let spinner = null;
|
|
8829
9127
|
if (isTTY) {
|
|
8830
|
-
section("System
|
|
8831
|
-
|
|
8832
|
-
spinner.start();
|
|
8833
|
-
await sleep(800);
|
|
9128
|
+
section("Step 1: Checking Your System");
|
|
9129
|
+
console.log();
|
|
8834
9130
|
}
|
|
8835
9131
|
const doctor = runDoctor();
|
|
9132
|
+
const gitStatus = checkGitDetailed();
|
|
9133
|
+
if (isTTY) {
|
|
9134
|
+
if (gitStatus.installed) {
|
|
9135
|
+
console.log(` ${c2.green}✓${c2.reset} git ${c2.dim}(${gitStatus.version})${c2.reset}`);
|
|
9136
|
+
if (gitStatus.configured) {
|
|
9137
|
+
console.log(` ${c2.dim}Configured as: ${gitStatus.userName} <${gitStatus.userEmail}>${c2.reset}`);
|
|
9138
|
+
} else {
|
|
9139
|
+
console.log(` ${c2.yellow}⚠${c2.reset} ${c2.yellow}Not configured. Run:${c2.reset}`);
|
|
9140
|
+
console.log(` ${c2.dim}git config --global user.name "Your Name"${c2.reset}`);
|
|
9141
|
+
console.log(` ${c2.dim}git config --global user.email "you@example.com"${c2.reset}`);
|
|
9142
|
+
result.warnings.push("git not configured with user.name and user.email");
|
|
9143
|
+
}
|
|
9144
|
+
} else {
|
|
9145
|
+
console.log(` ${c2.red}✗${c2.reset} git ${c2.red}(required)${c2.reset}`);
|
|
9146
|
+
console.log(` ${c2.dim}Version control for your knowledge system${c2.reset}`);
|
|
9147
|
+
result.errors.push("git is required but not installed");
|
|
9148
|
+
}
|
|
9149
|
+
if (gitStatus.githubAuth) {
|
|
9150
|
+
console.log(` ${c2.green}✓${c2.reset} GitHub ${c2.dim}(authenticated as ${gitStatus.githubUser})${c2.reset}`);
|
|
9151
|
+
} else {
|
|
9152
|
+
console.log(` ${c2.yellow}○${c2.reset} GitHub ${c2.dim}(not authenticated)${c2.reset}`);
|
|
9153
|
+
console.log(` ${c2.dim}Optional: Install gh CLI and run 'gh auth login'${c2.reset}`);
|
|
9154
|
+
}
|
|
9155
|
+
for (const dep of doctor.dependencies) {
|
|
9156
|
+
if (dep.name === "git")
|
|
9157
|
+
continue;
|
|
9158
|
+
const info2 = {
|
|
9159
|
+
"git-lfs": "Large file support (PDFs, images, videos)",
|
|
9160
|
+
node: "Runtime for automation scripts",
|
|
9161
|
+
python: "Powers AI agents and data processing",
|
|
9162
|
+
claude: "Claude Code AI assistant"
|
|
9163
|
+
};
|
|
9164
|
+
if (dep.installed) {
|
|
9165
|
+
console.log(` ${c2.green}✓${c2.reset} ${dep.name} ${dep.version ? `${c2.dim}(${dep.version})${c2.reset}` : ""}`);
|
|
9166
|
+
} else if (dep.required) {
|
|
9167
|
+
console.log(` ${c2.red}✗${c2.reset} ${dep.name} ${c2.red}(required)${c2.reset}`);
|
|
9168
|
+
console.log(` ${c2.dim}${info2[dep.name] || ""}${c2.reset}`);
|
|
9169
|
+
if (dep.installCommand) {
|
|
9170
|
+
console.log(` ${c2.yellow}Install: ${dep.installCommand}${c2.reset}`);
|
|
9171
|
+
}
|
|
9172
|
+
} else {
|
|
9173
|
+
console.log(` ${c2.yellow}○${c2.reset} ${dep.name} ${c2.dim}(recommended)${c2.reset}`);
|
|
9174
|
+
console.log(` ${c2.dim}${info2[dep.name] || ""}${c2.reset}`);
|
|
9175
|
+
if (dep.installCommand) {
|
|
9176
|
+
console.log(` ${c2.dim}Install: ${dep.installCommand}${c2.reset}`);
|
|
9177
|
+
}
|
|
9178
|
+
}
|
|
9179
|
+
}
|
|
9180
|
+
console.log();
|
|
9181
|
+
}
|
|
8836
9182
|
if (doctor.status === "missing_required") {
|
|
8837
|
-
if (spinner)
|
|
8838
|
-
spinner.fail("Missing required dependencies");
|
|
8839
9183
|
const missing = doctor.dependencies.filter((d) => d.required && !d.installed);
|
|
8840
9184
|
for (const dep of missing) {
|
|
8841
|
-
result.errors.push(`Missing required
|
|
8842
|
-
|
|
8843
|
-
|
|
8844
|
-
}
|
|
9185
|
+
result.errors.push(`Missing required: ${dep.name}`);
|
|
9186
|
+
}
|
|
9187
|
+
if (isTTY) {
|
|
9188
|
+
console.log(` ${c2.red}${c2.bold}Cannot continue - install required dependencies first.${c2.reset}`);
|
|
9189
|
+
console.log();
|
|
8845
9190
|
}
|
|
8846
9191
|
op.failStep("check_dependencies", "Missing required dependencies");
|
|
8847
9192
|
op.fail("Missing required dependencies");
|
|
8848
9193
|
return result;
|
|
8849
9194
|
}
|
|
8850
|
-
if (
|
|
8851
|
-
|
|
8852
|
-
|
|
8853
|
-
|
|
8854
|
-
|
|
8855
|
-
|
|
8856
|
-
result.warnings.push(`Missing recommended: ${dep.name}`);
|
|
8857
|
-
}
|
|
8858
|
-
}
|
|
8859
|
-
if (isTTY) {
|
|
8860
|
-
for (const dep of doctor.dependencies) {
|
|
8861
|
-
if (dep.installed) {
|
|
8862
|
-
console.log(` \x1B[32m✓\x1B[0m ${dep.name} ${dep.version ? `\x1B[90m(${dep.version})\x1B[0m` : ""}`);
|
|
8863
|
-
} else {
|
|
8864
|
-
console.log(` \x1B[33m○\x1B[0m ${dep.name} \x1B[90m(not installed)\x1B[0m`);
|
|
8865
|
-
}
|
|
8866
|
-
await sleep(100);
|
|
9195
|
+
if (interactive && !gitStatus.configured) {
|
|
9196
|
+
const proceed = await confirm("Git is not configured. Continue anyway?", false);
|
|
9197
|
+
if (!proceed) {
|
|
9198
|
+
result.errors.push("User cancelled: git not configured");
|
|
9199
|
+
op.fail("User cancelled");
|
|
9200
|
+
return result;
|
|
8867
9201
|
}
|
|
8868
9202
|
}
|
|
8869
9203
|
}
|
|
@@ -8871,55 +9205,51 @@ async function initDatacore(options = {}) {
|
|
|
8871
9205
|
op.addStep("create_data_dir");
|
|
8872
9206
|
op.startStep("create_data_dir");
|
|
8873
9207
|
if (isTTY) {
|
|
8874
|
-
section("Creating
|
|
9208
|
+
section("Step 2: Creating ~/Data");
|
|
9209
|
+
console.log(` ${c2.dim}Your central knowledge directory. Everything lives here.${c2.reset}`);
|
|
9210
|
+
console.log();
|
|
8875
9211
|
}
|
|
8876
|
-
if (!
|
|
8877
|
-
|
|
8878
|
-
|
|
8879
|
-
await sleep(300);
|
|
8880
|
-
}
|
|
8881
|
-
mkdirSync4(DATA_DIR4, { recursive: true });
|
|
8882
|
-
result.created.push(DATA_DIR4);
|
|
9212
|
+
if (!existsSync7(DATA_DIR5)) {
|
|
9213
|
+
mkdirSync4(DATA_DIR5, { recursive: true });
|
|
9214
|
+
result.created.push(DATA_DIR5);
|
|
8883
9215
|
if (isTTY)
|
|
8884
|
-
console.log(`
|
|
8885
|
-
} else
|
|
8886
|
-
|
|
9216
|
+
console.log(` ${c2.green}✓${c2.reset} Created ${DATA_DIR5}`);
|
|
9217
|
+
} else {
|
|
9218
|
+
if (isTTY)
|
|
9219
|
+
console.log(` ${c2.green}✓${c2.reset} Found ${DATA_DIR5}`);
|
|
8887
9220
|
}
|
|
9221
|
+
if (isTTY)
|
|
9222
|
+
console.log();
|
|
8888
9223
|
op.completeStep("create_data_dir");
|
|
8889
9224
|
op.addStep("create_datacore_dir");
|
|
8890
9225
|
op.startStep("create_datacore_dir");
|
|
8891
|
-
if (
|
|
8892
|
-
|
|
8893
|
-
|
|
8894
|
-
|
|
9226
|
+
if (isTTY) {
|
|
9227
|
+
section("Step 3: Creating .datacore");
|
|
9228
|
+
console.log(` ${c2.dim}System configuration, agents, commands, and modules.${c2.reset}`);
|
|
9229
|
+
console.log();
|
|
9230
|
+
}
|
|
9231
|
+
if (!existsSync7(DATACORE_DIR)) {
|
|
8895
9232
|
const dirs = [
|
|
8896
|
-
{ path: "",
|
|
8897
|
-
{ path: "commands",
|
|
8898
|
-
{ path: "agents",
|
|
8899
|
-
{ path: "modules",
|
|
8900
|
-
{ path: "specs",
|
|
8901
|
-
{ path: "lib",
|
|
8902
|
-
{ path: "env",
|
|
8903
|
-
{ path: "state",
|
|
8904
|
-
{ path: "registry",
|
|
9233
|
+
{ path: "", desc: "" },
|
|
9234
|
+
{ path: "commands", desc: "Slash commands (/today, /sync, etc.)" },
|
|
9235
|
+
{ path: "agents", desc: "AI agents for task automation" },
|
|
9236
|
+
{ path: "modules", desc: "Optional extensions" },
|
|
9237
|
+
{ path: "specs", desc: "System documentation" },
|
|
9238
|
+
{ path: "lib", desc: "Shared utilities" },
|
|
9239
|
+
{ path: "env", desc: "API keys and secrets" },
|
|
9240
|
+
{ path: "state", desc: "Runtime state" },
|
|
9241
|
+
{ path: "registry", desc: "Agent/command discovery" }
|
|
8905
9242
|
];
|
|
8906
|
-
for (const { path: dir,
|
|
8907
|
-
const path =
|
|
8908
|
-
|
|
8909
|
-
|
|
8910
|
-
|
|
8911
|
-
|
|
8912
|
-
console.log(` \x1B[36m◆\x1B[0m ${label}`);
|
|
8913
|
-
await sleep(80);
|
|
8914
|
-
}
|
|
9243
|
+
for (const { path: dir, desc } of dirs) {
|
|
9244
|
+
const path = join7(DATACORE_DIR, dir);
|
|
9245
|
+
mkdirSync4(path, { recursive: true });
|
|
9246
|
+
result.created.push(path);
|
|
9247
|
+
if (isTTY && dir) {
|
|
9248
|
+
console.log(` ${c2.green}✓${c2.reset} ${dir}/ ${c2.dim}- ${desc}${c2.reset}`);
|
|
8915
9249
|
}
|
|
8916
9250
|
}
|
|
8917
|
-
|
|
8918
|
-
|
|
8919
|
-
await sleep(200);
|
|
8920
|
-
}
|
|
8921
|
-
writeFileSync4(join6(DATACORE_DIR, "settings.yaml"), `# Datacore Settings
|
|
8922
|
-
# Override in settings.local.yaml
|
|
9251
|
+
writeFileSync4(join7(DATACORE_DIR, "settings.yaml"), `# Datacore Settings
|
|
9252
|
+
# Override in settings.local.yaml (gitignored)
|
|
8923
9253
|
|
|
8924
9254
|
editor:
|
|
8925
9255
|
open_markdown_on_generate: true
|
|
@@ -8936,75 +9266,162 @@ nightshift:
|
|
|
8936
9266
|
server: ""
|
|
8937
9267
|
auto_trigger: false
|
|
8938
9268
|
`);
|
|
8939
|
-
result.created.push(
|
|
8940
|
-
writeFileSync4(
|
|
8941
|
-
# Agents are discovered from .datacore/agents/ and module agents/
|
|
8942
|
-
|
|
9269
|
+
result.created.push(join7(DATACORE_DIR, "settings.yaml"));
|
|
9270
|
+
writeFileSync4(join7(DATACORE_DIR, "registry", "agents.yaml"), `# Agent Registry
|
|
8943
9271
|
agents: []
|
|
8944
9272
|
`);
|
|
8945
|
-
|
|
8946
|
-
writeFileSync4(join6(DATACORE_DIR, "registry", "commands.yaml"), `# Command Registry
|
|
8947
|
-
# Commands are discovered from .datacore/commands/ and module commands/
|
|
8948
|
-
|
|
9273
|
+
writeFileSync4(join7(DATACORE_DIR, "registry", "commands.yaml"), `# Command Registry
|
|
8949
9274
|
commands: []
|
|
8950
9275
|
`);
|
|
8951
|
-
|
|
9276
|
+
if (isTTY) {
|
|
9277
|
+
console.log();
|
|
9278
|
+
console.log(` ${c2.green}✓${c2.reset} Created settings.yaml`);
|
|
9279
|
+
console.log(` ${c2.dim}Customize in settings.local.yaml${c2.reset}`);
|
|
9280
|
+
}
|
|
9281
|
+
} else {
|
|
8952
9282
|
if (isTTY)
|
|
8953
|
-
console.log(`
|
|
8954
|
-
} else if (isTTY) {
|
|
8955
|
-
step(2, TOTAL_STEPS, "Core matrix exists");
|
|
8956
|
-
step(3, TOTAL_STEPS, "Configuration loaded");
|
|
9283
|
+
console.log(` ${c2.green}✓${c2.reset} Found existing .datacore/`);
|
|
8957
9284
|
}
|
|
9285
|
+
if (isTTY)
|
|
9286
|
+
console.log();
|
|
8958
9287
|
op.completeStep("create_datacore_dir");
|
|
8959
9288
|
op.addStep("create_personal_space");
|
|
8960
9289
|
op.startStep("create_personal_space");
|
|
8961
|
-
|
|
8962
|
-
|
|
9290
|
+
if (isTTY) {
|
|
9291
|
+
section("Step 4: Creating Personal Space");
|
|
9292
|
+
console.log(` ${c2.dim}Your personal GTD system and knowledge base.${c2.reset}`);
|
|
9293
|
+
console.log();
|
|
9294
|
+
}
|
|
9295
|
+
const existingSpaces = listSpaces();
|
|
9296
|
+
const hasPersonal = existingSpaces.some((s) => s.number === 0);
|
|
9297
|
+
if (!hasPersonal) {
|
|
9298
|
+
const space = createSpace("personal", "personal");
|
|
9299
|
+
result.created.push(space.path);
|
|
9300
|
+
result.spacesCreated.push(space.name);
|
|
8963
9301
|
if (isTTY) {
|
|
8964
|
-
|
|
8965
|
-
|
|
9302
|
+
console.log(` ${c2.green}✓${c2.reset} Created 0-personal/`);
|
|
9303
|
+
console.log();
|
|
9304
|
+
console.log(` ${c2.bold}GTD Inbox:${c2.reset} org/inbox.org`);
|
|
9305
|
+
console.log(` ${c2.dim}Capture everything here, process to zero daily${c2.reset}`);
|
|
9306
|
+
console.log();
|
|
9307
|
+
console.log(` ${c2.bold}Next Actions:${c2.reset} org/next_actions.org`);
|
|
9308
|
+
console.log(` ${c2.dim}Tasks by context: @computer, @phone, @errands${c2.reset}`);
|
|
9309
|
+
console.log(` ${c2.dim}Tag with :AI: to delegate to agents${c2.reset}`);
|
|
9310
|
+
console.log();
|
|
9311
|
+
console.log(` ${c2.bold}Knowledge:${c2.reset} notes/`);
|
|
9312
|
+
console.log(` ${c2.dim}Your personal wiki and note archive${c2.reset}`);
|
|
8966
9313
|
}
|
|
8967
|
-
|
|
8968
|
-
|
|
8969
|
-
|
|
8970
|
-
if (isTTY)
|
|
8971
|
-
console.log(` \x1B[35m◉\x1B[0m 0-personal initialized`);
|
|
8972
|
-
} catch (err) {
|
|
8973
|
-
result.warnings.push(`Could not create personal space: ${err.message}`);
|
|
9314
|
+
} else {
|
|
9315
|
+
if (isTTY) {
|
|
9316
|
+
console.log(` ${c2.green}✓${c2.reset} Found existing personal space`);
|
|
8974
9317
|
}
|
|
8975
|
-
} else if (isTTY) {
|
|
8976
|
-
step(4, TOTAL_STEPS, `Found ${spaces.length} existing space(s)`);
|
|
8977
9318
|
}
|
|
9319
|
+
if (isTTY)
|
|
9320
|
+
console.log();
|
|
8978
9321
|
op.completeStep("create_personal_space");
|
|
9322
|
+
if (interactive) {
|
|
9323
|
+
section("Step 5: Additional Spaces");
|
|
9324
|
+
console.log(` ${c2.dim}Spaces separate different areas of your life (work, projects, teams).${c2.reset}`);
|
|
9325
|
+
console.log(` ${c2.dim}Each space is a separate git repo with its own GTD system.${c2.reset}`);
|
|
9326
|
+
console.log();
|
|
9327
|
+
const wantMoreSpaces = await confirm("Would you like to create additional spaces?", false);
|
|
9328
|
+
if (wantMoreSpaces) {
|
|
9329
|
+
let creating = true;
|
|
9330
|
+
while (creating) {
|
|
9331
|
+
const name = await prompt('Space name (e.g., "work", "acme-corp")');
|
|
9332
|
+
if (!name) {
|
|
9333
|
+
creating = false;
|
|
9334
|
+
continue;
|
|
9335
|
+
}
|
|
9336
|
+
try {
|
|
9337
|
+
const space = createSpace(name, "team");
|
|
9338
|
+
result.created.push(space.path);
|
|
9339
|
+
result.spacesCreated.push(space.name);
|
|
9340
|
+
console.log(` ${c2.green}✓${c2.reset} Created ${space.name}/`);
|
|
9341
|
+
} catch (err) {
|
|
9342
|
+
console.log(` ${c2.red}✗${c2.reset} ${err.message}`);
|
|
9343
|
+
}
|
|
9344
|
+
creating = await confirm("Create another space?", false);
|
|
9345
|
+
}
|
|
9346
|
+
}
|
|
9347
|
+
console.log();
|
|
9348
|
+
}
|
|
9349
|
+
if (interactive) {
|
|
9350
|
+
section("Step 6: Install Modules");
|
|
9351
|
+
console.log(` ${c2.dim}Modules add features like overnight AI processing, CRM, and more.${c2.reset}`);
|
|
9352
|
+
console.log();
|
|
9353
|
+
const available = getAvailableModules();
|
|
9354
|
+
if (available.length > 0) {
|
|
9355
|
+
const wantModules = await confirm("Would you like to install modules?", true);
|
|
9356
|
+
if (wantModules) {
|
|
9357
|
+
console.log();
|
|
9358
|
+
console.log(" Available modules:");
|
|
9359
|
+
console.log();
|
|
9360
|
+
for (let i = 0;i < available.length; i++) {
|
|
9361
|
+
const mod = available[i];
|
|
9362
|
+
console.log(` ${c2.cyan}${i + 1}${c2.reset}) ${c2.bold}${mod.name}${c2.reset} - ${mod.description}`);
|
|
9363
|
+
for (const feature of mod.features) {
|
|
9364
|
+
console.log(` ${c2.dim}• ${feature}${c2.reset}`);
|
|
9365
|
+
}
|
|
9366
|
+
console.log();
|
|
9367
|
+
}
|
|
9368
|
+
const choices = await prompt('Enter numbers to install (comma-separated, or "all", or "none")');
|
|
9369
|
+
let toInstall = [];
|
|
9370
|
+
if (choices.toLowerCase() === "all") {
|
|
9371
|
+
toInstall = available.map((m) => m.name);
|
|
9372
|
+
} else if (choices && choices.toLowerCase() !== "none") {
|
|
9373
|
+
const nums = choices.split(",").map((s) => parseInt(s.trim(), 10));
|
|
9374
|
+
toInstall = nums.filter((n) => n >= 1 && n <= available.length).map((n) => available[n - 1].name);
|
|
9375
|
+
}
|
|
9376
|
+
for (const modName of toInstall) {
|
|
9377
|
+
const mod = available.find((m) => m.name === modName);
|
|
9378
|
+
if (!mod)
|
|
9379
|
+
continue;
|
|
9380
|
+
const spinner = new Spinner(`Installing ${modName}...`);
|
|
9381
|
+
spinner.start();
|
|
9382
|
+
try {
|
|
9383
|
+
await sleep(100);
|
|
9384
|
+
installModule(mod.repo);
|
|
9385
|
+
spinner.succeed(`Installed ${modName}`);
|
|
9386
|
+
result.modulesInstalled.push(modName);
|
|
9387
|
+
} catch (err) {
|
|
9388
|
+
spinner.fail(`Failed to install ${modName}: ${err.message}`);
|
|
9389
|
+
result.warnings.push(`Failed to install ${modName}`);
|
|
9390
|
+
}
|
|
9391
|
+
}
|
|
9392
|
+
}
|
|
9393
|
+
} else {
|
|
9394
|
+
console.log(` ${c2.dim}No additional modules available to install.${c2.reset}`);
|
|
9395
|
+
}
|
|
9396
|
+
console.log();
|
|
9397
|
+
}
|
|
8979
9398
|
op.addStep("create_claude_symlink");
|
|
8980
9399
|
op.startStep("create_claude_symlink");
|
|
8981
|
-
|
|
8982
|
-
|
|
8983
|
-
|
|
8984
|
-
|
|
8985
|
-
|
|
8986
|
-
|
|
9400
|
+
if (isTTY) {
|
|
9401
|
+
section("Step 7: Claude Code Integration");
|
|
9402
|
+
console.log(` ${c2.dim}Connecting Datacore to Claude Code AI assistant.${c2.reset}`);
|
|
9403
|
+
console.log();
|
|
9404
|
+
}
|
|
9405
|
+
const claudeDir = join7(DATA_DIR5, ".claude");
|
|
9406
|
+
if (!existsSync7(claudeDir)) {
|
|
8987
9407
|
try {
|
|
8988
9408
|
symlinkSync(DATACORE_DIR, claudeDir);
|
|
8989
9409
|
result.created.push(claudeDir);
|
|
8990
9410
|
if (isTTY)
|
|
8991
|
-
console.log(`
|
|
9411
|
+
console.log(` ${c2.green}✓${c2.reset} Created .claude -> .datacore symlink`);
|
|
8992
9412
|
} catch {
|
|
8993
9413
|
result.warnings.push("Could not create .claude symlink");
|
|
9414
|
+
if (isTTY)
|
|
9415
|
+
console.log(` ${c2.yellow}○${c2.reset} Could not create symlink`);
|
|
8994
9416
|
}
|
|
8995
|
-
} else
|
|
8996
|
-
|
|
9417
|
+
} else {
|
|
9418
|
+
if (isTTY)
|
|
9419
|
+
console.log(` ${c2.green}✓${c2.reset} Found existing .claude/`);
|
|
8997
9420
|
}
|
|
8998
|
-
|
|
8999
|
-
|
|
9000
|
-
|
|
9001
|
-
|
|
9002
|
-
const claudeBaseMd = join6(DATA_DIR4, "CLAUDE.base.md");
|
|
9003
|
-
if (!existsSync6(claudeMd) && !existsSync6(claudeBaseMd)) {
|
|
9004
|
-
if (isTTY) {
|
|
9005
|
-
step(6, TOTAL_STEPS, "Writing consciousness manifest...");
|
|
9006
|
-
await sleep(300);
|
|
9007
|
-
}
|
|
9421
|
+
const claudeMd = join7(DATA_DIR5, "CLAUDE.md");
|
|
9422
|
+
const claudeBaseMd = join7(DATA_DIR5, "CLAUDE.base.md");
|
|
9423
|
+
if (!existsSync7(claudeMd) && !existsSync7(claudeBaseMd)) {
|
|
9424
|
+
const allSpaces = listSpaces();
|
|
9008
9425
|
writeFileSync4(claudeBaseMd, `# Datacore
|
|
9009
9426
|
|
|
9010
9427
|
AI-powered second brain built on GTD methodology.
|
|
@@ -9015,16 +9432,24 @@ AI-powered second brain built on GTD methodology.
|
|
|
9015
9432
|
cd ~/Data && claude
|
|
9016
9433
|
\`\`\`
|
|
9017
9434
|
|
|
9435
|
+
## Daily Workflow
|
|
9436
|
+
|
|
9437
|
+
1. **Morning**: Run \`/today\` for your daily briefing
|
|
9438
|
+
2. **Capture**: Add tasks to \`0-personal/org/inbox.org\`
|
|
9439
|
+
3. **Process**: Clear inbox, organize by context
|
|
9440
|
+
4. **Work**: Use \`:AI:\` tags to delegate tasks
|
|
9441
|
+
5. **Evening**: Run \`/tomorrow\` for wrap-up
|
|
9442
|
+
|
|
9018
9443
|
## Commands
|
|
9019
9444
|
|
|
9020
|
-
-
|
|
9021
|
-
-
|
|
9022
|
-
-
|
|
9445
|
+
- \`/today\` - Daily briefing with priorities
|
|
9446
|
+
- \`/tomorrow\` - End-of-day wrap-up
|
|
9447
|
+
- \`/sync\` - Sync all repos
|
|
9023
9448
|
- \`datacore doctor\` - Check system health
|
|
9024
9449
|
|
|
9025
9450
|
## Spaces
|
|
9026
9451
|
|
|
9027
|
-
${
|
|
9452
|
+
${allSpaces.map((s) => `- ${s.name}`).join(`
|
|
9028
9453
|
`) || "- 0-personal"}
|
|
9029
9454
|
|
|
9030
9455
|
## Documentation
|
|
@@ -9033,22 +9458,47 @@ See .datacore/specs/ for detailed documentation.
|
|
|
9033
9458
|
`);
|
|
9034
9459
|
result.created.push(claudeBaseMd);
|
|
9035
9460
|
if (isTTY)
|
|
9036
|
-
console.log(`
|
|
9037
|
-
} else
|
|
9038
|
-
|
|
9461
|
+
console.log(` ${c2.green}✓${c2.reset} Created CLAUDE.base.md`);
|
|
9462
|
+
} else {
|
|
9463
|
+
if (isTTY)
|
|
9464
|
+
console.log(` ${c2.green}✓${c2.reset} Found existing CLAUDE.md`);
|
|
9039
9465
|
}
|
|
9040
|
-
|
|
9466
|
+
if (isTTY)
|
|
9467
|
+
console.log();
|
|
9468
|
+
op.completeStep("create_claude_symlink");
|
|
9041
9469
|
result.success = true;
|
|
9042
9470
|
result.nextSteps = [
|
|
9043
|
-
"
|
|
9044
|
-
"
|
|
9471
|
+
"cd ~/Data && claude",
|
|
9472
|
+
"Add tasks to 0-personal/org/inbox.org",
|
|
9473
|
+
"Run /today for your first daily briefing"
|
|
9045
9474
|
];
|
|
9046
9475
|
if (isTTY) {
|
|
9047
|
-
await sleep(500);
|
|
9048
9476
|
console.log(INIT_COMPLETE);
|
|
9049
|
-
await typewrite(" Your second brain is ready.", 25);
|
|
9050
9477
|
console.log();
|
|
9051
|
-
console.log(
|
|
9478
|
+
console.log(` ${c2.bold}Setup Complete!${c2.reset}`);
|
|
9479
|
+
console.log();
|
|
9480
|
+
if (result.spacesCreated.length > 0) {
|
|
9481
|
+
console.log(` ${c2.green}Spaces created:${c2.reset} ${result.spacesCreated.join(", ")}`);
|
|
9482
|
+
}
|
|
9483
|
+
if (result.modulesInstalled.length > 0) {
|
|
9484
|
+
console.log(` ${c2.green}Modules installed:${c2.reset} ${result.modulesInstalled.join(", ")}`);
|
|
9485
|
+
}
|
|
9486
|
+
if (result.warnings.length > 0) {
|
|
9487
|
+
console.log(` ${c2.yellow}Warnings:${c2.reset} ${result.warnings.length}`);
|
|
9488
|
+
}
|
|
9489
|
+
console.log();
|
|
9490
|
+
console.log(` ${c2.bold}Get Started:${c2.reset}`);
|
|
9491
|
+
console.log();
|
|
9492
|
+
console.log(` ${c2.cyan}1.${c2.reset} cd ~/Data && claude`);
|
|
9493
|
+
console.log(` ${c2.dim}Start Claude Code in your Datacore directory${c2.reset}`);
|
|
9494
|
+
console.log();
|
|
9495
|
+
console.log(` ${c2.cyan}2.${c2.reset} Type ${c2.cyan}/today${c2.reset}`);
|
|
9496
|
+
console.log(` ${c2.dim}Get your first daily briefing${c2.reset}`);
|
|
9497
|
+
console.log();
|
|
9498
|
+
console.log(` ${c2.cyan}3.${c2.reset} Add tasks to ${c2.cyan}0-personal/org/inbox.org${c2.reset}`);
|
|
9499
|
+
console.log(` ${c2.dim}Your GTD capture inbox${c2.reset}`);
|
|
9500
|
+
console.log();
|
|
9501
|
+
console.log(` ${c2.dim}Run 'datacore doctor' anytime to check system health.${c2.reset}`);
|
|
9052
9502
|
console.log();
|
|
9053
9503
|
}
|
|
9054
9504
|
op.complete();
|
|
@@ -9059,150 +9509,14 @@ See .datacore/specs/ for detailed documentation.
|
|
|
9059
9509
|
return result;
|
|
9060
9510
|
}
|
|
9061
9511
|
|
|
9062
|
-
// src/lib/module.ts
|
|
9063
|
-
import { existsSync as existsSync7, readdirSync as readdirSync2, readFileSync as readFileSync4, rmSync } from "fs";
|
|
9064
|
-
import { join as join7, basename as basename3 } from "path";
|
|
9065
|
-
import { execSync as execSync4 } from "child_process";
|
|
9066
|
-
var DATA_DIR5 = join7(process.env.HOME || "~", "Data");
|
|
9067
|
-
var MODULES_DIR = join7(DATA_DIR5, ".datacore", "modules");
|
|
9068
|
-
function listModules() {
|
|
9069
|
-
if (!existsSync7(MODULES_DIR)) {
|
|
9070
|
-
return [];
|
|
9071
|
-
}
|
|
9072
|
-
const entries = readdirSync2(MODULES_DIR, { withFileTypes: true });
|
|
9073
|
-
const modules = [];
|
|
9074
|
-
for (const entry of entries) {
|
|
9075
|
-
if (!entry.isDirectory())
|
|
9076
|
-
continue;
|
|
9077
|
-
if (entry.name.startsWith("."))
|
|
9078
|
-
continue;
|
|
9079
|
-
const modulePath = join7(MODULES_DIR, entry.name);
|
|
9080
|
-
const info2 = getModuleInfo(modulePath);
|
|
9081
|
-
if (info2) {
|
|
9082
|
-
modules.push(info2);
|
|
9083
|
-
}
|
|
9084
|
-
}
|
|
9085
|
-
return modules;
|
|
9086
|
-
}
|
|
9087
|
-
function getModuleInfo(modulePath) {
|
|
9088
|
-
const name = basename3(modulePath);
|
|
9089
|
-
const yamlPath = join7(modulePath, "module.yaml");
|
|
9090
|
-
const ymlPath = join7(modulePath, "module.yml");
|
|
9091
|
-
const configPath = existsSync7(yamlPath) ? yamlPath : existsSync7(ymlPath) ? ymlPath : null;
|
|
9092
|
-
let version;
|
|
9093
|
-
let description;
|
|
9094
|
-
if (configPath) {
|
|
9095
|
-
try {
|
|
9096
|
-
const { parse: parse2 } = require_dist();
|
|
9097
|
-
const content = readFileSync4(configPath, "utf-8");
|
|
9098
|
-
const config = parse2(content);
|
|
9099
|
-
version = config.version;
|
|
9100
|
-
description = config.description;
|
|
9101
|
-
} catch {}
|
|
9102
|
-
}
|
|
9103
|
-
const agentsDir = join7(modulePath, "agents");
|
|
9104
|
-
const agents = [];
|
|
9105
|
-
if (existsSync7(agentsDir)) {
|
|
9106
|
-
const agentFiles = readdirSync2(agentsDir);
|
|
9107
|
-
for (const file of agentFiles) {
|
|
9108
|
-
if (file.endsWith(".md")) {
|
|
9109
|
-
agents.push(file.replace(".md", ""));
|
|
9110
|
-
}
|
|
9111
|
-
}
|
|
9112
|
-
}
|
|
9113
|
-
const commandsDir = join7(modulePath, "commands");
|
|
9114
|
-
const commands = [];
|
|
9115
|
-
if (existsSync7(commandsDir)) {
|
|
9116
|
-
const cmdFiles = readdirSync2(commandsDir);
|
|
9117
|
-
for (const file of cmdFiles) {
|
|
9118
|
-
if (file.endsWith(".md")) {
|
|
9119
|
-
commands.push(file.replace(".md", ""));
|
|
9120
|
-
}
|
|
9121
|
-
}
|
|
9122
|
-
}
|
|
9123
|
-
return {
|
|
9124
|
-
name,
|
|
9125
|
-
path: modulePath,
|
|
9126
|
-
version,
|
|
9127
|
-
description,
|
|
9128
|
-
agents,
|
|
9129
|
-
commands
|
|
9130
|
-
};
|
|
9131
|
-
}
|
|
9132
|
-
function installModule(source) {
|
|
9133
|
-
if (!existsSync7(MODULES_DIR)) {
|
|
9134
|
-
const { mkdirSync: mkdirSync5 } = __require("fs");
|
|
9135
|
-
mkdirSync5(MODULES_DIR, { recursive: true });
|
|
9136
|
-
}
|
|
9137
|
-
let name;
|
|
9138
|
-
let isGit = false;
|
|
9139
|
-
if (source.includes("github.com") || source.startsWith("git@") || source.endsWith(".git")) {
|
|
9140
|
-
isGit = true;
|
|
9141
|
-
const match = source.match(/([^/]+?)(?:\.git)?$/);
|
|
9142
|
-
name = match?.[1] ?? source.split("/").pop() ?? "unknown";
|
|
9143
|
-
name = name.replace(/^module-/, "");
|
|
9144
|
-
} else if (source.startsWith("@")) {
|
|
9145
|
-
name = source.split("/").pop()?.replace(/^datacore-/, "") ?? "unknown";
|
|
9146
|
-
} else {
|
|
9147
|
-
name = source.replace(/^datacore-/, "").replace(/^module-/, "");
|
|
9148
|
-
}
|
|
9149
|
-
const modulePath = join7(MODULES_DIR, name);
|
|
9150
|
-
if (existsSync7(modulePath)) {
|
|
9151
|
-
throw new Error(`Module already installed: ${name}`);
|
|
9152
|
-
}
|
|
9153
|
-
if (isGit) {
|
|
9154
|
-
execSync4(`git clone ${source} "${modulePath}"`, { stdio: "pipe" });
|
|
9155
|
-
} else {
|
|
9156
|
-
const gitUrl = `https://github.com/datacore/module-${name}.git`;
|
|
9157
|
-
try {
|
|
9158
|
-
execSync4(`git clone ${gitUrl} "${modulePath}"`, { stdio: "pipe" });
|
|
9159
|
-
} catch {
|
|
9160
|
-
throw new Error(`Could not install module: ${source}`);
|
|
9161
|
-
}
|
|
9162
|
-
}
|
|
9163
|
-
const info2 = getModuleInfo(modulePath);
|
|
9164
|
-
if (!info2) {
|
|
9165
|
-
rmSync(modulePath, { recursive: true, force: true });
|
|
9166
|
-
throw new Error("Invalid module: missing module.yaml");
|
|
9167
|
-
}
|
|
9168
|
-
return info2;
|
|
9169
|
-
}
|
|
9170
|
-
function updateModules(name) {
|
|
9171
|
-
const modules = listModules();
|
|
9172
|
-
const results = [];
|
|
9173
|
-
const toUpdate = name ? modules.filter((m) => m.name === name) : modules;
|
|
9174
|
-
for (const mod of toUpdate) {
|
|
9175
|
-
try {
|
|
9176
|
-
const gitDir = join7(mod.path, ".git");
|
|
9177
|
-
if (existsSync7(gitDir)) {
|
|
9178
|
-
execSync4("git pull", { cwd: mod.path, stdio: "pipe" });
|
|
9179
|
-
results.push({ name: mod.name, updated: true });
|
|
9180
|
-
} else {
|
|
9181
|
-
results.push({ name: mod.name, updated: false, error: "Not a git repository" });
|
|
9182
|
-
}
|
|
9183
|
-
} catch (err) {
|
|
9184
|
-
results.push({ name: mod.name, updated: false, error: err.message });
|
|
9185
|
-
}
|
|
9186
|
-
}
|
|
9187
|
-
return results;
|
|
9188
|
-
}
|
|
9189
|
-
function removeModule(name) {
|
|
9190
|
-
const modulePath = join7(MODULES_DIR, name);
|
|
9191
|
-
if (!existsSync7(modulePath)) {
|
|
9192
|
-
return false;
|
|
9193
|
-
}
|
|
9194
|
-
rmSync(modulePath, { recursive: true, force: true });
|
|
9195
|
-
return true;
|
|
9196
|
-
}
|
|
9197
|
-
|
|
9198
9512
|
// src/lib/snapshot.ts
|
|
9199
9513
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
9200
|
-
import { existsSync as existsSync8, readFileSync as
|
|
9514
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5 } from "fs";
|
|
9201
9515
|
import { execSync as execSync5 } from "child_process";
|
|
9202
9516
|
import { join as join8 } from "path";
|
|
9203
9517
|
var DATA_DIR6 = join8(process.env.HOME || "~", "Data");
|
|
9204
9518
|
var LOCK_FILE = join8(DATA_DIR6, "datacore.lock.yaml");
|
|
9205
|
-
var CLI_VERSION = "1.0.
|
|
9519
|
+
var CLI_VERSION = "1.0.5";
|
|
9206
9520
|
function getGitInfo(path) {
|
|
9207
9521
|
if (!existsSync8(join8(path, ".git"))) {
|
|
9208
9522
|
return {};
|
|
@@ -9268,7 +9582,7 @@ function createSnapshot(options = {}) {
|
|
|
9268
9582
|
const settingsPath = join8(DATA_DIR6, ".datacore", "settings.yaml");
|
|
9269
9583
|
if (existsSync8(settingsPath)) {
|
|
9270
9584
|
try {
|
|
9271
|
-
const content =
|
|
9585
|
+
const content = readFileSync4(settingsPath, "utf-8");
|
|
9272
9586
|
snapshot.settings = import_yaml2.parse(content);
|
|
9273
9587
|
} catch {}
|
|
9274
9588
|
}
|
|
@@ -9289,7 +9603,7 @@ function loadSnapshot(path) {
|
|
|
9289
9603
|
return null;
|
|
9290
9604
|
}
|
|
9291
9605
|
try {
|
|
9292
|
-
const content =
|
|
9606
|
+
const content = readFileSync4(lockPath, "utf-8");
|
|
9293
9607
|
return import_yaml2.parse(content);
|
|
9294
9608
|
} catch {
|
|
9295
9609
|
return null;
|
|
@@ -9421,7 +9735,7 @@ function restoreFromSnapshot(snapshot, options = {}) {
|
|
|
9421
9735
|
}
|
|
9422
9736
|
|
|
9423
9737
|
// src/index.ts
|
|
9424
|
-
var VERSION = "1.0.
|
|
9738
|
+
var VERSION = "1.0.5";
|
|
9425
9739
|
var args = process.argv.slice(2);
|
|
9426
9740
|
var parsed = parseArgs(args);
|
|
9427
9741
|
async function handleMeta(command, cmdArgs, flags, format) {
|
|
@@ -9469,8 +9783,8 @@ async function handleMeta(command, cmdArgs, flags, format) {
|
|
|
9469
9783
|
}
|
|
9470
9784
|
console.log();
|
|
9471
9785
|
console.log("Next steps:");
|
|
9472
|
-
for (const
|
|
9473
|
-
console.log(` → ${
|
|
9786
|
+
for (const step of result.nextSteps) {
|
|
9787
|
+
console.log(` → ${step}`);
|
|
9474
9788
|
}
|
|
9475
9789
|
} else {
|
|
9476
9790
|
error("Initialization failed");
|