@datacore-one/cli 1.0.4 → 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 +684 -301
- 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,14 +7991,56 @@ 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) {
|
|
@@ -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
|
|
8502
|
+
|
|
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
|
|
8368
8527
|
|
|
8369
|
-
|
|
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: [] };
|
|
@@ -8651,6 +8982,7 @@ function startOperation(operation, params = {}) {
|
|
|
8651
8982
|
}
|
|
8652
8983
|
|
|
8653
8984
|
// src/lib/animation.ts
|
|
8985
|
+
var SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
8654
8986
|
var c = {
|
|
8655
8987
|
reset: "\x1B[0m",
|
|
8656
8988
|
bright: "\x1B[1m",
|
|
@@ -8686,6 +9018,44 @@ ${c.green}${c.bright}
|
|
|
8686
9018
|
╚═══════════════════════════════════════════════════════════════╝
|
|
8687
9019
|
${c.reset}
|
|
8688
9020
|
`;
|
|
9021
|
+
function sleep(ms) {
|
|
9022
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
9023
|
+
}
|
|
9024
|
+
class Spinner {
|
|
9025
|
+
interval = null;
|
|
9026
|
+
frame = 0;
|
|
9027
|
+
message;
|
|
9028
|
+
constructor(message) {
|
|
9029
|
+
this.message = message;
|
|
9030
|
+
}
|
|
9031
|
+
start() {
|
|
9032
|
+
process.stdout.write("\x1B[?25l");
|
|
9033
|
+
this.interval = setInterval(() => {
|
|
9034
|
+
const spinner = SPINNER_FRAMES[this.frame % SPINNER_FRAMES.length];
|
|
9035
|
+
process.stdout.write(`\r${c.cyan}${spinner}${c.reset} ${this.message}`);
|
|
9036
|
+
this.frame++;
|
|
9037
|
+
}, 80);
|
|
9038
|
+
}
|
|
9039
|
+
update(message) {
|
|
9040
|
+
this.message = message;
|
|
9041
|
+
}
|
|
9042
|
+
succeed(message) {
|
|
9043
|
+
this.stop();
|
|
9044
|
+
console.log(`\r${c.green}✓${c.reset} ${message || this.message}`);
|
|
9045
|
+
}
|
|
9046
|
+
fail(message) {
|
|
9047
|
+
this.stop();
|
|
9048
|
+
console.log(`\r${c.yellow}✗${c.reset} ${message || this.message}`);
|
|
9049
|
+
}
|
|
9050
|
+
stop() {
|
|
9051
|
+
if (this.interval) {
|
|
9052
|
+
clearInterval(this.interval);
|
|
9053
|
+
this.interval = null;
|
|
9054
|
+
}
|
|
9055
|
+
process.stdout.write("\x1B[?25h");
|
|
9056
|
+
process.stdout.write("\r" + " ".repeat(this.message.length + 10) + "\r");
|
|
9057
|
+
}
|
|
9058
|
+
}
|
|
8689
9059
|
function section(title) {
|
|
8690
9060
|
console.log();
|
|
8691
9061
|
console.log(`${c.cyan}${c.bright}▸ ${title}${c.reset}`);
|
|
@@ -8693,20 +9063,53 @@ function section(title) {
|
|
|
8693
9063
|
}
|
|
8694
9064
|
|
|
8695
9065
|
// src/lib/init.ts
|
|
8696
|
-
var
|
|
8697
|
-
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
|
+
}
|
|
8698
9098
|
function isInitialized() {
|
|
8699
|
-
return
|
|
9099
|
+
return existsSync7(DATACORE_DIR);
|
|
8700
9100
|
}
|
|
8701
9101
|
async function initDatacore(options = {}) {
|
|
8702
9102
|
const { nonInteractive = false, skipChecks = false, stream = false } = options;
|
|
8703
9103
|
const isTTY = stream && process.stdout.isTTY;
|
|
9104
|
+
const interactive = isTTY && !nonInteractive;
|
|
8704
9105
|
const result = {
|
|
8705
9106
|
success: false,
|
|
8706
9107
|
created: [],
|
|
8707
9108
|
warnings: [],
|
|
8708
9109
|
errors: [],
|
|
8709
|
-
nextSteps: []
|
|
9110
|
+
nextSteps: [],
|
|
9111
|
+
spacesCreated: [],
|
|
9112
|
+
modulesInstalled: []
|
|
8710
9113
|
};
|
|
8711
9114
|
const op = startOperation("init", { options });
|
|
8712
9115
|
op.start();
|
|
@@ -8714,42 +9117,63 @@ async function initDatacore(options = {}) {
|
|
|
8714
9117
|
if (isTTY) {
|
|
8715
9118
|
console.clear();
|
|
8716
9119
|
console.log(BANNER);
|
|
9120
|
+
console.log(` ${c2.dim}Setting up your AI-powered second brain...${c2.reset}`);
|
|
8717
9121
|
console.log();
|
|
9122
|
+
await sleep(300);
|
|
8718
9123
|
}
|
|
8719
|
-
const TOTAL_STEPS = 6;
|
|
8720
9124
|
op.addStep("check_dependencies");
|
|
8721
9125
|
op.startStep("check_dependencies");
|
|
8722
9126
|
if (!skipChecks) {
|
|
8723
9127
|
if (isTTY) {
|
|
8724
|
-
section("Checking
|
|
8725
|
-
console.log(" \x1B[90mDatacore requires a few tools to manage your knowledge system.\x1B[0m");
|
|
9128
|
+
section("Step 1: Checking Your System");
|
|
8726
9129
|
console.log();
|
|
8727
9130
|
}
|
|
8728
9131
|
const doctor = runDoctor();
|
|
8729
|
-
const
|
|
8730
|
-
git: "Version control for your knowledge repos",
|
|
8731
|
-
"git-lfs": "Large file support (PDFs, images, videos)",
|
|
8732
|
-
node: "Runtime for CLI tools and automation",
|
|
8733
|
-
python: "Powers AI agents and data processing",
|
|
8734
|
-
claude: "Claude Code AI assistant integration"
|
|
8735
|
-
};
|
|
9132
|
+
const gitStatus = checkGitDetailed();
|
|
8736
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
|
+
}
|
|
8737
9155
|
for (const dep of doctor.dependencies) {
|
|
8738
|
-
|
|
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
|
+
};
|
|
8739
9164
|
if (dep.installed) {
|
|
8740
|
-
console.log(`
|
|
8741
|
-
console.log(` \x1B[90m${info2}\x1B[0m`);
|
|
9165
|
+
console.log(` ${c2.green}✓${c2.reset} ${dep.name} ${dep.version ? `${c2.dim}(${dep.version})${c2.reset}` : ""}`);
|
|
8742
9166
|
} else if (dep.required) {
|
|
8743
|
-
console.log(`
|
|
8744
|
-
console.log(`
|
|
9167
|
+
console.log(` ${c2.red}✗${c2.reset} ${dep.name} ${c2.red}(required)${c2.reset}`);
|
|
9168
|
+
console.log(` ${c2.dim}${info2[dep.name] || ""}${c2.reset}`);
|
|
8745
9169
|
if (dep.installCommand) {
|
|
8746
|
-
console.log(`
|
|
9170
|
+
console.log(` ${c2.yellow}Install: ${dep.installCommand}${c2.reset}`);
|
|
8747
9171
|
}
|
|
8748
9172
|
} else {
|
|
8749
|
-
console.log(`
|
|
8750
|
-
console.log(`
|
|
9173
|
+
console.log(` ${c2.yellow}○${c2.reset} ${dep.name} ${c2.dim}(recommended)${c2.reset}`);
|
|
9174
|
+
console.log(` ${c2.dim}${info2[dep.name] || ""}${c2.reset}`);
|
|
8751
9175
|
if (dep.installCommand) {
|
|
8752
|
-
console.log(`
|
|
9176
|
+
console.log(` ${c2.dim}Install: ${dep.installCommand}${c2.reset}`);
|
|
8753
9177
|
}
|
|
8754
9178
|
}
|
|
8755
9179
|
}
|
|
@@ -8758,19 +9182,22 @@ async function initDatacore(options = {}) {
|
|
|
8758
9182
|
if (doctor.status === "missing_required") {
|
|
8759
9183
|
const missing = doctor.dependencies.filter((d) => d.required && !d.installed);
|
|
8760
9184
|
for (const dep of missing) {
|
|
8761
|
-
result.errors.push(`Missing required
|
|
8762
|
-
|
|
8763
|
-
|
|
8764
|
-
}
|
|
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();
|
|
8765
9190
|
}
|
|
8766
9191
|
op.failStep("check_dependencies", "Missing required dependencies");
|
|
8767
9192
|
op.fail("Missing required dependencies");
|
|
8768
9193
|
return result;
|
|
8769
9194
|
}
|
|
8770
|
-
if (
|
|
8771
|
-
const
|
|
8772
|
-
|
|
8773
|
-
result.
|
|
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;
|
|
8774
9201
|
}
|
|
8775
9202
|
}
|
|
8776
9203
|
}
|
|
@@ -8778,51 +9205,51 @@ async function initDatacore(options = {}) {
|
|
|
8778
9205
|
op.addStep("create_data_dir");
|
|
8779
9206
|
op.startStep("create_data_dir");
|
|
8780
9207
|
if (isTTY) {
|
|
8781
|
-
section("
|
|
8782
|
-
console.log(
|
|
9208
|
+
section("Step 2: Creating ~/Data");
|
|
9209
|
+
console.log(` ${c2.dim}Your central knowledge directory. Everything lives here.${c2.reset}`);
|
|
8783
9210
|
console.log();
|
|
8784
9211
|
}
|
|
8785
|
-
if (!
|
|
8786
|
-
mkdirSync4(
|
|
8787
|
-
result.created.push(
|
|
9212
|
+
if (!existsSync7(DATA_DIR5)) {
|
|
9213
|
+
mkdirSync4(DATA_DIR5, { recursive: true });
|
|
9214
|
+
result.created.push(DATA_DIR5);
|
|
8788
9215
|
if (isTTY)
|
|
8789
|
-
console.log(`
|
|
8790
|
-
} else
|
|
8791
|
-
|
|
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}`);
|
|
8792
9220
|
}
|
|
9221
|
+
if (isTTY)
|
|
9222
|
+
console.log();
|
|
8793
9223
|
op.completeStep("create_data_dir");
|
|
8794
9224
|
op.addStep("create_datacore_dir");
|
|
8795
9225
|
op.startStep("create_datacore_dir");
|
|
8796
9226
|
if (isTTY) {
|
|
8797
|
-
|
|
8798
|
-
|
|
8799
|
-
console.log(" \x1B[90mSystem configuration, agents, and modules live here.\x1B[0m");
|
|
9227
|
+
section("Step 3: Creating .datacore");
|
|
9228
|
+
console.log(` ${c2.dim}System configuration, agents, commands, and modules.${c2.reset}`);
|
|
8800
9229
|
console.log();
|
|
8801
9230
|
}
|
|
8802
|
-
if (!
|
|
9231
|
+
if (!existsSync7(DATACORE_DIR)) {
|
|
8803
9232
|
const dirs = [
|
|
8804
|
-
{ path: "", desc: "
|
|
8805
|
-
{ path: "commands", desc: "Slash commands (
|
|
9233
|
+
{ path: "", desc: "" },
|
|
9234
|
+
{ path: "commands", desc: "Slash commands (/today, /sync, etc.)" },
|
|
8806
9235
|
{ path: "agents", desc: "AI agents for task automation" },
|
|
8807
|
-
{ path: "modules", desc: "Optional extensions
|
|
9236
|
+
{ path: "modules", desc: "Optional extensions" },
|
|
8808
9237
|
{ path: "specs", desc: "System documentation" },
|
|
8809
9238
|
{ path: "lib", desc: "Shared utilities" },
|
|
8810
|
-
{ path: "env", desc: "
|
|
8811
|
-
{ path: "state", desc: "Runtime state
|
|
8812
|
-
{ path: "registry", desc: "Agent
|
|
9239
|
+
{ path: "env", desc: "API keys and secrets" },
|
|
9240
|
+
{ path: "state", desc: "Runtime state" },
|
|
9241
|
+
{ path: "registry", desc: "Agent/command discovery" }
|
|
8813
9242
|
];
|
|
8814
9243
|
for (const { path: dir, desc } of dirs) {
|
|
8815
|
-
const path =
|
|
8816
|
-
|
|
8817
|
-
|
|
8818
|
-
|
|
8819
|
-
|
|
8820
|
-
console.log(` \x1B[32m✓\x1B[0m ${dir}/ \x1B[90m- ${desc}\x1B[0m`);
|
|
8821
|
-
}
|
|
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}`);
|
|
8822
9249
|
}
|
|
8823
9250
|
}
|
|
8824
|
-
writeFileSync4(
|
|
8825
|
-
# Override in settings.local.yaml
|
|
9251
|
+
writeFileSync4(join7(DATACORE_DIR, "settings.yaml"), `# Datacore Settings
|
|
9252
|
+
# Override in settings.local.yaml (gitignored)
|
|
8826
9253
|
|
|
8827
9254
|
editor:
|
|
8828
9255
|
open_markdown_on_generate: true
|
|
@@ -8839,95 +9266,162 @@ nightshift:
|
|
|
8839
9266
|
server: ""
|
|
8840
9267
|
auto_trigger: false
|
|
8841
9268
|
`);
|
|
8842
|
-
result.created.push(
|
|
8843
|
-
writeFileSync4(
|
|
8844
|
-
# Agents are discovered from .datacore/agents/ and module agents/
|
|
8845
|
-
|
|
9269
|
+
result.created.push(join7(DATACORE_DIR, "settings.yaml"));
|
|
9270
|
+
writeFileSync4(join7(DATACORE_DIR, "registry", "agents.yaml"), `# Agent Registry
|
|
8846
9271
|
agents: []
|
|
8847
9272
|
`);
|
|
8848
|
-
|
|
8849
|
-
writeFileSync4(join6(DATACORE_DIR, "registry", "commands.yaml"), `# Command Registry
|
|
8850
|
-
# Commands are discovered from .datacore/commands/ and module commands/
|
|
8851
|
-
|
|
9273
|
+
writeFileSync4(join7(DATACORE_DIR, "registry", "commands.yaml"), `# Command Registry
|
|
8852
9274
|
commands: []
|
|
8853
9275
|
`);
|
|
8854
|
-
result.created.push(join6(DATACORE_DIR, "registry", "commands.yaml"));
|
|
8855
9276
|
if (isTTY) {
|
|
8856
9277
|
console.log();
|
|
8857
|
-
console.log(`
|
|
8858
|
-
console.log(
|
|
9278
|
+
console.log(` ${c2.green}✓${c2.reset} Created settings.yaml`);
|
|
9279
|
+
console.log(` ${c2.dim}Customize in settings.local.yaml${c2.reset}`);
|
|
8859
9280
|
}
|
|
8860
|
-
} else
|
|
8861
|
-
|
|
9281
|
+
} else {
|
|
9282
|
+
if (isTTY)
|
|
9283
|
+
console.log(` ${c2.green}✓${c2.reset} Found existing .datacore/`);
|
|
8862
9284
|
}
|
|
9285
|
+
if (isTTY)
|
|
9286
|
+
console.log();
|
|
8863
9287
|
op.completeStep("create_datacore_dir");
|
|
8864
9288
|
op.addStep("create_personal_space");
|
|
8865
9289
|
op.startStep("create_personal_space");
|
|
8866
9290
|
if (isTTY) {
|
|
8867
|
-
|
|
8868
|
-
|
|
8869
|
-
console.log(" \x1B[90mSpaces are separate knowledge areas (personal, work, projects).\x1B[0m");
|
|
8870
|
-
console.log(" \x1B[90mEach space has its own GTD inbox, notes, and journals.\x1B[0m");
|
|
9291
|
+
section("Step 4: Creating Personal Space");
|
|
9292
|
+
console.log(` ${c2.dim}Your personal GTD system and knowledge base.${c2.reset}`);
|
|
8871
9293
|
console.log();
|
|
8872
9294
|
}
|
|
8873
|
-
const
|
|
8874
|
-
|
|
8875
|
-
|
|
8876
|
-
|
|
8877
|
-
|
|
8878
|
-
|
|
8879
|
-
|
|
8880
|
-
|
|
8881
|
-
|
|
8882
|
-
|
|
8883
|
-
}
|
|
8884
|
-
|
|
8885
|
-
|
|
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);
|
|
9301
|
+
if (isTTY) {
|
|
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}`);
|
|
8886
9313
|
}
|
|
8887
|
-
} else
|
|
8888
|
-
|
|
8889
|
-
|
|
8890
|
-
console.log(` \x1B[90m${space.name}/\x1B[0m`);
|
|
9314
|
+
} else {
|
|
9315
|
+
if (isTTY) {
|
|
9316
|
+
console.log(` ${c2.green}✓${c2.reset} Found existing personal space`);
|
|
8891
9317
|
}
|
|
8892
9318
|
}
|
|
9319
|
+
if (isTTY)
|
|
9320
|
+
console.log();
|
|
8893
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
|
+
}
|
|
8894
9398
|
op.addStep("create_claude_symlink");
|
|
8895
9399
|
op.startStep("create_claude_symlink");
|
|
8896
9400
|
if (isTTY) {
|
|
8897
|
-
|
|
8898
|
-
|
|
8899
|
-
console.log(" \x1B[90mClaude Code looks for .claude/ to find project context.\x1B[0m");
|
|
8900
|
-
console.log(" \x1B[90mThis symlink connects it to your Datacore configuration.\x1B[0m");
|
|
9401
|
+
section("Step 7: Claude Code Integration");
|
|
9402
|
+
console.log(` ${c2.dim}Connecting Datacore to Claude Code AI assistant.${c2.reset}`);
|
|
8901
9403
|
console.log();
|
|
8902
9404
|
}
|
|
8903
|
-
const claudeDir =
|
|
8904
|
-
if (!
|
|
9405
|
+
const claudeDir = join7(DATA_DIR5, ".claude");
|
|
9406
|
+
if (!existsSync7(claudeDir)) {
|
|
8905
9407
|
try {
|
|
8906
9408
|
symlinkSync(DATACORE_DIR, claudeDir);
|
|
8907
9409
|
result.created.push(claudeDir);
|
|
8908
9410
|
if (isTTY)
|
|
8909
|
-
console.log(`
|
|
9411
|
+
console.log(` ${c2.green}✓${c2.reset} Created .claude -> .datacore symlink`);
|
|
8910
9412
|
} catch {
|
|
8911
9413
|
result.warnings.push("Could not create .claude symlink");
|
|
8912
9414
|
if (isTTY)
|
|
8913
|
-
console.log(`
|
|
9415
|
+
console.log(` ${c2.yellow}○${c2.reset} Could not create symlink`);
|
|
8914
9416
|
}
|
|
8915
|
-
} else
|
|
8916
|
-
|
|
8917
|
-
|
|
8918
|
-
op.completeStep("create_claude_symlink");
|
|
8919
|
-
op.addStep("create_claude_md");
|
|
8920
|
-
op.startStep("create_claude_md");
|
|
8921
|
-
if (isTTY) {
|
|
8922
|
-
console.log();
|
|
8923
|
-
section("Creating CLAUDE.md");
|
|
8924
|
-
console.log(" \x1B[90mThis file tells Claude Code about your Datacore system.\x1B[0m");
|
|
8925
|
-
console.log(" \x1B[90mIt auto-loads when you run `claude` in ~/Data.\x1B[0m");
|
|
8926
|
-
console.log();
|
|
9417
|
+
} else {
|
|
9418
|
+
if (isTTY)
|
|
9419
|
+
console.log(` ${c2.green}✓${c2.reset} Found existing .claude/`);
|
|
8927
9420
|
}
|
|
8928
|
-
const claudeMd =
|
|
8929
|
-
const claudeBaseMd =
|
|
8930
|
-
if (!
|
|
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();
|
|
8931
9425
|
writeFileSync4(claudeBaseMd, `# Datacore
|
|
8932
9426
|
|
|
8933
9427
|
AI-powered second brain built on GTD methodology.
|
|
@@ -8938,16 +9432,24 @@ AI-powered second brain built on GTD methodology.
|
|
|
8938
9432
|
cd ~/Data && claude
|
|
8939
9433
|
\`\`\`
|
|
8940
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
|
+
|
|
8941
9443
|
## Commands
|
|
8942
9444
|
|
|
8943
|
-
-
|
|
8944
|
-
-
|
|
8945
|
-
-
|
|
9445
|
+
- \`/today\` - Daily briefing with priorities
|
|
9446
|
+
- \`/tomorrow\` - End-of-day wrap-up
|
|
9447
|
+
- \`/sync\` - Sync all repos
|
|
8946
9448
|
- \`datacore doctor\` - Check system health
|
|
8947
9449
|
|
|
8948
9450
|
## Spaces
|
|
8949
9451
|
|
|
8950
|
-
${
|
|
9452
|
+
${allSpaces.map((s) => `- ${s.name}`).join(`
|
|
8951
9453
|
`) || "- 0-personal"}
|
|
8952
9454
|
|
|
8953
9455
|
## Documentation
|
|
@@ -8956,30 +9458,47 @@ See .datacore/specs/ for detailed documentation.
|
|
|
8956
9458
|
`);
|
|
8957
9459
|
result.created.push(claudeBaseMd);
|
|
8958
9460
|
if (isTTY)
|
|
8959
|
-
console.log(`
|
|
8960
|
-
} else
|
|
8961
|
-
|
|
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`);
|
|
8962
9465
|
}
|
|
8963
|
-
|
|
9466
|
+
if (isTTY)
|
|
9467
|
+
console.log();
|
|
9468
|
+
op.completeStep("create_claude_symlink");
|
|
8964
9469
|
result.success = true;
|
|
8965
9470
|
result.nextSteps = [
|
|
8966
|
-
"
|
|
8967
|
-
"
|
|
9471
|
+
"cd ~/Data && claude",
|
|
9472
|
+
"Add tasks to 0-personal/org/inbox.org",
|
|
9473
|
+
"Run /today for your first daily briefing"
|
|
8968
9474
|
];
|
|
8969
9475
|
if (isTTY) {
|
|
8970
|
-
console.log();
|
|
8971
9476
|
console.log(INIT_COMPLETE);
|
|
8972
9477
|
console.log();
|
|
8973
|
-
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}`);
|
|
8974
9494
|
console.log();
|
|
8975
|
-
console.log(
|
|
8976
|
-
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}`);
|
|
8977
9497
|
console.log();
|
|
8978
|
-
console.log(
|
|
8979
|
-
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}`);
|
|
8980
9500
|
console.log();
|
|
8981
|
-
console.log(
|
|
8982
|
-
console.log(" \x1B[90mYour GTD capture inbox - process daily\x1B[0m");
|
|
9501
|
+
console.log(` ${c2.dim}Run 'datacore doctor' anytime to check system health.${c2.reset}`);
|
|
8983
9502
|
console.log();
|
|
8984
9503
|
}
|
|
8985
9504
|
op.complete();
|
|
@@ -8990,150 +9509,14 @@ See .datacore/specs/ for detailed documentation.
|
|
|
8990
9509
|
return result;
|
|
8991
9510
|
}
|
|
8992
9511
|
|
|
8993
|
-
// src/lib/module.ts
|
|
8994
|
-
import { existsSync as existsSync7, readdirSync as readdirSync2, readFileSync as readFileSync4, rmSync } from "fs";
|
|
8995
|
-
import { join as join7, basename as basename3 } from "path";
|
|
8996
|
-
import { execSync as execSync4 } from "child_process";
|
|
8997
|
-
var DATA_DIR5 = join7(process.env.HOME || "~", "Data");
|
|
8998
|
-
var MODULES_DIR = join7(DATA_DIR5, ".datacore", "modules");
|
|
8999
|
-
function listModules() {
|
|
9000
|
-
if (!existsSync7(MODULES_DIR)) {
|
|
9001
|
-
return [];
|
|
9002
|
-
}
|
|
9003
|
-
const entries = readdirSync2(MODULES_DIR, { withFileTypes: true });
|
|
9004
|
-
const modules = [];
|
|
9005
|
-
for (const entry of entries) {
|
|
9006
|
-
if (!entry.isDirectory())
|
|
9007
|
-
continue;
|
|
9008
|
-
if (entry.name.startsWith("."))
|
|
9009
|
-
continue;
|
|
9010
|
-
const modulePath = join7(MODULES_DIR, entry.name);
|
|
9011
|
-
const info2 = getModuleInfo(modulePath);
|
|
9012
|
-
if (info2) {
|
|
9013
|
-
modules.push(info2);
|
|
9014
|
-
}
|
|
9015
|
-
}
|
|
9016
|
-
return modules;
|
|
9017
|
-
}
|
|
9018
|
-
function getModuleInfo(modulePath) {
|
|
9019
|
-
const name = basename3(modulePath);
|
|
9020
|
-
const yamlPath = join7(modulePath, "module.yaml");
|
|
9021
|
-
const ymlPath = join7(modulePath, "module.yml");
|
|
9022
|
-
const configPath = existsSync7(yamlPath) ? yamlPath : existsSync7(ymlPath) ? ymlPath : null;
|
|
9023
|
-
let version;
|
|
9024
|
-
let description;
|
|
9025
|
-
if (configPath) {
|
|
9026
|
-
try {
|
|
9027
|
-
const { parse: parse2 } = require_dist();
|
|
9028
|
-
const content = readFileSync4(configPath, "utf-8");
|
|
9029
|
-
const config = parse2(content);
|
|
9030
|
-
version = config.version;
|
|
9031
|
-
description = config.description;
|
|
9032
|
-
} catch {}
|
|
9033
|
-
}
|
|
9034
|
-
const agentsDir = join7(modulePath, "agents");
|
|
9035
|
-
const agents = [];
|
|
9036
|
-
if (existsSync7(agentsDir)) {
|
|
9037
|
-
const agentFiles = readdirSync2(agentsDir);
|
|
9038
|
-
for (const file of agentFiles) {
|
|
9039
|
-
if (file.endsWith(".md")) {
|
|
9040
|
-
agents.push(file.replace(".md", ""));
|
|
9041
|
-
}
|
|
9042
|
-
}
|
|
9043
|
-
}
|
|
9044
|
-
const commandsDir = join7(modulePath, "commands");
|
|
9045
|
-
const commands = [];
|
|
9046
|
-
if (existsSync7(commandsDir)) {
|
|
9047
|
-
const cmdFiles = readdirSync2(commandsDir);
|
|
9048
|
-
for (const file of cmdFiles) {
|
|
9049
|
-
if (file.endsWith(".md")) {
|
|
9050
|
-
commands.push(file.replace(".md", ""));
|
|
9051
|
-
}
|
|
9052
|
-
}
|
|
9053
|
-
}
|
|
9054
|
-
return {
|
|
9055
|
-
name,
|
|
9056
|
-
path: modulePath,
|
|
9057
|
-
version,
|
|
9058
|
-
description,
|
|
9059
|
-
agents,
|
|
9060
|
-
commands
|
|
9061
|
-
};
|
|
9062
|
-
}
|
|
9063
|
-
function installModule(source) {
|
|
9064
|
-
if (!existsSync7(MODULES_DIR)) {
|
|
9065
|
-
const { mkdirSync: mkdirSync5 } = __require("fs");
|
|
9066
|
-
mkdirSync5(MODULES_DIR, { recursive: true });
|
|
9067
|
-
}
|
|
9068
|
-
let name;
|
|
9069
|
-
let isGit = false;
|
|
9070
|
-
if (source.includes("github.com") || source.startsWith("git@") || source.endsWith(".git")) {
|
|
9071
|
-
isGit = true;
|
|
9072
|
-
const match = source.match(/([^/]+?)(?:\.git)?$/);
|
|
9073
|
-
name = match?.[1] ?? source.split("/").pop() ?? "unknown";
|
|
9074
|
-
name = name.replace(/^module-/, "");
|
|
9075
|
-
} else if (source.startsWith("@")) {
|
|
9076
|
-
name = source.split("/").pop()?.replace(/^datacore-/, "") ?? "unknown";
|
|
9077
|
-
} else {
|
|
9078
|
-
name = source.replace(/^datacore-/, "").replace(/^module-/, "");
|
|
9079
|
-
}
|
|
9080
|
-
const modulePath = join7(MODULES_DIR, name);
|
|
9081
|
-
if (existsSync7(modulePath)) {
|
|
9082
|
-
throw new Error(`Module already installed: ${name}`);
|
|
9083
|
-
}
|
|
9084
|
-
if (isGit) {
|
|
9085
|
-
execSync4(`git clone ${source} "${modulePath}"`, { stdio: "pipe" });
|
|
9086
|
-
} else {
|
|
9087
|
-
const gitUrl = `https://github.com/datacore/module-${name}.git`;
|
|
9088
|
-
try {
|
|
9089
|
-
execSync4(`git clone ${gitUrl} "${modulePath}"`, { stdio: "pipe" });
|
|
9090
|
-
} catch {
|
|
9091
|
-
throw new Error(`Could not install module: ${source}`);
|
|
9092
|
-
}
|
|
9093
|
-
}
|
|
9094
|
-
const info2 = getModuleInfo(modulePath);
|
|
9095
|
-
if (!info2) {
|
|
9096
|
-
rmSync(modulePath, { recursive: true, force: true });
|
|
9097
|
-
throw new Error("Invalid module: missing module.yaml");
|
|
9098
|
-
}
|
|
9099
|
-
return info2;
|
|
9100
|
-
}
|
|
9101
|
-
function updateModules(name) {
|
|
9102
|
-
const modules = listModules();
|
|
9103
|
-
const results = [];
|
|
9104
|
-
const toUpdate = name ? modules.filter((m) => m.name === name) : modules;
|
|
9105
|
-
for (const mod of toUpdate) {
|
|
9106
|
-
try {
|
|
9107
|
-
const gitDir = join7(mod.path, ".git");
|
|
9108
|
-
if (existsSync7(gitDir)) {
|
|
9109
|
-
execSync4("git pull", { cwd: mod.path, stdio: "pipe" });
|
|
9110
|
-
results.push({ name: mod.name, updated: true });
|
|
9111
|
-
} else {
|
|
9112
|
-
results.push({ name: mod.name, updated: false, error: "Not a git repository" });
|
|
9113
|
-
}
|
|
9114
|
-
} catch (err) {
|
|
9115
|
-
results.push({ name: mod.name, updated: false, error: err.message });
|
|
9116
|
-
}
|
|
9117
|
-
}
|
|
9118
|
-
return results;
|
|
9119
|
-
}
|
|
9120
|
-
function removeModule(name) {
|
|
9121
|
-
const modulePath = join7(MODULES_DIR, name);
|
|
9122
|
-
if (!existsSync7(modulePath)) {
|
|
9123
|
-
return false;
|
|
9124
|
-
}
|
|
9125
|
-
rmSync(modulePath, { recursive: true, force: true });
|
|
9126
|
-
return true;
|
|
9127
|
-
}
|
|
9128
|
-
|
|
9129
9512
|
// src/lib/snapshot.ts
|
|
9130
9513
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
9131
|
-
import { existsSync as existsSync8, readFileSync as
|
|
9514
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5 } from "fs";
|
|
9132
9515
|
import { execSync as execSync5 } from "child_process";
|
|
9133
9516
|
import { join as join8 } from "path";
|
|
9134
9517
|
var DATA_DIR6 = join8(process.env.HOME || "~", "Data");
|
|
9135
9518
|
var LOCK_FILE = join8(DATA_DIR6, "datacore.lock.yaml");
|
|
9136
|
-
var CLI_VERSION = "1.0.
|
|
9519
|
+
var CLI_VERSION = "1.0.5";
|
|
9137
9520
|
function getGitInfo(path) {
|
|
9138
9521
|
if (!existsSync8(join8(path, ".git"))) {
|
|
9139
9522
|
return {};
|
|
@@ -9199,7 +9582,7 @@ function createSnapshot(options = {}) {
|
|
|
9199
9582
|
const settingsPath = join8(DATA_DIR6, ".datacore", "settings.yaml");
|
|
9200
9583
|
if (existsSync8(settingsPath)) {
|
|
9201
9584
|
try {
|
|
9202
|
-
const content =
|
|
9585
|
+
const content = readFileSync4(settingsPath, "utf-8");
|
|
9203
9586
|
snapshot.settings = import_yaml2.parse(content);
|
|
9204
9587
|
} catch {}
|
|
9205
9588
|
}
|
|
@@ -9220,7 +9603,7 @@ function loadSnapshot(path) {
|
|
|
9220
9603
|
return null;
|
|
9221
9604
|
}
|
|
9222
9605
|
try {
|
|
9223
|
-
const content =
|
|
9606
|
+
const content = readFileSync4(lockPath, "utf-8");
|
|
9224
9607
|
return import_yaml2.parse(content);
|
|
9225
9608
|
} catch {
|
|
9226
9609
|
return null;
|
|
@@ -9352,7 +9735,7 @@ function restoreFromSnapshot(snapshot, options = {}) {
|
|
|
9352
9735
|
}
|
|
9353
9736
|
|
|
9354
9737
|
// src/index.ts
|
|
9355
|
-
var VERSION = "1.0.
|
|
9738
|
+
var VERSION = "1.0.5";
|
|
9356
9739
|
var args = process.argv.slice(2);
|
|
9357
9740
|
var parsed = parseArgs(args);
|
|
9358
9741
|
async function handleMeta(command, cmdArgs, flags, format) {
|
|
@@ -9400,8 +9783,8 @@ async function handleMeta(command, cmdArgs, flags, format) {
|
|
|
9400
9783
|
}
|
|
9401
9784
|
console.log();
|
|
9402
9785
|
console.log("Next steps:");
|
|
9403
|
-
for (const
|
|
9404
|
-
console.log(` → ${
|
|
9786
|
+
for (const step of result.nextSteps) {
|
|
9787
|
+
console.log(` → ${step}`);
|
|
9405
9788
|
}
|
|
9406
9789
|
} else {
|
|
9407
9790
|
error("Initialization failed");
|