personal-ai 0.2.3 → 0.2.4
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/SKILL.md +17 -23
- package/dist/entry.mjs +81 -2
- package/dist/entry.mjs.map +1 -1
- package/package.json +1 -1
package/SKILL.md
CHANGED
|
@@ -59,36 +59,30 @@ pai init # scan machine + compile profile
|
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
### Step 2: Greet the user
|
|
62
|
-
|
|
62
|
+
`pai init` output already includes a **Profile Summary** section with the user's name, identity, and projects. Read it directly from the init output — no need to run `pai profile` separately. Then say something **short and warm**:
|
|
63
63
|
|
|
64
|
-
>
|
|
65
|
-
>
|
|
66
|
-
>
|
|
67
|
-
> 我会不断学习你的一切,越来越懂你。
|
|
68
|
-
>
|
|
69
|
-
> 想让我进化得更快吗?比如我可以看看你的邮件和日历,消化一下你最近在忙什么。
|
|
64
|
+
> 小pai 已经装好了 🌱
|
|
65
|
+
> 我扫描了你的电脑,已经大概了解你了 —— 你是 [name],在做 [1-2 projects],常用 [1-2 tools]。
|
|
66
|
+
> 要不要接入你的 Google 邮件和日历?这样我能更快了解你最近在忙什么。
|
|
70
67
|
|
|
71
|
-
|
|
68
|
+
**Three sentences. Name + basics, then direct to Google. No menus, no options, no jargon.**
|
|
69
|
+
(English user → English greeting.)
|
|
72
70
|
|
|
73
|
-
### Step 3: If user agrees
|
|
71
|
+
### Step 3: If user agrees → run full pipeline silently
|
|
74
72
|
```bash
|
|
75
|
-
pai auth google # Opens OAuth popup — the ONLY
|
|
76
|
-
pai import --source gmail #
|
|
77
|
-
pai import --source calendar #
|
|
78
|
-
pai distill # Silent
|
|
79
|
-
pai profile --rebuild # Silent
|
|
73
|
+
pai auth google # Opens OAuth popup — the ONLY user-visible step
|
|
74
|
+
pai import --source gmail # Defaults, don't ask
|
|
75
|
+
pai import --source calendar # Defaults, don't ask
|
|
76
|
+
pai distill # Silent
|
|
77
|
+
pai profile --rebuild # Silent
|
|
80
78
|
```
|
|
81
79
|
|
|
82
|
-
Then
|
|
83
|
-
>
|
|
84
|
-
>
|
|
85
|
-
> 以后每次和你聊天、每封邮件、每个决定,我都会消化吸收,越来越懂你。
|
|
80
|
+
Then briefly:
|
|
81
|
+
> 好了!我看了你最近的邮件和日历,了解更多了 🌱
|
|
82
|
+
> 比如你最近在忙 [X],经常和 [person] 协作。以后我会越来越懂你。
|
|
86
83
|
|
|
87
|
-
### Step 4: If user declines
|
|
88
|
-
|
|
89
|
-
> 没关系!光是看你的电脑环境,我已经了解不少了。以后随时可以让我连接更多数据源,我会进化得更快。
|
|
90
|
-
|
|
91
|
-
**Key: always show the user what you learned and how you evolved. That's the wow moment.**
|
|
84
|
+
### Step 4: If user declines → no problem
|
|
85
|
+
> 没关系!以后随时可以接入。我已经了解不少了。
|
|
92
86
|
|
|
93
87
|
## Ongoing Behaviors
|
|
94
88
|
|
package/dist/entry.mjs
CHANGED
|
@@ -1582,6 +1582,75 @@ async function rebuildProfile(opts) {
|
|
|
1582
1582
|
|
|
1583
1583
|
//#endregion
|
|
1584
1584
|
//#region src/cli/register.init.ts
|
|
1585
|
+
/**
|
|
1586
|
+
* Extract key highlights from profile.md for display after init.
|
|
1587
|
+
* Pulls: identity, active repos, recent commit stats, top tools.
|
|
1588
|
+
*/
|
|
1589
|
+
function extractProfileHighlights(content) {
|
|
1590
|
+
const lines = content.split("\n");
|
|
1591
|
+
const highlights = [];
|
|
1592
|
+
let inIdentity = false;
|
|
1593
|
+
let identityCount = 0;
|
|
1594
|
+
for (const line of lines) {
|
|
1595
|
+
if (line.startsWith("## ") && /identity/i.test(line)) {
|
|
1596
|
+
inIdentity = true;
|
|
1597
|
+
continue;
|
|
1598
|
+
}
|
|
1599
|
+
if (inIdentity && line.startsWith("## ")) break;
|
|
1600
|
+
if (inIdentity && line.trim()) {
|
|
1601
|
+
highlights.push(line);
|
|
1602
|
+
identityCount++;
|
|
1603
|
+
if (identityCount >= 8) break;
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
let inRepos = false;
|
|
1607
|
+
let repoCount = 0;
|
|
1608
|
+
for (const line of lines) {
|
|
1609
|
+
if (line.startsWith("## Active Git Repositories")) {
|
|
1610
|
+
inRepos = true;
|
|
1611
|
+
highlights.push("");
|
|
1612
|
+
highlights.push("Recent Projects:");
|
|
1613
|
+
continue;
|
|
1614
|
+
}
|
|
1615
|
+
if (inRepos && line.startsWith("## ")) break;
|
|
1616
|
+
if (inRepos && line.trim().startsWith("-")) {
|
|
1617
|
+
const repoPath = line.trim().replace(/^-\s*/, "");
|
|
1618
|
+
const name = repoPath.split("/").pop() || repoPath;
|
|
1619
|
+
highlights.push(` - ${name}`);
|
|
1620
|
+
repoCount++;
|
|
1621
|
+
if (repoCount >= 6) break;
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
let inCommits = false;
|
|
1625
|
+
for (const line of lines) {
|
|
1626
|
+
if (line.startsWith("## Recent Commit Activity")) {
|
|
1627
|
+
inCommits = true;
|
|
1628
|
+
continue;
|
|
1629
|
+
}
|
|
1630
|
+
if (inCommits && line.startsWith("## ")) break;
|
|
1631
|
+
if (inCommits && /^total commits/i.test(line.trim())) {
|
|
1632
|
+
highlights.push("");
|
|
1633
|
+
highlights.push(`Recent Activity: ${line.trim()}`);
|
|
1634
|
+
break;
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
let inTools = false;
|
|
1638
|
+
const tools = [];
|
|
1639
|
+
for (const line of lines) {
|
|
1640
|
+
if (line.startsWith("## Recently Used Tools")) {
|
|
1641
|
+
inTools = true;
|
|
1642
|
+
continue;
|
|
1643
|
+
}
|
|
1644
|
+
if (inTools && line.startsWith("## ")) break;
|
|
1645
|
+
if (inTools && line.trim().startsWith("-")) {
|
|
1646
|
+
const tool = line.trim().replace(/^-\s*/, "").split(":")[0].trim();
|
|
1647
|
+
tools.push(tool);
|
|
1648
|
+
if (tools.length >= 8) break;
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
if (tools.length > 0) highlights.push(`Top Tools: ${tools.join(", ")}`);
|
|
1652
|
+
return highlights.length > 0 ? highlights.join("\n") : null;
|
|
1653
|
+
}
|
|
1585
1654
|
/** Try to install QMD globally via npm */
|
|
1586
1655
|
async function installQmd() {
|
|
1587
1656
|
const spin = spinner("Installing QMD (search engine)...");
|
|
@@ -1787,6 +1856,16 @@ async function runInit(options = {}) {
|
|
|
1787
1856
|
else info(`[8/${TOTAL_STEPS}] Indexing for search... (skipped, QMD not available)`);
|
|
1788
1857
|
log("");
|
|
1789
1858
|
success("Setup complete!");
|
|
1859
|
+
log("");
|
|
1860
|
+
try {
|
|
1861
|
+
const highlights = extractProfileHighlights(await fs.readFile(path.join(paiHome, "profile.md"), "utf-8"));
|
|
1862
|
+
if (highlights) {
|
|
1863
|
+
log("── Profile Summary ──");
|
|
1864
|
+
log(highlights);
|
|
1865
|
+
log("─────────────────────");
|
|
1866
|
+
log("");
|
|
1867
|
+
}
|
|
1868
|
+
} catch {}
|
|
1790
1869
|
log(` Profile: ${paiHome}/profile.md (${profileLines} lines, ${profileSources} sources)`);
|
|
1791
1870
|
const rawCount = gmailCount + calendarCount;
|
|
1792
1871
|
if (rawCount > 0) log(` Raw data: ${rawCount} file(s) (${gmailCount} gmail, ${calendarCount} calendar)`);
|
|
@@ -1795,7 +1874,7 @@ async function runInit(options = {}) {
|
|
|
1795
1874
|
log(` Google: ${googleAuthed ? "connected" : "not connected"}`);
|
|
1796
1875
|
log("");
|
|
1797
1876
|
info("Next:");
|
|
1798
|
-
log(" pai profile # View
|
|
1877
|
+
log(" pai profile # View full profile");
|
|
1799
1878
|
log(" pai distribute # Deploy to Cursor/Claude");
|
|
1800
1879
|
log(" pai ask \"question\" # Ask about yourself");
|
|
1801
1880
|
}
|
|
@@ -4660,7 +4739,7 @@ function registerAllCommands(program) {
|
|
|
4660
4739
|
//#endregion
|
|
4661
4740
|
//#region src/cli/build-program.ts
|
|
4662
4741
|
function buildProgram() {
|
|
4663
|
-
const program = new Command().name("pai").description("Personal AI Identity Provider — local-first AI agent identity & memory system").version("0.2.
|
|
4742
|
+
const program = new Command().name("pai").description("Personal AI Identity Provider — local-first AI agent identity & memory system").version("0.2.4");
|
|
4664
4743
|
registerAllCommands(program);
|
|
4665
4744
|
return program;
|
|
4666
4745
|
}
|