@tdsoft-tech/aikit 0.1.30 → 0.1.31
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/CHANGELOG.md +14 -0
- package/README.md +28 -17
- package/dist/cli.js +1012 -394
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +384 -67
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.js +104 -67
- package/dist/mcp-server.js.map +1 -1
- package/package.json +3 -1
package/dist/index.d.ts
CHANGED
|
@@ -943,6 +943,11 @@ declare class AntiHallucination {
|
|
|
943
943
|
private patternToRegex;
|
|
944
944
|
}
|
|
945
945
|
|
|
946
|
+
/**
|
|
947
|
+
* Non-blocking public API for CLI
|
|
948
|
+
*/
|
|
949
|
+
declare function checkForUpdatesAsync(): Promise<void>;
|
|
950
|
+
|
|
946
951
|
/**
|
|
947
952
|
* Simple logger with colored output
|
|
948
953
|
*/
|
|
@@ -1038,4 +1043,4 @@ declare const paths: {
|
|
|
1038
1043
|
*/
|
|
1039
1044
|
declare function getVersion(): string;
|
|
1040
1045
|
|
|
1041
|
-
export { type AIKitConfig, type Agent, AgentManager, type AgentType, AntiHallucination, BeadsIntegration, type Command, CommandRunner, Config, type Memory, MemoryManager, type Plugin, type PluginEvent, PluginSystem, type Skill, SkillEngine, type Tool, ToolRegistry, getVersion as VERSION, defineTool, loadConfig, logger, paths };
|
|
1046
|
+
export { type AIKitConfig, type Agent, AgentManager, type AgentType, AntiHallucination, BeadsIntegration, type Command, CommandRunner, Config, type Memory, MemoryManager, type Plugin, type PluginEvent, PluginSystem, type Skill, SkillEngine, type Tool, ToolRegistry, getVersion as VERSION, checkForUpdatesAsync, defineTool, loadConfig, logger, paths };
|
package/dist/index.js
CHANGED
|
@@ -153,6 +153,7 @@ var init_paths = __esm({
|
|
|
153
153
|
import { readFileSync } from "fs";
|
|
154
154
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
155
155
|
import { dirname, join as join2 } from "path";
|
|
156
|
+
import { compare, gt, valid } from "semver";
|
|
156
157
|
function getVersion() {
|
|
157
158
|
try {
|
|
158
159
|
const __filename2 = fileURLToPath2(import.meta.url);
|
|
@@ -165,6 +166,9 @@ function getVersion() {
|
|
|
165
166
|
return "0.0.0";
|
|
166
167
|
}
|
|
167
168
|
}
|
|
169
|
+
function isGreaterThan(v1, v2) {
|
|
170
|
+
return gt(v1, v2);
|
|
171
|
+
}
|
|
168
172
|
var init_version = __esm({
|
|
169
173
|
"src/utils/version.ts"() {
|
|
170
174
|
"use strict";
|
|
@@ -3459,14 +3463,14 @@ Total: 2 checkpoints
|
|
|
3459
3463
|
init_esm_shims();
|
|
3460
3464
|
var SESSION_COMMANDS = [
|
|
3461
3465
|
{
|
|
3462
|
-
name: "session
|
|
3466
|
+
name: "session-start",
|
|
3463
3467
|
description: "Start a new development session",
|
|
3464
3468
|
category: "session",
|
|
3465
|
-
usage: "/session
|
|
3469
|
+
usage: "/session-start [name]",
|
|
3466
3470
|
examples: [
|
|
3467
|
-
"/session
|
|
3468
|
-
"/session
|
|
3469
|
-
'/session
|
|
3471
|
+
"/session-start",
|
|
3472
|
+
"/session-start authentication-refactor",
|
|
3473
|
+
'/session-start "Add user profile feature"'
|
|
3470
3474
|
],
|
|
3471
3475
|
content: `Start a new development session to track your work.
|
|
3472
3476
|
|
|
@@ -3474,47 +3478,70 @@ var SESSION_COMMANDS = [
|
|
|
3474
3478
|
|
|
3475
3479
|
Session name: $ARGUMENTS
|
|
3476
3480
|
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3481
|
+
**IMPORTANT - Scope Rules:**
|
|
3482
|
+
- Sessions are scoped to the CURRENT working directory
|
|
3483
|
+
- AIKit will NOT search parent directories for .aikit
|
|
3484
|
+
- If .aikit doesn't exist in current directory, you MUST run 'aikit init' first
|
|
3485
|
+
- Each directory needs its own .aikit if you want separate session tracking
|
|
3486
|
+
|
|
3487
|
+
1. **Check Current Directory:**
|
|
3488
|
+
- Verify .aikit exists in current directory (process.cwd())
|
|
3489
|
+
- If not, inform user to run 'aikit init' first
|
|
3490
|
+
- DO NOT search parent directories
|
|
3482
3491
|
|
|
3483
|
-
2. **
|
|
3492
|
+
2. **Create Session:**
|
|
3493
|
+
- Generate session ID with timestamp
|
|
3494
|
+
- Create session file in .aikit/sessions/ (current directory only)
|
|
3495
|
+
- Determine session tracker file:
|
|
3496
|
+
* Try 'tty' command to get terminal identifier
|
|
3497
|
+
* If 'tty' works, use .aikit/sessions/.current-<sanitized_tty>-session
|
|
3498
|
+
(replace '/' with '-' in TTY path)
|
|
3499
|
+
* If 'tty' fails with "not a tty", get parent PID using: ps -o ppid= -p $$
|
|
3500
|
+
Use .aikit/sessions/.current-ppid-<PPID>-session
|
|
3501
|
+
(each Claude Code window has unique PPID)
|
|
3502
|
+
- Write session ID to the tracker file
|
|
3503
|
+
- **Capture initial git state (scoped to current directory):**
|
|
3504
|
+
* First check if .git exists in CURRENT directory (process.cwd())
|
|
3505
|
+
* ONLY capture git state if .git exists in current directory
|
|
3506
|
+
* DO NOT search parent directories for git repo
|
|
3507
|
+
* If no .git in current directory, skip git state capture
|
|
3508
|
+
|
|
3509
|
+
3. **Set Goals:**
|
|
3484
3510
|
- Ask user for session goals if not provided
|
|
3485
3511
|
- Document what you want to accomplish
|
|
3486
3512
|
- Link to Beads task if active
|
|
3487
3513
|
|
|
3488
|
-
|
|
3514
|
+
4. **Session Started:**
|
|
3489
3515
|
- Session ID: YYYY-MM-DD-HHMM[-name]
|
|
3490
3516
|
- Status: active
|
|
3491
3517
|
- Ready for updates
|
|
3492
3518
|
|
|
3493
3519
|
## What Gets Tracked
|
|
3494
3520
|
- Session start time
|
|
3495
|
-
- Git branch and commits
|
|
3496
|
-
- Modified files
|
|
3521
|
+
- Git branch and commits (ONLY if .git exists in current directory)
|
|
3522
|
+
- Modified files (ONLY if .git exists in current directory)
|
|
3497
3523
|
- Progress notes
|
|
3498
3524
|
- Linked Beads task
|
|
3499
3525
|
|
|
3500
3526
|
## Session File Location
|
|
3501
|
-
.aikit/sessions/YYYY-MM-DD-HHMM[-name].md
|
|
3527
|
+
Current directory: .aikit/sessions/YYYY-MM-DD-HHMM[-name].md
|
|
3528
|
+
(Always relative to process.cwd(), never parent directories)
|
|
3502
3529
|
|
|
3503
3530
|
## Examples
|
|
3504
3531
|
|
|
3505
3532
|
Start unnamed session:
|
|
3506
3533
|
\`\`\`
|
|
3507
|
-
/session
|
|
3534
|
+
/session-start
|
|
3508
3535
|
\`\`\`
|
|
3509
3536
|
|
|
3510
3537
|
Start with descriptive name:
|
|
3511
3538
|
\`\`\`
|
|
3512
|
-
/session
|
|
3539
|
+
/session-start auth-refactor
|
|
3513
3540
|
\`\`\`
|
|
3514
3541
|
|
|
3515
3542
|
Start with goal:
|
|
3516
3543
|
\`\`\`
|
|
3517
|
-
/session
|
|
3544
|
+
/session-start "Implement OAuth 2.0"
|
|
3518
3545
|
Goals:
|
|
3519
3546
|
- Add Google OAuth
|
|
3520
3547
|
- Add JWT token handling
|
|
@@ -3523,18 +3550,18 @@ Goals:
|
|
|
3523
3550
|
## Notes
|
|
3524
3551
|
- Session files are markdown with frontmatter
|
|
3525
3552
|
- Sessions persist across AI conversations
|
|
3526
|
-
- Use /session
|
|
3527
|
-
- Use /session
|
|
3553
|
+
- Use /session-update to add progress notes
|
|
3554
|
+
- Use /session-end to close and summarize`
|
|
3528
3555
|
},
|
|
3529
3556
|
{
|
|
3530
|
-
name: "session
|
|
3557
|
+
name: "session-update",
|
|
3531
3558
|
description: "Add progress notes to current session",
|
|
3532
3559
|
category: "session",
|
|
3533
|
-
usage: "/session
|
|
3560
|
+
usage: "/session-update [notes]",
|
|
3534
3561
|
examples: [
|
|
3535
|
-
"/session
|
|
3536
|
-
"/session
|
|
3537
|
-
'/session
|
|
3562
|
+
"/session-update",
|
|
3563
|
+
"/session-update Fixed authentication bug",
|
|
3564
|
+
'/session-update "Added JWT middleware"'
|
|
3538
3565
|
],
|
|
3539
3566
|
content: `Update the current session with progress notes.
|
|
3540
3567
|
|
|
@@ -3543,19 +3570,28 @@ Goals:
|
|
|
3543
3570
|
Progress notes: $ARGUMENTS
|
|
3544
3571
|
|
|
3545
3572
|
1. **Check Active Session:**
|
|
3546
|
-
-
|
|
3573
|
+
- Determine session tracker file:
|
|
3574
|
+
* Try 'tty' command to get terminal identifier
|
|
3575
|
+
* If 'tty' works, read .aikit/sessions/.current-<sanitized_tty>-session
|
|
3576
|
+
* If 'tty' fails, get parent PID and read .aikit/sessions/.current-ppid-<PPID>-session
|
|
3547
3577
|
- Load session file
|
|
3548
3578
|
|
|
3549
3579
|
2. **Capture Current State:**
|
|
3550
|
-
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3580
|
+
- **IMPORTANT - Git State Scope:**
|
|
3581
|
+
* First check if .git exists in CURRENT directory (process.cwd())
|
|
3582
|
+
* ONLY capture git state if .git exists in current directory
|
|
3583
|
+
* DO NOT search parent directories for git repo
|
|
3584
|
+
* If no .git in current directory, skip git state capture
|
|
3585
|
+
- If .git exists in current directory:
|
|
3586
|
+
* Get current git branch
|
|
3587
|
+
* Count git commits
|
|
3588
|
+
* List modified files
|
|
3589
|
+
- Check active Beads task (from .beads directory if exists)
|
|
3554
3590
|
|
|
3555
3591
|
3. **Add Update:**
|
|
3556
3592
|
- Add timestamped update entry
|
|
3557
3593
|
- Include your notes (or auto-generate)
|
|
3558
|
-
- Include git state
|
|
3594
|
+
- Include git state ONLY if .git exists in current directory
|
|
3559
3595
|
- Include Beads task if active
|
|
3560
3596
|
|
|
3561
3597
|
4. **Save Session:**
|
|
@@ -3565,27 +3601,25 @@ Progress notes: $ARGUMENTS
|
|
|
3565
3601
|
## What Gets Captured
|
|
3566
3602
|
- Timestamp of update
|
|
3567
3603
|
- Your progress notes
|
|
3568
|
-
-
|
|
3569
|
-
- Number of commits
|
|
3570
|
-
- List of modified files
|
|
3604
|
+
- Git state (branch, commits, files) - ONLY if .git exists in current directory
|
|
3571
3605
|
- Active Beads task (if any)
|
|
3572
3606
|
|
|
3573
3607
|
## Examples
|
|
3574
3608
|
|
|
3575
3609
|
Auto-update (no notes):
|
|
3576
3610
|
\`\`\`
|
|
3577
|
-
/session
|
|
3611
|
+
/session-update
|
|
3578
3612
|
\`\`\`
|
|
3579
3613
|
*Auto-generates summary of recent work*
|
|
3580
3614
|
|
|
3581
3615
|
With specific notes:
|
|
3582
3616
|
\`\`\`
|
|
3583
|
-
/session
|
|
3617
|
+
/session-update Fixed Next.js params issue
|
|
3584
3618
|
\`\`\`
|
|
3585
3619
|
|
|
3586
3620
|
With detailed notes:
|
|
3587
3621
|
\`\`\`
|
|
3588
|
-
/session
|
|
3622
|
+
/session-update "Implemented OAuth flow with Google provider. Added callback handler and token validation."
|
|
3589
3623
|
\`\`\`
|
|
3590
3624
|
|
|
3591
3625
|
## Notes
|
|
@@ -3595,11 +3629,11 @@ With detailed notes:
|
|
|
3595
3629
|
- Beads task automatically linked`
|
|
3596
3630
|
},
|
|
3597
3631
|
{
|
|
3598
|
-
name: "session
|
|
3632
|
+
name: "session-end",
|
|
3599
3633
|
description: "End current session with summary",
|
|
3600
3634
|
category: "session",
|
|
3601
|
-
usage: "/session
|
|
3602
|
-
examples: ["/session
|
|
3635
|
+
usage: "/session-end",
|
|
3636
|
+
examples: ["/session-end"],
|
|
3603
3637
|
content: `End the current session and generate a comprehensive summary.
|
|
3604
3638
|
|
|
3605
3639
|
## Workflow
|
|
@@ -3629,7 +3663,10 @@ With detailed notes:
|
|
|
3629
3663
|
- Mark session as ended
|
|
3630
3664
|
- Set end time
|
|
3631
3665
|
- Save session file
|
|
3632
|
-
-
|
|
3666
|
+
- Determine session tracker file:
|
|
3667
|
+
* Try 'tty' command to get terminal identifier
|
|
3668
|
+
* If 'tty' works, clear .aikit/sessions/.current-<sanitized_tty>-session
|
|
3669
|
+
* If 'tty' fails, get parent PID and clear .aikit/sessions/.current-ppid-<PPID>-session
|
|
3633
3670
|
|
|
3634
3671
|
## Summary Includes
|
|
3635
3672
|
|
|
@@ -3684,17 +3721,20 @@ Lessons:
|
|
|
3684
3721
|
- Can start new session after ending`
|
|
3685
3722
|
},
|
|
3686
3723
|
{
|
|
3687
|
-
name: "session
|
|
3724
|
+
name: "session-current",
|
|
3688
3725
|
description: "Show current active session",
|
|
3689
3726
|
category: "session",
|
|
3690
|
-
usage: "/session
|
|
3691
|
-
examples: ["/session
|
|
3727
|
+
usage: "/session-current",
|
|
3728
|
+
examples: ["/session-current"],
|
|
3692
3729
|
content: `Display information about the current active session.
|
|
3693
3730
|
|
|
3694
3731
|
## Workflow
|
|
3695
3732
|
|
|
3696
3733
|
1. **Check Active Session:**
|
|
3697
|
-
-
|
|
3734
|
+
- Determine session tracker file:
|
|
3735
|
+
* Try 'tty' command to get terminal identifier
|
|
3736
|
+
* If 'tty' works, read .aikit/sessions/.current-<sanitized_tty>-session
|
|
3737
|
+
* If 'tty' fails, get parent PID and read .aikit/sessions/.current-ppid-<PPID>-session
|
|
3698
3738
|
- Load session data
|
|
3699
3739
|
|
|
3700
3740
|
2. **Display Session Info:**
|
|
@@ -3734,8 +3774,8 @@ Beads Task:
|
|
|
3734
3774
|
- bead-001 (in-progress)
|
|
3735
3775
|
|
|
3736
3776
|
Commands:
|
|
3737
|
-
/session
|
|
3738
|
-
/session
|
|
3777
|
+
/session-update [notes] - Add progress
|
|
3778
|
+
/session-end - Close session
|
|
3739
3779
|
\`\`\`
|
|
3740
3780
|
|
|
3741
3781
|
## Notes
|
|
@@ -3744,18 +3784,18 @@ Commands:
|
|
|
3744
3784
|
- Displays recent progress`
|
|
3745
3785
|
},
|
|
3746
3786
|
{
|
|
3747
|
-
name: "session
|
|
3787
|
+
name: "session-list",
|
|
3748
3788
|
description: "List all sessions",
|
|
3749
3789
|
category: "session",
|
|
3750
|
-
usage: "/session
|
|
3751
|
-
examples: ["/session
|
|
3790
|
+
usage: "/session-list",
|
|
3791
|
+
examples: ["/session-list"],
|
|
3752
3792
|
content: `List all development sessions with summaries.
|
|
3753
3793
|
|
|
3754
3794
|
## Workflow
|
|
3755
3795
|
|
|
3756
3796
|
1. **Scan Sessions Directory:**
|
|
3757
3797
|
- Find all .md files in .aikit/sessions/
|
|
3758
|
-
- Exclude .current
|
|
3798
|
+
- Exclude all .current-*-session files (terminal trackers)
|
|
3759
3799
|
|
|
3760
3800
|
2. **Sort by Date:**
|
|
3761
3801
|
- Newest sessions first
|
|
@@ -3798,16 +3838,16 @@ Total: 3 sessions
|
|
|
3798
3838
|
- Shows both active and ended sessions
|
|
3799
3839
|
- Most recent sessions first
|
|
3800
3840
|
- Active session highlighted
|
|
3801
|
-
- Use /session
|
|
3841
|
+
- Use /session-show <id> for details`
|
|
3802
3842
|
},
|
|
3803
3843
|
{
|
|
3804
|
-
name: "session
|
|
3844
|
+
name: "session-show",
|
|
3805
3845
|
description: "Show details of a specific session",
|
|
3806
3846
|
category: "session",
|
|
3807
|
-
usage: "/session
|
|
3847
|
+
usage: "/session-show <session-id>",
|
|
3808
3848
|
examples: [
|
|
3809
|
-
"/session
|
|
3810
|
-
"/session
|
|
3849
|
+
"/session-show 2025-01-02-1430",
|
|
3850
|
+
"/session-show 2025-01-02-1430-auth-refactor"
|
|
3811
3851
|
],
|
|
3812
3852
|
content: `Display full details of a specific session.
|
|
3813
3853
|
|
|
@@ -3878,14 +3918,14 @@ Successfully refactored authentication system...
|
|
|
3878
3918
|
- Full session details displayed`
|
|
3879
3919
|
},
|
|
3880
3920
|
{
|
|
3881
|
-
name: "session
|
|
3921
|
+
name: "session-search",
|
|
3882
3922
|
description: "Search sessions by keyword",
|
|
3883
3923
|
category: "session",
|
|
3884
|
-
usage: "/session
|
|
3924
|
+
usage: "/session-search <query>",
|
|
3885
3925
|
examples: [
|
|
3886
|
-
"/session
|
|
3887
|
-
'/session
|
|
3888
|
-
"/session
|
|
3926
|
+
"/session-search oauth",
|
|
3927
|
+
'/session-search "jwt"',
|
|
3928
|
+
"/session-search authentication"
|
|
3889
3929
|
],
|
|
3890
3930
|
content: `Search for sessions matching a keyword.
|
|
3891
3931
|
|
|
@@ -3906,7 +3946,7 @@ Search query: $ARGUMENTS
|
|
|
3906
3946
|
|
|
3907
3947
|
3. **Show Actions:**
|
|
3908
3948
|
- List matching sessions
|
|
3909
|
-
- Suggest /session
|
|
3949
|
+
- Suggest /session-show for details
|
|
3910
3950
|
|
|
3911
3951
|
## Example Output
|
|
3912
3952
|
\`\`\`
|
|
@@ -3936,14 +3976,14 @@ Total: 2 matching sessions
|
|
|
3936
3976
|
- Use partial IDs too`
|
|
3937
3977
|
},
|
|
3938
3978
|
{
|
|
3939
|
-
name: "session
|
|
3979
|
+
name: "session-resume",
|
|
3940
3980
|
description: "Resume a past session (load context)",
|
|
3941
3981
|
category: "session",
|
|
3942
|
-
usage: "/session
|
|
3982
|
+
usage: "/session-resume <session-id>",
|
|
3943
3983
|
examples: [
|
|
3944
|
-
"/session
|
|
3945
|
-
"/session
|
|
3946
|
-
"/session
|
|
3984
|
+
"/session-resume latest",
|
|
3985
|
+
"/session-resume 2025-01-02-1430",
|
|
3986
|
+
"/session-resume 2025-01-02-1430-auth-refactor"
|
|
3947
3987
|
],
|
|
3948
3988
|
content: `Load context from a past session to resume work.
|
|
3949
3989
|
|
|
@@ -6163,6 +6203,282 @@ List approved dependencies here.
|
|
|
6163
6203
|
}
|
|
6164
6204
|
};
|
|
6165
6205
|
|
|
6206
|
+
// src/core/update-manager.ts
|
|
6207
|
+
init_esm_shims();
|
|
6208
|
+
init_version();
|
|
6209
|
+
import chalk2 from "chalk";
|
|
6210
|
+
|
|
6211
|
+
// src/utils/npm-client.ts
|
|
6212
|
+
init_esm_shims();
|
|
6213
|
+
import https from "https";
|
|
6214
|
+
async function getLatestVersion(packageName) {
|
|
6215
|
+
return new Promise((resolve) => {
|
|
6216
|
+
const url = `https://registry.npmjs.org/${packageName}`;
|
|
6217
|
+
https.get(url, (res) => {
|
|
6218
|
+
let data = "";
|
|
6219
|
+
res.on("data", (chunk) => {
|
|
6220
|
+
data += chunk;
|
|
6221
|
+
});
|
|
6222
|
+
res.on("end", () => {
|
|
6223
|
+
try {
|
|
6224
|
+
if (res.statusCode === 200) {
|
|
6225
|
+
const packageData = JSON.parse(data);
|
|
6226
|
+
const latestVersion = packageData["dist-tags"]?.latest;
|
|
6227
|
+
resolve(latestVersion || null);
|
|
6228
|
+
} else {
|
|
6229
|
+
resolve(null);
|
|
6230
|
+
}
|
|
6231
|
+
} catch {
|
|
6232
|
+
resolve(null);
|
|
6233
|
+
}
|
|
6234
|
+
});
|
|
6235
|
+
}).on("error", () => {
|
|
6236
|
+
resolve(null);
|
|
6237
|
+
}).setTimeout(5e3, () => {
|
|
6238
|
+
resolve(null);
|
|
6239
|
+
});
|
|
6240
|
+
});
|
|
6241
|
+
}
|
|
6242
|
+
|
|
6243
|
+
// src/utils/update-cache.ts
|
|
6244
|
+
init_esm_shims();
|
|
6245
|
+
init_paths();
|
|
6246
|
+
import { readFile as readFile8, writeFile as writeFile9, mkdir as mkdir8 } from "fs/promises";
|
|
6247
|
+
import { existsSync as existsSync5 } from "fs";
|
|
6248
|
+
import { join as join13 } from "path";
|
|
6249
|
+
var CACHE_FILE = ".update-cache.json";
|
|
6250
|
+
var DEFAULT_CACHE = {
|
|
6251
|
+
lastCheckTime: 0,
|
|
6252
|
+
lastCheckedVersion: "0.0.0",
|
|
6253
|
+
errorCount: 0
|
|
6254
|
+
};
|
|
6255
|
+
function getCachePath() {
|
|
6256
|
+
const configDir = paths.globalConfig();
|
|
6257
|
+
return join13(configDir, CACHE_FILE);
|
|
6258
|
+
}
|
|
6259
|
+
async function readCache() {
|
|
6260
|
+
try {
|
|
6261
|
+
const cachePath = getCachePath();
|
|
6262
|
+
if (!existsSync5(cachePath)) {
|
|
6263
|
+
return DEFAULT_CACHE;
|
|
6264
|
+
}
|
|
6265
|
+
const content = await readFile8(cachePath, "utf-8");
|
|
6266
|
+
const data = JSON.parse(content);
|
|
6267
|
+
return { ...DEFAULT_CACHE, ...data };
|
|
6268
|
+
} catch {
|
|
6269
|
+
return DEFAULT_CACHE;
|
|
6270
|
+
}
|
|
6271
|
+
}
|
|
6272
|
+
async function writeCache(data) {
|
|
6273
|
+
try {
|
|
6274
|
+
const cachePath = getCachePath();
|
|
6275
|
+
const configDir = paths.globalConfig();
|
|
6276
|
+
if (!existsSync5(configDir)) {
|
|
6277
|
+
await mkdir8(configDir, { recursive: true });
|
|
6278
|
+
}
|
|
6279
|
+
await writeFile9(cachePath, JSON.stringify(data, null, 2), "utf-8");
|
|
6280
|
+
} catch {
|
|
6281
|
+
}
|
|
6282
|
+
}
|
|
6283
|
+
async function setLastCheckTime(timestamp) {
|
|
6284
|
+
const cache = await readCache();
|
|
6285
|
+
cache.lastCheckTime = timestamp;
|
|
6286
|
+
await writeCache(cache);
|
|
6287
|
+
}
|
|
6288
|
+
async function setLastCheckedVersion(version) {
|
|
6289
|
+
const cache = await readCache();
|
|
6290
|
+
cache.lastCheckedVersion = version;
|
|
6291
|
+
await writeCache(cache);
|
|
6292
|
+
}
|
|
6293
|
+
async function setCompletedUpdate(version) {
|
|
6294
|
+
const cache = await readCache();
|
|
6295
|
+
cache.completedUpdate = version;
|
|
6296
|
+
cache.completedUpdateTime = Date.now();
|
|
6297
|
+
cache.errorCount = 0;
|
|
6298
|
+
cache.lastError = void 0;
|
|
6299
|
+
await writeCache(cache);
|
|
6300
|
+
}
|
|
6301
|
+
async function clearCompletedUpdate() {
|
|
6302
|
+
const cache = await readCache();
|
|
6303
|
+
cache.completedUpdate = void 0;
|
|
6304
|
+
cache.completedUpdateTime = void 0;
|
|
6305
|
+
await writeCache(cache);
|
|
6306
|
+
}
|
|
6307
|
+
async function incrementError(error) {
|
|
6308
|
+
const cache = await readCache();
|
|
6309
|
+
cache.errorCount += 1;
|
|
6310
|
+
cache.lastError = error;
|
|
6311
|
+
await writeCache(cache);
|
|
6312
|
+
}
|
|
6313
|
+
|
|
6314
|
+
// src/core/background-updater.ts
|
|
6315
|
+
init_esm_shims();
|
|
6316
|
+
init_paths();
|
|
6317
|
+
import { spawn } from "child_process";
|
|
6318
|
+
import { writeFile as writeFile10, mkdir as mkdir9 } from "fs/promises";
|
|
6319
|
+
import { join as join14 } from "path";
|
|
6320
|
+
async function spawnUpdateProcess(targetVersion) {
|
|
6321
|
+
try {
|
|
6322
|
+
const configDir = paths.globalConfig();
|
|
6323
|
+
const logsDir = join14(configDir, "logs");
|
|
6324
|
+
await mkdir9(logsDir, { recursive: true });
|
|
6325
|
+
const scriptContent = generateUpdateScript(targetVersion, logsDir);
|
|
6326
|
+
const scriptPath = join14(configDir, "update-script.js");
|
|
6327
|
+
await writeFile10(scriptPath, scriptContent, "utf-8");
|
|
6328
|
+
const child = spawn(process.execPath, [scriptPath], {
|
|
6329
|
+
detached: true,
|
|
6330
|
+
stdio: "ignore",
|
|
6331
|
+
windowsHide: true
|
|
6332
|
+
});
|
|
6333
|
+
child.unref();
|
|
6334
|
+
return true;
|
|
6335
|
+
} catch {
|
|
6336
|
+
return false;
|
|
6337
|
+
}
|
|
6338
|
+
}
|
|
6339
|
+
function generateUpdateScript(targetVersion, logsDir) {
|
|
6340
|
+
return `
|
|
6341
|
+
// AIKit Auto-Update Script
|
|
6342
|
+
// Generated automatically - DO NOT EDIT
|
|
6343
|
+
|
|
6344
|
+
const { spawn } = require('child_process');
|
|
6345
|
+
const { writeFile, appendFile } = require('fs').promises;
|
|
6346
|
+
const { join } = require('path');
|
|
6347
|
+
|
|
6348
|
+
const configDir = '${paths.globalConfig().replace(/\\/g, "\\\\")}';
|
|
6349
|
+
const logsDir = '${logsDir.replace(/\\/g, "\\\\")}';
|
|
6350
|
+
const cachePath = join(configDir, '.update-cache.json');
|
|
6351
|
+
const errorLogPath = join(logsDir, 'update-error.log');
|
|
6352
|
+
const targetVersion = '${targetVersion}';
|
|
6353
|
+
|
|
6354
|
+
async function logError(message) {
|
|
6355
|
+
const timestamp = new Date().toISOString();
|
|
6356
|
+
await appendFile(errorLogPath, \`[\${timestamp}] \${message}\\n\`);
|
|
6357
|
+
}
|
|
6358
|
+
|
|
6359
|
+
async function updateCache(version, error) {
|
|
6360
|
+
try {
|
|
6361
|
+
const fs = require('fs');
|
|
6362
|
+
let cache = { lastCheckTime: 0, lastCheckedVersion: '0.0.0', errorCount: 0 };
|
|
6363
|
+
|
|
6364
|
+
try {
|
|
6365
|
+
cache = JSON.parse(fs.readFileSync(cachePath, 'utf-8'));
|
|
6366
|
+
} catch {}
|
|
6367
|
+
|
|
6368
|
+
if (error) {
|
|
6369
|
+
cache.errorCount = (cache.errorCount || 0) + 1;
|
|
6370
|
+
cache.lastError = error;
|
|
6371
|
+
} else {
|
|
6372
|
+
cache.completedUpdate = version;
|
|
6373
|
+
cache.completedUpdateTime = Date.now();
|
|
6374
|
+
cache.errorCount = 0;
|
|
6375
|
+
cache.lastError = undefined;
|
|
6376
|
+
}
|
|
6377
|
+
|
|
6378
|
+
await writeFile(cachePath, JSON.stringify(cache, null, 2));
|
|
6379
|
+
} catch {}
|
|
6380
|
+
}
|
|
6381
|
+
|
|
6382
|
+
async function runUpdate() {
|
|
6383
|
+
return new Promise((resolve) => {
|
|
6384
|
+
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
6385
|
+
const child = spawn(npmCmd, ['install', '-g', '@tdsoft-tech/aikit@latest'], {
|
|
6386
|
+
stdio: 'pipe',
|
|
6387
|
+
});
|
|
6388
|
+
|
|
6389
|
+
let output = '';
|
|
6390
|
+
let errorOutput = '';
|
|
6391
|
+
|
|
6392
|
+
child.stdout.on('data', (data) => {
|
|
6393
|
+
output += data.toString();
|
|
6394
|
+
});
|
|
6395
|
+
|
|
6396
|
+
child.stderr.on('data', (data) => {
|
|
6397
|
+
errorOutput += data.toString();
|
|
6398
|
+
});
|
|
6399
|
+
|
|
6400
|
+
child.on('close', async (code) => {
|
|
6401
|
+
if (code === 0) {
|
|
6402
|
+
await updateCache(targetVersion, null);
|
|
6403
|
+
resolve(true);
|
|
6404
|
+
} else {
|
|
6405
|
+
const errorMsg = errorOutput || 'npm install failed';
|
|
6406
|
+
await logError(\`Update failed (code \${code}): \${errorMsg}\`);
|
|
6407
|
+
await updateCache(targetVersion, errorMsg);
|
|
6408
|
+
resolve(false);
|
|
6409
|
+
}
|
|
6410
|
+
});
|
|
6411
|
+
|
|
6412
|
+
child.on('error', async (err) => {
|
|
6413
|
+
await logError(\`Update error: \${err.message}\`);
|
|
6414
|
+
await updateCache(targetVersion, err.message);
|
|
6415
|
+
resolve(false);
|
|
6416
|
+
});
|
|
6417
|
+
});
|
|
6418
|
+
}
|
|
6419
|
+
|
|
6420
|
+
// Run update and exit
|
|
6421
|
+
runUpdate().then(() => process.exit(0));
|
|
6422
|
+
`;
|
|
6423
|
+
}
|
|
6424
|
+
|
|
6425
|
+
// src/core/update-manager.ts
|
|
6426
|
+
var CHECK_INTERVAL = 24 * 60 * 60 * 1e3;
|
|
6427
|
+
var PACKAGE_NAME = "@tdsoft-tech/aikit";
|
|
6428
|
+
async function shouldCheckForUpdates() {
|
|
6429
|
+
const cache = await readCache();
|
|
6430
|
+
const now = Date.now();
|
|
6431
|
+
return now - cache.lastCheckTime > CHECK_INTERVAL;
|
|
6432
|
+
}
|
|
6433
|
+
async function displayNotification() {
|
|
6434
|
+
const cache = await readCache();
|
|
6435
|
+
if (cache.completedUpdate) {
|
|
6436
|
+
const currentVersion = getVersion();
|
|
6437
|
+
if (isGreaterThan(cache.completedUpdate, currentVersion)) {
|
|
6438
|
+
console.log(chalk2.cyan.bold("\n\u2728 AIKit has been updated!\n"));
|
|
6439
|
+
console.log(chalk2.gray(` Version: ${currentVersion} \u2192 ${cache.completedUpdate}`));
|
|
6440
|
+
console.log(chalk2.gray(` Updated: Just now
|
|
6441
|
+
`));
|
|
6442
|
+
console.log(chalk2.gray("Run 'aikit --version' to verify.\n"));
|
|
6443
|
+
await clearCompletedUpdate();
|
|
6444
|
+
}
|
|
6445
|
+
}
|
|
6446
|
+
if (cache.errorCount >= 3 && cache.lastError) {
|
|
6447
|
+
console.log(chalk2.yellow.bold("\n\u26A0\uFE0F AIKit update failed\n"));
|
|
6448
|
+
console.log(chalk2.gray(` Last error: ${cache.lastError}`));
|
|
6449
|
+
console.log(chalk2.gray(" Check logs: ~/.config/aikit/logs/update-error.log\n"));
|
|
6450
|
+
}
|
|
6451
|
+
}
|
|
6452
|
+
async function performBackgroundUpdate(latestVersion) {
|
|
6453
|
+
const success = await spawnUpdateProcess(latestVersion);
|
|
6454
|
+
if (!success) {
|
|
6455
|
+
await incrementError("Failed to spawn update process");
|
|
6456
|
+
} else {
|
|
6457
|
+
await setCompletedUpdate(latestVersion);
|
|
6458
|
+
}
|
|
6459
|
+
}
|
|
6460
|
+
async function checkForUpdates() {
|
|
6461
|
+
try {
|
|
6462
|
+
await displayNotification();
|
|
6463
|
+
if (!await shouldCheckForUpdates()) {
|
|
6464
|
+
return;
|
|
6465
|
+
}
|
|
6466
|
+
const currentVersion = getVersion();
|
|
6467
|
+
const latestVersion = await getLatestVersion(PACKAGE_NAME);
|
|
6468
|
+
await setLastCheckTime(Date.now());
|
|
6469
|
+
await setLastCheckedVersion(currentVersion);
|
|
6470
|
+
if (!latestVersion || !isGreaterThan(latestVersion, currentVersion)) {
|
|
6471
|
+
return;
|
|
6472
|
+
}
|
|
6473
|
+
await performBackgroundUpdate(latestVersion);
|
|
6474
|
+
} catch {
|
|
6475
|
+
}
|
|
6476
|
+
}
|
|
6477
|
+
async function checkForUpdatesAsync() {
|
|
6478
|
+
checkForUpdates().catch(() => {
|
|
6479
|
+
});
|
|
6480
|
+
}
|
|
6481
|
+
|
|
6166
6482
|
// src/index.ts
|
|
6167
6483
|
init_logger();
|
|
6168
6484
|
init_paths();
|
|
@@ -6178,6 +6494,7 @@ export {
|
|
|
6178
6494
|
SkillEngine,
|
|
6179
6495
|
ToolRegistry,
|
|
6180
6496
|
getVersion as VERSION,
|
|
6497
|
+
checkForUpdatesAsync,
|
|
6181
6498
|
defineTool,
|
|
6182
6499
|
loadConfig,
|
|
6183
6500
|
logger,
|