@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/dist/cli.js CHANGED
@@ -159,6 +159,7 @@ var init_paths = __esm({
159
159
  import { readFileSync } from "fs";
160
160
  import { fileURLToPath as fileURLToPath2 } from "url";
161
161
  import { dirname, join as join2 } from "path";
162
+ import { compare, gt, valid } from "semver";
162
163
  function getVersion() {
163
164
  try {
164
165
  const __filename2 = fileURLToPath2(import.meta.url);
@@ -171,6 +172,9 @@ function getVersion() {
171
172
  return "0.0.0";
172
173
  }
173
174
  }
175
+ function isGreaterThan(v1, v2) {
176
+ return gt(v1, v2);
177
+ }
174
178
  var init_version = __esm({
175
179
  "src/utils/version.ts"() {
176
180
  "use strict";
@@ -403,8 +407,8 @@ var init_memory = __esm({
403
407
  for (const subDir of subDirs) {
404
408
  const dirPath = join6(memoryPath, subDir);
405
409
  try {
406
- const { readdir: readdir11 } = await import("fs/promises");
407
- const files = await readdir11(dirPath);
410
+ const { readdir: readdir12 } = await import("fs/promises");
411
+ const files = await readdir12(dirPath);
408
412
  for (const file of files) {
409
413
  if (!file.endsWith(".md")) continue;
410
414
  const content = await readFile4(join6(dirPath, file), "utf-8");
@@ -1684,11 +1688,14 @@ __export(sessions_exports, {
1684
1688
  SessionManager: () => SessionManager,
1685
1689
  formatSession: () => formatSession
1686
1690
  });
1687
- import { readFile as readFile7, writeFile as writeFile8, readdir as readdir7, mkdir as mkdir8 } from "fs/promises";
1688
- import { join as join13 } from "path";
1691
+ import { readFile as readFile8, writeFile as writeFile10, readdir as readdir7, mkdir as mkdir10, access as access4, constants as constants4 } from "fs/promises";
1692
+ import { join as join15 } from "path";
1689
1693
  import matter3 from "gray-matter";
1690
1694
  import { exec as exec2 } from "child_process";
1691
1695
  import { promisify as promisify2 } from "util";
1696
+ function sanitizeTTY(tty) {
1697
+ return tty.replace(/[^a-zA-Z0-9._-]/g, "-");
1698
+ }
1692
1699
  function formatSession(session) {
1693
1700
  const startDate = new Date(session.startTime);
1694
1701
  const endDate = session.endTime ? new Date(session.endTime) : null;
@@ -1711,20 +1718,104 @@ var init_sessions = __esm({
1711
1718
  SessionManager = class {
1712
1719
  sessionsDir;
1713
1720
  projectPath;
1721
+ aikitDir;
1714
1722
  constructor(projectPath) {
1715
1723
  this.projectPath = projectPath || process.cwd();
1716
- this.sessionsDir = join13(this.projectPath, ".aikit", "sessions");
1724
+ this.aikitDir = join15(this.projectPath, ".aikit");
1725
+ this.sessionsDir = join15(this.aikitDir, "sessions");
1726
+ }
1727
+ /**
1728
+ * Get current terminal's TTY path
1729
+ * Uses the `tty` command to get the terminal device path
1730
+ * Returns null if not a TTY (editor environment)
1731
+ */
1732
+ async getCurrentTTY() {
1733
+ try {
1734
+ const { stdout } = await execAsync2("tty");
1735
+ const tty = stdout.trim();
1736
+ if (tty === "not a tty" || !tty.startsWith("/")) {
1737
+ return null;
1738
+ }
1739
+ return tty;
1740
+ } catch {
1741
+ return null;
1742
+ }
1743
+ }
1744
+ /**
1745
+ * Get a unique identifier for the current terminal/editor session
1746
+ * Uses TTY if available, otherwise uses PPID (parent process ID)
1747
+ */
1748
+ async getTerminalIdentifier() {
1749
+ const tty = await this.getCurrentTTY();
1750
+ if (tty) {
1751
+ return sanitizeTTY(tty);
1752
+ }
1753
+ return `ppid-${process.ppid}`;
1754
+ }
1755
+ /**
1756
+ * Get the current session tracker file path
1757
+ * Always uses per-terminal file (TTY or PPID-based)
1758
+ */
1759
+ async getSessionTrackerPath() {
1760
+ const identifier = await this.getTerminalIdentifier();
1761
+ return join15(this.sessionsDir, `.current-${identifier}-session`);
1762
+ }
1763
+ /**
1764
+ * Switch to a different session in the current terminal
1765
+ */
1766
+ async switchSession(sessionId) {
1767
+ const session = await this.getSession(sessionId);
1768
+ if (!session) {
1769
+ throw new Error(`Session not found: ${sessionId}`);
1770
+ }
1771
+ const sessionFile = await this.getSessionTrackerPath();
1772
+ await writeFile10(sessionFile, sessionId);
1773
+ }
1774
+ /**
1775
+ * Initialize the current terminal's session file
1776
+ * Creates an empty tracker file if it doesn't exist
1777
+ */
1778
+ async initTerminalSession() {
1779
+ const sessionFile = await this.getSessionTrackerPath();
1780
+ try {
1781
+ await access4(sessionFile);
1782
+ } catch {
1783
+ await writeFile10(sessionFile, "");
1784
+ }
1785
+ return { tracker: sessionFile };
1786
+ }
1787
+ /**
1788
+ * Get current terminal info (for display purposes)
1789
+ */
1790
+ async getTerminalInfo() {
1791
+ const tty = await this.getCurrentTTY();
1792
+ const sessionId = await this.getActiveSessionId();
1793
+ return { tty, sessionId };
1794
+ }
1795
+ /**
1796
+ * Check if .aikit directory exists in current project path
1797
+ */
1798
+ async ensureAikitExists() {
1799
+ try {
1800
+ await access4(this.aikitDir, constants4.R_OK);
1801
+ } catch {
1802
+ throw new Error(
1803
+ `AIKit not initialized in current directory (${this.projectPath}). Run 'aikit init' first to initialize AIKit in this directory.`
1804
+ );
1805
+ }
1717
1806
  }
1718
1807
  /**
1719
1808
  * Initialize sessions directory
1720
1809
  */
1721
1810
  async init() {
1722
- await mkdir8(this.sessionsDir, { recursive: true });
1811
+ await this.ensureAikitExists();
1812
+ await mkdir10(this.sessionsDir, { recursive: true });
1723
1813
  }
1724
1814
  /**
1725
1815
  * Start a new session
1726
1816
  */
1727
1817
  async startSession(name, goals) {
1818
+ await this.ensureAikitExists();
1728
1819
  await this.init();
1729
1820
  const now = /* @__PURE__ */ new Date();
1730
1821
  const date = now.toISOString().split("T")[0].replace(/-/g, "");
@@ -1754,6 +1845,7 @@ var init_sessions = __esm({
1754
1845
  * Update current session with notes
1755
1846
  */
1756
1847
  async updateSession(notes) {
1848
+ await this.ensureAikitExists();
1757
1849
  const sessionId = await this.getActiveSessionId();
1758
1850
  if (!sessionId) {
1759
1851
  throw new Error("No active session. Use startSession() first.");
@@ -1783,6 +1875,7 @@ var init_sessions = __esm({
1783
1875
  * End current session and generate summary
1784
1876
  */
1785
1877
  async endSession() {
1878
+ await this.ensureAikitExists();
1786
1879
  const sessionId = await this.getActiveSessionId();
1787
1880
  if (!sessionId) {
1788
1881
  throw new Error("No active session. Use startSession() first.");
@@ -1810,6 +1903,7 @@ var init_sessions = __esm({
1810
1903
  * Get current active session
1811
1904
  */
1812
1905
  async getCurrentSession() {
1906
+ await this.ensureAikitExists();
1813
1907
  const sessionId = await this.getActiveSessionId();
1814
1908
  if (!sessionId) return null;
1815
1909
  return this.getSession(sessionId);
@@ -1818,6 +1912,7 @@ var init_sessions = __esm({
1818
1912
  * Get all sessions
1819
1913
  */
1820
1914
  async listSessions() {
1915
+ await this.ensureAikitExists();
1821
1916
  try {
1822
1917
  const files = await readdir7(this.sessionsDir);
1823
1918
  const sessions = [];
@@ -1832,17 +1927,21 @@ var init_sessions = __esm({
1832
1927
  return sessions.sort(
1833
1928
  (a, b) => new Date(b.startTime).getTime() - new Date(a.startTime).getTime()
1834
1929
  );
1835
- } catch {
1836
- return [];
1930
+ } catch (error) {
1931
+ if (error.code === "ENOENT") {
1932
+ return [];
1933
+ }
1934
+ throw error;
1837
1935
  }
1838
1936
  }
1839
1937
  /**
1840
1938
  * Get specific session
1841
1939
  */
1842
1940
  async getSession(id) {
1843
- const filePath = join13(this.sessionsDir, `${id}.md`);
1941
+ await this.ensureAikitExists();
1942
+ const filePath = join15(this.sessionsDir, `${id}.md`);
1844
1943
  try {
1845
- const content = await readFile7(filePath, "utf-8");
1944
+ const content = await readFile8(filePath, "utf-8");
1846
1945
  const { data, content: body } = matter3(content);
1847
1946
  const updates = this.parseUpdates(body);
1848
1947
  return {
@@ -1865,35 +1964,88 @@ var init_sessions = __esm({
1865
1964
  const sessions = await this.listSessions();
1866
1965
  const lowerQuery = query.toLowerCase();
1867
1966
  return sessions.filter(
1868
- (session) => session.name.toLowerCase().includes(lowerQuery) || session.id.toLowerCase().includes(lowerQuery) || session.goals.some((g) => g.toLowerCase().includes(lowerQuery)) || session.updates.some((u) => u.notes?.toLowerCase().includes(lowerQuery))
1967
+ (session) => session.name.toLowerCase().includes(lowerQuery) || session.id.toLowerCase().includes(lowerQuery) || Array.isArray(session.goals) && session.goals.some(
1968
+ (g) => typeof g === "string" && g.toLowerCase().includes(lowerQuery)
1969
+ ) || session.updates.some((u) => u.notes?.toLowerCase().includes(lowerQuery))
1869
1970
  );
1870
1971
  }
1972
+ /**
1973
+ * Resume a past session (set as active)
1974
+ * Supports partial ID matching and "latest" keyword
1975
+ */
1976
+ async resumeSession(idOrLatest) {
1977
+ await this.ensureAikitExists();
1978
+ let session = null;
1979
+ if (idOrLatest === "latest") {
1980
+ const sessions = await this.listSessions();
1981
+ if (sessions.length === 0) {
1982
+ throw new Error("No sessions found to resume");
1983
+ }
1984
+ session = sessions[0];
1985
+ } else {
1986
+ session = await this.getSession(idOrLatest);
1987
+ if (!session) {
1988
+ const sessions = await this.listSessions();
1989
+ const matches = sessions.filter((s) => s.id.startsWith(idOrLatest));
1990
+ if (matches.length === 0) {
1991
+ throw new Error(`Session not found: ${idOrLatest}`);
1992
+ }
1993
+ if (matches.length > 1) {
1994
+ throw new Error(
1995
+ `Multiple sessions match "${idOrLatest}": ${matches.map((s) => s.id).join(", ")}. Please use a more specific ID.`
1996
+ );
1997
+ }
1998
+ session = matches[0];
1999
+ }
2000
+ }
2001
+ if (!session) {
2002
+ throw new Error(`Session not found: ${idOrLatest}`);
2003
+ }
2004
+ const currentSessionId = await this.getActiveSessionId();
2005
+ if (currentSessionId === session.id) {
2006
+ return session;
2007
+ }
2008
+ await this.setActiveSession(session.id);
2009
+ if (session.status === "ended") {
2010
+ session.status = "active";
2011
+ session.endTime = void 0;
2012
+ session.updates.push({
2013
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2014
+ notes: "Session resumed",
2015
+ gitBranch: (await this.getGitState()).branch
2016
+ });
2017
+ await this.saveSession(session);
2018
+ }
2019
+ return session;
2020
+ }
1871
2021
  /**
1872
2022
  * Get active session ID
2023
+ * Reads from the current session tracker file
1873
2024
  */
1874
2025
  async getActiveSessionId() {
1875
- const trackerPath = join13(this.sessionsDir, ".current-session");
2026
+ const sessionFile = await this.getSessionTrackerPath();
1876
2027
  try {
1877
- const content = await readFile7(trackerPath, "utf-8");
1878
- return content.trim();
2028
+ const content = await readFile8(sessionFile, "utf-8");
2029
+ return content.trim() || null;
1879
2030
  } catch {
1880
2031
  return null;
1881
2032
  }
1882
2033
  }
1883
2034
  /**
1884
- * Set active session
2035
+ * Set active session for current terminal
2036
+ * Writes to the current session tracker file
1885
2037
  */
1886
2038
  async setActiveSession(id) {
1887
- const trackerPath = join13(this.sessionsDir, ".current-session");
1888
- await writeFile8(trackerPath, id);
2039
+ const sessionFile = await this.getSessionTrackerPath();
2040
+ await writeFile10(sessionFile, id);
1889
2041
  }
1890
2042
  /**
1891
- * Clear active session
2043
+ * Clear active session for current terminal
1892
2044
  */
1893
2045
  async clearActiveSession() {
1894
- const trackerPath = join13(this.sessionsDir, ".current-session");
2046
+ const sessionFile = await this.getSessionTrackerPath();
1895
2047
  try {
1896
- await writeFile8(trackerPath, "");
2048
+ await writeFile10(sessionFile, "");
1897
2049
  } catch {
1898
2050
  }
1899
2051
  }
@@ -1901,7 +2053,7 @@ var init_sessions = __esm({
1901
2053
  * Save session to file
1902
2054
  */
1903
2055
  async saveSession(session) {
1904
- const filePath = join13(this.sessionsDir, `${session.id}.md`);
2056
+ const filePath = join15(this.sessionsDir, `${session.id}.md`);
1905
2057
  const updatesMarkdown = session.updates.map((update) => {
1906
2058
  const date = new Date(update.timestamp);
1907
2059
  const dateStr = date.toLocaleString();
@@ -1940,7 +2092,7 @@ var init_sessions = __esm({
1940
2092
  ${session.endTime ? `**Ended:** ${new Date(session.endTime).toLocaleString()}` : ""}
1941
2093
 
1942
2094
  ## Goals
1943
- ${session.goals.map((g, i) => `- [ ] ${g}`).join("\n")}
2095
+ ${session.goals.map((g) => `- [ ] ${g}`).join("\n")}
1944
2096
 
1945
2097
  ## Progress
1946
2098
 
@@ -1950,7 +2102,7 @@ ${updatesMarkdown}
1950
2102
  ${this.generateSummary(session)}
1951
2103
  `;
1952
2104
  const fileContent = matter3.stringify(content, frontmatter);
1953
- await writeFile8(filePath, fileContent);
2105
+ await writeFile10(filePath, fileContent);
1954
2106
  }
1955
2107
  /**
1956
2108
  * Generate session summary
@@ -2076,14 +2228,16 @@ ${this.generateSummary(session)}
2076
2228
  }
2077
2229
  /**
2078
2230
  * Get current Beads task
2231
+ * NOTE: This only reads Beads metadata for session updates.
2232
+ * Sessions are NEVER stored in .beads - they are always in .aikit/sessions
2079
2233
  */
2080
2234
  async getCurrentBeadsTask() {
2081
- const beadsDir = join13(this.projectPath, ".beads");
2235
+ const beadsDir = join15(this.projectPath, ".beads");
2082
2236
  try {
2083
2237
  const files = await readdir7(beadsDir);
2084
2238
  const beadFiles = files.filter((f) => f.startsWith("bead-") && f.endsWith(".md"));
2085
2239
  for (const file of beadFiles) {
2086
- const content = await readFile7(join13(beadsDir, file), "utf-8");
2240
+ const content = await readFile8(join15(beadsDir, file), "utf-8");
2087
2241
  const statusMatch = content.match(/^status:\s*(\w+)/m);
2088
2242
  const id = file.replace(".md", "");
2089
2243
  if (statusMatch && (statusMatch[1] === "in-progress" || statusMatch[1] === "todo")) {
@@ -2107,8 +2261,8 @@ var tool_config_exports = {};
2107
2261
  __export(tool_config_exports, {
2108
2262
  ToolConfigManager: () => ToolConfigManager
2109
2263
  });
2110
- import { readFile as readFile14, writeFile as writeFile16, mkdir as mkdir14, access as access7, constants as constants4 } from "fs/promises";
2111
- import { join as join21 } from "path";
2264
+ import { readFile as readFile15, writeFile as writeFile18, mkdir as mkdir16, access as access7, constants as constants5 } from "fs/promises";
2265
+ import { join as join23 } from "path";
2112
2266
  import { z as z3 } from "zod";
2113
2267
  var ToolConfigSchema, REGISTERED_TOOLS, ToolConfigManager;
2114
2268
  var init_tool_config = __esm({
@@ -2136,7 +2290,7 @@ var init_tool_config = __esm({
2136
2290
  toolsConfigPath;
2137
2291
  constructor(config) {
2138
2292
  this.config = config;
2139
- this.toolsConfigPath = join21(this.config.configPath, "config", "tools.json");
2293
+ this.toolsConfigPath = join23(this.config.configPath, "config", "tools.json");
2140
2294
  }
2141
2295
  /**
2142
2296
  * Get all registered tools with their current status
@@ -2219,8 +2373,8 @@ var init_tool_config = __esm({
2219
2373
  */
2220
2374
  async loadConfigs() {
2221
2375
  try {
2222
- await access7(this.toolsConfigPath, constants4.R_OK);
2223
- const content = await readFile14(this.toolsConfigPath, "utf-8");
2376
+ await access7(this.toolsConfigPath, constants5.R_OK);
2377
+ const content = await readFile15(this.toolsConfigPath, "utf-8");
2224
2378
  return JSON.parse(content);
2225
2379
  } catch {
2226
2380
  return {};
@@ -2230,9 +2384,9 @@ var init_tool_config = __esm({
2230
2384
  * Save configurations
2231
2385
  */
2232
2386
  async saveConfigs(configs) {
2233
- const configDir = join21(this.config.configPath, "config");
2234
- await mkdir14(configDir, { recursive: true });
2235
- await writeFile16(this.toolsConfigPath, JSON.stringify(configs, null, 2));
2387
+ const configDir = join23(this.config.configPath, "config");
2388
+ await mkdir16(configDir, { recursive: true });
2389
+ await writeFile18(this.toolsConfigPath, JSON.stringify(configs, null, 2));
2236
2390
  }
2237
2391
  };
2238
2392
  }
@@ -4161,14 +4315,14 @@ Total: 2 checkpoints
4161
4315
  init_esm_shims();
4162
4316
  var SESSION_COMMANDS = [
4163
4317
  {
4164
- name: "session:start",
4318
+ name: "session-start",
4165
4319
  description: "Start a new development session",
4166
4320
  category: "session",
4167
- usage: "/session:start [name]",
4321
+ usage: "/session-start [name]",
4168
4322
  examples: [
4169
- "/session:start",
4170
- "/session:start authentication-refactor",
4171
- '/session:start "Add user profile feature"'
4323
+ "/session-start",
4324
+ "/session-start authentication-refactor",
4325
+ '/session-start "Add user profile feature"'
4172
4326
  ],
4173
4327
  content: `Start a new development session to track your work.
4174
4328
 
@@ -4176,47 +4330,70 @@ var SESSION_COMMANDS = [
4176
4330
 
4177
4331
  Session name: $ARGUMENTS
4178
4332
 
4179
- 1. **Create Session:**
4180
- - Generate session ID with timestamp
4181
- - Create session file in .aikit/sessions/
4182
- - Track active session in .current-session
4183
- - Capture initial git state
4333
+ **IMPORTANT - Scope Rules:**
4334
+ - Sessions are scoped to the CURRENT working directory
4335
+ - AIKit will NOT search parent directories for .aikit
4336
+ - If .aikit doesn't exist in current directory, you MUST run 'aikit init' first
4337
+ - Each directory needs its own .aikit if you want separate session tracking
4338
+
4339
+ 1. **Check Current Directory:**
4340
+ - Verify .aikit exists in current directory (process.cwd())
4341
+ - If not, inform user to run 'aikit init' first
4342
+ - DO NOT search parent directories
4184
4343
 
4185
- 2. **Set Goals:**
4344
+ 2. **Create Session:**
4345
+ - Generate session ID with timestamp
4346
+ - Create session file in .aikit/sessions/ (current directory only)
4347
+ - Determine session tracker file:
4348
+ * Try 'tty' command to get terminal identifier
4349
+ * If 'tty' works, use .aikit/sessions/.current-<sanitized_tty>-session
4350
+ (replace '/' with '-' in TTY path)
4351
+ * If 'tty' fails with "not a tty", get parent PID using: ps -o ppid= -p $$
4352
+ Use .aikit/sessions/.current-ppid-<PPID>-session
4353
+ (each Claude Code window has unique PPID)
4354
+ - Write session ID to the tracker file
4355
+ - **Capture initial git state (scoped to current directory):**
4356
+ * First check if .git exists in CURRENT directory (process.cwd())
4357
+ * ONLY capture git state if .git exists in current directory
4358
+ * DO NOT search parent directories for git repo
4359
+ * If no .git in current directory, skip git state capture
4360
+
4361
+ 3. **Set Goals:**
4186
4362
  - Ask user for session goals if not provided
4187
4363
  - Document what you want to accomplish
4188
4364
  - Link to Beads task if active
4189
4365
 
4190
- 3. **Session Started:**
4366
+ 4. **Session Started:**
4191
4367
  - Session ID: YYYY-MM-DD-HHMM[-name]
4192
4368
  - Status: active
4193
4369
  - Ready for updates
4194
4370
 
4195
4371
  ## What Gets Tracked
4196
4372
  - Session start time
4197
- - Git branch and commits
4198
- - Modified files
4373
+ - Git branch and commits (ONLY if .git exists in current directory)
4374
+ - Modified files (ONLY if .git exists in current directory)
4199
4375
  - Progress notes
4200
4376
  - Linked Beads task
4201
4377
 
4202
4378
  ## Session File Location
4203
- .aikit/sessions/YYYY-MM-DD-HHMM[-name].md
4379
+ Current directory: .aikit/sessions/YYYY-MM-DD-HHMM[-name].md
4380
+ (Always relative to process.cwd(), never parent directories)
4204
4381
 
4205
4382
  ## Examples
4206
4383
 
4207
4384
  Start unnamed session:
4208
4385
  \`\`\`
4209
- /session:start
4386
+ /session-start
4210
4387
  \`\`\`
4211
4388
 
4212
4389
  Start with descriptive name:
4213
4390
  \`\`\`
4214
- /session:start auth-refactor
4391
+ /session-start auth-refactor
4215
4392
  \`\`\`
4216
4393
 
4217
4394
  Start with goal:
4218
4395
  \`\`\`
4219
- /session:start "Implement OAuth 2.0"
4396
+ /session-start "Implement OAuth 2.0"
4220
4397
  Goals:
4221
4398
  - Add Google OAuth
4222
4399
  - Add JWT token handling
@@ -4225,18 +4402,18 @@ Goals:
4225
4402
  ## Notes
4226
4403
  - Session files are markdown with frontmatter
4227
4404
  - Sessions persist across AI conversations
4228
- - Use /session:update to add progress notes
4229
- - Use /session:end to close and summarize`
4405
+ - Use /session-update to add progress notes
4406
+ - Use /session-end to close and summarize`
4230
4407
  },
4231
4408
  {
4232
- name: "session:update",
4409
+ name: "session-update",
4233
4410
  description: "Add progress notes to current session",
4234
4411
  category: "session",
4235
- usage: "/session:update [notes]",
4412
+ usage: "/session-update [notes]",
4236
4413
  examples: [
4237
- "/session:update",
4238
- "/session:update Fixed authentication bug",
4239
- '/session:update "Added JWT middleware"'
4414
+ "/session-update",
4415
+ "/session-update Fixed authentication bug",
4416
+ '/session-update "Added JWT middleware"'
4240
4417
  ],
4241
4418
  content: `Update the current session with progress notes.
4242
4419
 
@@ -4245,19 +4422,28 @@ Goals:
4245
4422
  Progress notes: $ARGUMENTS
4246
4423
 
4247
4424
  1. **Check Active Session:**
4248
- - Verify there's an active session
4425
+ - Determine session tracker file:
4426
+ * Try 'tty' command to get terminal identifier
4427
+ * If 'tty' works, read .aikit/sessions/.current-<sanitized_tty>-session
4428
+ * If 'tty' fails, get parent PID and read .aikit/sessions/.current-ppid-<PPID>-session
4249
4429
  - Load session file
4250
4430
 
4251
4431
  2. **Capture Current State:**
4252
- - Get current git branch
4253
- - Count git commits
4254
- - List modified files
4255
- - Check active Beads task
4432
+ - **IMPORTANT - Git State Scope:**
4433
+ * First check if .git exists in CURRENT directory (process.cwd())
4434
+ * ONLY capture git state if .git exists in current directory
4435
+ * DO NOT search parent directories for git repo
4436
+ * If no .git in current directory, skip git state capture
4437
+ - If .git exists in current directory:
4438
+ * Get current git branch
4439
+ * Count git commits
4440
+ * List modified files
4441
+ - Check active Beads task (from .beads directory if exists)
4256
4442
 
4257
4443
  3. **Add Update:**
4258
4444
  - Add timestamped update entry
4259
4445
  - Include your notes (or auto-generate)
4260
- - Include git state
4446
+ - Include git state ONLY if .git exists in current directory
4261
4447
  - Include Beads task if active
4262
4448
 
4263
4449
  4. **Save Session:**
@@ -4267,27 +4453,25 @@ Progress notes: $ARGUMENTS
4267
4453
  ## What Gets Captured
4268
4454
  - Timestamp of update
4269
4455
  - Your progress notes
4270
- - Current git branch
4271
- - Number of commits
4272
- - List of modified files
4456
+ - Git state (branch, commits, files) - ONLY if .git exists in current directory
4273
4457
  - Active Beads task (if any)
4274
4458
 
4275
4459
  ## Examples
4276
4460
 
4277
4461
  Auto-update (no notes):
4278
4462
  \`\`\`
4279
- /session:update
4463
+ /session-update
4280
4464
  \`\`\`
4281
4465
  *Auto-generates summary of recent work*
4282
4466
 
4283
4467
  With specific notes:
4284
4468
  \`\`\`
4285
- /session:update Fixed Next.js params issue
4469
+ /session-update Fixed Next.js params issue
4286
4470
  \`\`\`
4287
4471
 
4288
4472
  With detailed notes:
4289
4473
  \`\`\`
4290
- /session:update "Implemented OAuth flow with Google provider. Added callback handler and token validation."
4474
+ /session-update "Implemented OAuth flow with Google provider. Added callback handler and token validation."
4291
4475
  \`\`\`
4292
4476
 
4293
4477
  ## Notes
@@ -4297,11 +4481,11 @@ With detailed notes:
4297
4481
  - Beads task automatically linked`
4298
4482
  },
4299
4483
  {
4300
- name: "session:end",
4484
+ name: "session-end",
4301
4485
  description: "End current session with summary",
4302
4486
  category: "session",
4303
- usage: "/session:end",
4304
- examples: ["/session:end"],
4487
+ usage: "/session-end",
4488
+ examples: ["/session-end"],
4305
4489
  content: `End the current session and generate a comprehensive summary.
4306
4490
 
4307
4491
  ## Workflow
@@ -4331,7 +4515,10 @@ With detailed notes:
4331
4515
  - Mark session as ended
4332
4516
  - Set end time
4333
4517
  - Save session file
4334
- - Clear .current-session tracker
4518
+ - Determine session tracker file:
4519
+ * Try 'tty' command to get terminal identifier
4520
+ * If 'tty' works, clear .aikit/sessions/.current-<sanitized_tty>-session
4521
+ * If 'tty' fails, get parent PID and clear .aikit/sessions/.current-ppid-<PPID>-session
4335
4522
 
4336
4523
  ## Summary Includes
4337
4524
 
@@ -4386,17 +4573,20 @@ Lessons:
4386
4573
  - Can start new session after ending`
4387
4574
  },
4388
4575
  {
4389
- name: "session:current",
4576
+ name: "session-current",
4390
4577
  description: "Show current active session",
4391
4578
  category: "session",
4392
- usage: "/session:current",
4393
- examples: ["/session:current"],
4579
+ usage: "/session-current",
4580
+ examples: ["/session-current"],
4394
4581
  content: `Display information about the current active session.
4395
4582
 
4396
4583
  ## Workflow
4397
4584
 
4398
4585
  1. **Check Active Session:**
4399
- - Read .current-session file
4586
+ - Determine session tracker file:
4587
+ * Try 'tty' command to get terminal identifier
4588
+ * If 'tty' works, read .aikit/sessions/.current-<sanitized_tty>-session
4589
+ * If 'tty' fails, get parent PID and read .aikit/sessions/.current-ppid-<PPID>-session
4400
4590
  - Load session data
4401
4591
 
4402
4592
  2. **Display Session Info:**
@@ -4436,8 +4626,8 @@ Beads Task:
4436
4626
  - bead-001 (in-progress)
4437
4627
 
4438
4628
  Commands:
4439
- /session:update [notes] - Add progress
4440
- /session:end - Close session
4629
+ /session-update [notes] - Add progress
4630
+ /session-end - Close session
4441
4631
  \`\`\`
4442
4632
 
4443
4633
  ## Notes
@@ -4446,18 +4636,18 @@ Commands:
4446
4636
  - Displays recent progress`
4447
4637
  },
4448
4638
  {
4449
- name: "session:list",
4639
+ name: "session-list",
4450
4640
  description: "List all sessions",
4451
4641
  category: "session",
4452
- usage: "/session:list",
4453
- examples: ["/session:list"],
4642
+ usage: "/session-list",
4643
+ examples: ["/session-list"],
4454
4644
  content: `List all development sessions with summaries.
4455
4645
 
4456
4646
  ## Workflow
4457
4647
 
4458
4648
  1. **Scan Sessions Directory:**
4459
4649
  - Find all .md files in .aikit/sessions/
4460
- - Exclude .current-session
4650
+ - Exclude all .current-*-session files (terminal trackers)
4461
4651
 
4462
4652
  2. **Sort by Date:**
4463
4653
  - Newest sessions first
@@ -4500,16 +4690,16 @@ Total: 3 sessions
4500
4690
  - Shows both active and ended sessions
4501
4691
  - Most recent sessions first
4502
4692
  - Active session highlighted
4503
- - Use /session:show <id> for details`
4693
+ - Use /session-show <id> for details`
4504
4694
  },
4505
4695
  {
4506
- name: "session:show",
4696
+ name: "session-show",
4507
4697
  description: "Show details of a specific session",
4508
4698
  category: "session",
4509
- usage: "/session:show <session-id>",
4699
+ usage: "/session-show <session-id>",
4510
4700
  examples: [
4511
- "/session:show 2025-01-02-1430",
4512
- "/session:show 2025-01-02-1430-auth-refactor"
4701
+ "/session-show 2025-01-02-1430",
4702
+ "/session-show 2025-01-02-1430-auth-refactor"
4513
4703
  ],
4514
4704
  content: `Display full details of a specific session.
4515
4705
 
@@ -4580,14 +4770,14 @@ Successfully refactored authentication system...
4580
4770
  - Full session details displayed`
4581
4771
  },
4582
4772
  {
4583
- name: "session:search",
4773
+ name: "session-search",
4584
4774
  description: "Search sessions by keyword",
4585
4775
  category: "session",
4586
- usage: "/session:search <query>",
4776
+ usage: "/session-search <query>",
4587
4777
  examples: [
4588
- "/session:search oauth",
4589
- '/session:search "jwt"',
4590
- "/session:search authentication"
4778
+ "/session-search oauth",
4779
+ '/session-search "jwt"',
4780
+ "/session-search authentication"
4591
4781
  ],
4592
4782
  content: `Search for sessions matching a keyword.
4593
4783
 
@@ -4608,7 +4798,7 @@ Search query: $ARGUMENTS
4608
4798
 
4609
4799
  3. **Show Actions:**
4610
4800
  - List matching sessions
4611
- - Suggest /session:show for details
4801
+ - Suggest /session-show for details
4612
4802
 
4613
4803
  ## Example Output
4614
4804
  \`\`\`
@@ -4638,14 +4828,14 @@ Total: 2 matching sessions
4638
4828
  - Use partial IDs too`
4639
4829
  },
4640
4830
  {
4641
- name: "session:resume",
4831
+ name: "session-resume",
4642
4832
  description: "Resume a past session (load context)",
4643
4833
  category: "session",
4644
- usage: "/session:resume <session-id>",
4834
+ usage: "/session-resume <session-id>",
4645
4835
  examples: [
4646
- "/session:resume latest",
4647
- "/session:resume 2025-01-02-1430",
4648
- "/session:resume 2025-01-02-1430-auth-refactor"
4836
+ "/session-resume latest",
4837
+ "/session-resume 2025-01-02-1430",
4838
+ "/session-resume 2025-01-02-1430-auth-refactor"
4649
4839
  ],
4650
4840
  content: `Load context from a past session to resume work.
4651
4841
 
@@ -6597,6 +6787,282 @@ init_beads();
6597
6787
  init_esm_shims();
6598
6788
  init_logger();
6599
6789
 
6790
+ // src/core/update-manager.ts
6791
+ init_esm_shims();
6792
+ init_version();
6793
+ import chalk2 from "chalk";
6794
+
6795
+ // src/utils/npm-client.ts
6796
+ init_esm_shims();
6797
+ import https from "https";
6798
+ async function getLatestVersion(packageName) {
6799
+ return new Promise((resolve) => {
6800
+ const url = `https://registry.npmjs.org/${packageName}`;
6801
+ https.get(url, (res) => {
6802
+ let data = "";
6803
+ res.on("data", (chunk) => {
6804
+ data += chunk;
6805
+ });
6806
+ res.on("end", () => {
6807
+ try {
6808
+ if (res.statusCode === 200) {
6809
+ const packageData = JSON.parse(data);
6810
+ const latestVersion = packageData["dist-tags"]?.latest;
6811
+ resolve(latestVersion || null);
6812
+ } else {
6813
+ resolve(null);
6814
+ }
6815
+ } catch {
6816
+ resolve(null);
6817
+ }
6818
+ });
6819
+ }).on("error", () => {
6820
+ resolve(null);
6821
+ }).setTimeout(5e3, () => {
6822
+ resolve(null);
6823
+ });
6824
+ });
6825
+ }
6826
+
6827
+ // src/utils/update-cache.ts
6828
+ init_esm_shims();
6829
+ init_paths();
6830
+ import { readFile as readFile7, writeFile as writeFile8, mkdir as mkdir8 } from "fs/promises";
6831
+ import { existsSync as existsSync5 } from "fs";
6832
+ import { join as join12 } from "path";
6833
+ var CACHE_FILE = ".update-cache.json";
6834
+ var DEFAULT_CACHE = {
6835
+ lastCheckTime: 0,
6836
+ lastCheckedVersion: "0.0.0",
6837
+ errorCount: 0
6838
+ };
6839
+ function getCachePath() {
6840
+ const configDir = paths.globalConfig();
6841
+ return join12(configDir, CACHE_FILE);
6842
+ }
6843
+ async function readCache() {
6844
+ try {
6845
+ const cachePath = getCachePath();
6846
+ if (!existsSync5(cachePath)) {
6847
+ return DEFAULT_CACHE;
6848
+ }
6849
+ const content = await readFile7(cachePath, "utf-8");
6850
+ const data = JSON.parse(content);
6851
+ return { ...DEFAULT_CACHE, ...data };
6852
+ } catch {
6853
+ return DEFAULT_CACHE;
6854
+ }
6855
+ }
6856
+ async function writeCache(data) {
6857
+ try {
6858
+ const cachePath = getCachePath();
6859
+ const configDir = paths.globalConfig();
6860
+ if (!existsSync5(configDir)) {
6861
+ await mkdir8(configDir, { recursive: true });
6862
+ }
6863
+ await writeFile8(cachePath, JSON.stringify(data, null, 2), "utf-8");
6864
+ } catch {
6865
+ }
6866
+ }
6867
+ async function setLastCheckTime(timestamp) {
6868
+ const cache = await readCache();
6869
+ cache.lastCheckTime = timestamp;
6870
+ await writeCache(cache);
6871
+ }
6872
+ async function setLastCheckedVersion(version) {
6873
+ const cache = await readCache();
6874
+ cache.lastCheckedVersion = version;
6875
+ await writeCache(cache);
6876
+ }
6877
+ async function setCompletedUpdate(version) {
6878
+ const cache = await readCache();
6879
+ cache.completedUpdate = version;
6880
+ cache.completedUpdateTime = Date.now();
6881
+ cache.errorCount = 0;
6882
+ cache.lastError = void 0;
6883
+ await writeCache(cache);
6884
+ }
6885
+ async function clearCompletedUpdate() {
6886
+ const cache = await readCache();
6887
+ cache.completedUpdate = void 0;
6888
+ cache.completedUpdateTime = void 0;
6889
+ await writeCache(cache);
6890
+ }
6891
+ async function incrementError(error) {
6892
+ const cache = await readCache();
6893
+ cache.errorCount += 1;
6894
+ cache.lastError = error;
6895
+ await writeCache(cache);
6896
+ }
6897
+
6898
+ // src/core/background-updater.ts
6899
+ init_esm_shims();
6900
+ init_paths();
6901
+ import { spawn } from "child_process";
6902
+ import { writeFile as writeFile9, mkdir as mkdir9 } from "fs/promises";
6903
+ import { join as join13 } from "path";
6904
+ async function spawnUpdateProcess(targetVersion) {
6905
+ try {
6906
+ const configDir = paths.globalConfig();
6907
+ const logsDir = join13(configDir, "logs");
6908
+ await mkdir9(logsDir, { recursive: true });
6909
+ const scriptContent = generateUpdateScript(targetVersion, logsDir);
6910
+ const scriptPath = join13(configDir, "update-script.js");
6911
+ await writeFile9(scriptPath, scriptContent, "utf-8");
6912
+ const child = spawn(process.execPath, [scriptPath], {
6913
+ detached: true,
6914
+ stdio: "ignore",
6915
+ windowsHide: true
6916
+ });
6917
+ child.unref();
6918
+ return true;
6919
+ } catch {
6920
+ return false;
6921
+ }
6922
+ }
6923
+ function generateUpdateScript(targetVersion, logsDir) {
6924
+ return `
6925
+ // AIKit Auto-Update Script
6926
+ // Generated automatically - DO NOT EDIT
6927
+
6928
+ const { spawn } = require('child_process');
6929
+ const { writeFile, appendFile } = require('fs').promises;
6930
+ const { join } = require('path');
6931
+
6932
+ const configDir = '${paths.globalConfig().replace(/\\/g, "\\\\")}';
6933
+ const logsDir = '${logsDir.replace(/\\/g, "\\\\")}';
6934
+ const cachePath = join(configDir, '.update-cache.json');
6935
+ const errorLogPath = join(logsDir, 'update-error.log');
6936
+ const targetVersion = '${targetVersion}';
6937
+
6938
+ async function logError(message) {
6939
+ const timestamp = new Date().toISOString();
6940
+ await appendFile(errorLogPath, \`[\${timestamp}] \${message}\\n\`);
6941
+ }
6942
+
6943
+ async function updateCache(version, error) {
6944
+ try {
6945
+ const fs = require('fs');
6946
+ let cache = { lastCheckTime: 0, lastCheckedVersion: '0.0.0', errorCount: 0 };
6947
+
6948
+ try {
6949
+ cache = JSON.parse(fs.readFileSync(cachePath, 'utf-8'));
6950
+ } catch {}
6951
+
6952
+ if (error) {
6953
+ cache.errorCount = (cache.errorCount || 0) + 1;
6954
+ cache.lastError = error;
6955
+ } else {
6956
+ cache.completedUpdate = version;
6957
+ cache.completedUpdateTime = Date.now();
6958
+ cache.errorCount = 0;
6959
+ cache.lastError = undefined;
6960
+ }
6961
+
6962
+ await writeFile(cachePath, JSON.stringify(cache, null, 2));
6963
+ } catch {}
6964
+ }
6965
+
6966
+ async function runUpdate() {
6967
+ return new Promise((resolve) => {
6968
+ const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
6969
+ const child = spawn(npmCmd, ['install', '-g', '@tdsoft-tech/aikit@latest'], {
6970
+ stdio: 'pipe',
6971
+ });
6972
+
6973
+ let output = '';
6974
+ let errorOutput = '';
6975
+
6976
+ child.stdout.on('data', (data) => {
6977
+ output += data.toString();
6978
+ });
6979
+
6980
+ child.stderr.on('data', (data) => {
6981
+ errorOutput += data.toString();
6982
+ });
6983
+
6984
+ child.on('close', async (code) => {
6985
+ if (code === 0) {
6986
+ await updateCache(targetVersion, null);
6987
+ resolve(true);
6988
+ } else {
6989
+ const errorMsg = errorOutput || 'npm install failed';
6990
+ await logError(\`Update failed (code \${code}): \${errorMsg}\`);
6991
+ await updateCache(targetVersion, errorMsg);
6992
+ resolve(false);
6993
+ }
6994
+ });
6995
+
6996
+ child.on('error', async (err) => {
6997
+ await logError(\`Update error: \${err.message}\`);
6998
+ await updateCache(targetVersion, err.message);
6999
+ resolve(false);
7000
+ });
7001
+ });
7002
+ }
7003
+
7004
+ // Run update and exit
7005
+ runUpdate().then(() => process.exit(0));
7006
+ `;
7007
+ }
7008
+
7009
+ // src/core/update-manager.ts
7010
+ var CHECK_INTERVAL = 24 * 60 * 60 * 1e3;
7011
+ var PACKAGE_NAME = "@tdsoft-tech/aikit";
7012
+ async function shouldCheckForUpdates() {
7013
+ const cache = await readCache();
7014
+ const now = Date.now();
7015
+ return now - cache.lastCheckTime > CHECK_INTERVAL;
7016
+ }
7017
+ async function displayNotification() {
7018
+ const cache = await readCache();
7019
+ if (cache.completedUpdate) {
7020
+ const currentVersion = getVersion();
7021
+ if (isGreaterThan(cache.completedUpdate, currentVersion)) {
7022
+ console.log(chalk2.cyan.bold("\n\u2728 AIKit has been updated!\n"));
7023
+ console.log(chalk2.gray(` Version: ${currentVersion} \u2192 ${cache.completedUpdate}`));
7024
+ console.log(chalk2.gray(` Updated: Just now
7025
+ `));
7026
+ console.log(chalk2.gray("Run 'aikit --version' to verify.\n"));
7027
+ await clearCompletedUpdate();
7028
+ }
7029
+ }
7030
+ if (cache.errorCount >= 3 && cache.lastError) {
7031
+ console.log(chalk2.yellow.bold("\n\u26A0\uFE0F AIKit update failed\n"));
7032
+ console.log(chalk2.gray(` Last error: ${cache.lastError}`));
7033
+ console.log(chalk2.gray(" Check logs: ~/.config/aikit/logs/update-error.log\n"));
7034
+ }
7035
+ }
7036
+ async function performBackgroundUpdate(latestVersion) {
7037
+ const success = await spawnUpdateProcess(latestVersion);
7038
+ if (!success) {
7039
+ await incrementError("Failed to spawn update process");
7040
+ } else {
7041
+ await setCompletedUpdate(latestVersion);
7042
+ }
7043
+ }
7044
+ async function checkForUpdates() {
7045
+ try {
7046
+ await displayNotification();
7047
+ if (!await shouldCheckForUpdates()) {
7048
+ return;
7049
+ }
7050
+ const currentVersion = getVersion();
7051
+ const latestVersion = await getLatestVersion(PACKAGE_NAME);
7052
+ await setLastCheckTime(Date.now());
7053
+ await setLastCheckedVersion(currentVersion);
7054
+ if (!latestVersion || !isGreaterThan(latestVersion, currentVersion)) {
7055
+ return;
7056
+ }
7057
+ await performBackgroundUpdate(latestVersion);
7058
+ } catch {
7059
+ }
7060
+ }
7061
+ async function checkForUpdatesAsync() {
7062
+ checkForUpdates().catch(() => {
7063
+ });
7064
+ }
7065
+
6600
7066
  // src/index.ts
6601
7067
  init_logger();
6602
7068
  init_paths();
@@ -6608,15 +7074,15 @@ init_esm_shims();
6608
7074
  // src/cli/commands/init.ts
6609
7075
  init_esm_shims();
6610
7076
  init_config();
6611
- import chalk2 from "chalk";
7077
+ import chalk3 from "chalk";
6612
7078
  import inquirer from "inquirer";
6613
7079
  init_beads();
6614
7080
 
6615
7081
  // src/utils/cli-detector.ts
6616
7082
  init_esm_shims();
6617
7083
  import { execSync } from "child_process";
6618
- import { existsSync as existsSync5 } from "fs";
6619
- import { join as join12 } from "path";
7084
+ import { existsSync as existsSync6 } from "fs";
7085
+ import { join as join14 } from "path";
6620
7086
  import { homedir as homedir2 } from "os";
6621
7087
  var CliPlatform = /* @__PURE__ */ ((CliPlatform2) => {
6622
7088
  CliPlatform2["OPENCODE"] = "opencode";
@@ -6630,16 +7096,16 @@ var CliDetector = class {
6630
7096
  */
6631
7097
  static async checkOpenCode() {
6632
7098
  try {
6633
- const opencodePath = process.platform === "win32" ? process.env.APPDATA || join12(homedir2(), "AppData", "Roaming") : join12(homedir2(), ".config");
6634
- const opencodeConfig = join12(opencodePath, "opencode", "opencode.json");
6635
- let installed = existsSync5(opencodeConfig);
7099
+ const opencodePath = process.platform === "win32" ? process.env.APPDATA || join14(homedir2(), "AppData", "Roaming") : join14(homedir2(), ".config");
7100
+ const opencodeConfig = join14(opencodePath, "opencode", "opencode.json");
7101
+ let installed = existsSync6(opencodeConfig);
6636
7102
  let version;
6637
7103
  if (installed) {
6638
7104
  try {
6639
7105
  execSync("opencode --version", { stdio: "ignore" });
6640
7106
  version = "installed";
6641
7107
  } catch (error) {
6642
- if (existsSync5(opencodeConfig)) {
7108
+ if (existsSync6(opencodeConfig)) {
6643
7109
  version = "installed (config exists)";
6644
7110
  } else {
6645
7111
  installed = false;
@@ -6736,18 +7202,18 @@ var CliDetector = class {
6736
7202
  */
6737
7203
  static async detectPlatforms() {
6738
7204
  const platforms = [];
6739
- const opencodePath = process.platform === "win32" ? process.env.APPDATA || join12(homedir2(), "AppData", "Roaming") : join12(homedir2(), ".config");
7205
+ const opencodePath = process.platform === "win32" ? process.env.APPDATA || join14(homedir2(), "AppData", "Roaming") : join14(homedir2(), ".config");
6740
7206
  platforms.push({
6741
7207
  platform: "opencode" /* OPENCODE */,
6742
7208
  displayName: "OpenCode",
6743
- installed: existsSync5(join12(opencodePath, "opencode", "opencode.json")),
7209
+ installed: existsSync6(join14(opencodePath, "opencode", "opencode.json")),
6744
7210
  configPath: opencodePath
6745
7211
  });
6746
- const claudePath = process.platform === "win32" ? process.env.APPDATA || join12(homedir2(), "AppData", "Roaming") : join12(homedir2(), ".claude");
7212
+ const claudePath = process.platform === "win32" ? process.env.APPDATA || join14(homedir2(), "AppData", "Roaming") : join14(homedir2(), ".claude");
6747
7213
  platforms.push({
6748
7214
  platform: "claude" /* CLAUDE */,
6749
7215
  displayName: "Claude Code CLI",
6750
- installed: existsSync5(claudePath),
7216
+ installed: existsSync6(claudePath),
6751
7217
  configPath: claudePath
6752
7218
  });
6753
7219
  return platforms;
@@ -6780,9 +7246,9 @@ init_paths();
6780
7246
 
6781
7247
  // src/cli/helpers.ts
6782
7248
  init_esm_shims();
6783
- import { existsSync as existsSync6 } from "fs";
6784
- import { mkdir as mkdir9, writeFile as writeFile9, readFile as readFile8, access as access5 } from "fs/promises";
6785
- import { join as join14, dirname as dirname2 } from "path";
7249
+ import { existsSync as existsSync7 } from "fs";
7250
+ import { mkdir as mkdir11, writeFile as writeFile11, readFile as readFile9, access as access5 } from "fs/promises";
7251
+ import { join as join16, dirname as dirname2 } from "path";
6786
7252
  import { homedir as homedir3 } from "os";
6787
7253
  import { fileURLToPath as fileURLToPath3 } from "url";
6788
7254
  import { execSync as execSync2 } from "child_process";
@@ -6808,7 +7274,7 @@ async function initializeConfig(configDir, _isGlobal) {
6808
7274
  "memory/research"
6809
7275
  ];
6810
7276
  for (const dir of dirs) {
6811
- await mkdir9(join14(configDir, dir), { recursive: true });
7277
+ await mkdir11(join16(configDir, dir), { recursive: true });
6812
7278
  }
6813
7279
  const defaultConfig = {
6814
7280
  version: getVersion(),
@@ -6821,8 +7287,8 @@ async function initializeConfig(configDir, _isGlobal) {
6821
7287
  beads: { enabled: true },
6822
7288
  antiHallucination: { enabled: true }
6823
7289
  };
6824
- await writeFile9(
6825
- join14(configDir, "aikit.json"),
7290
+ await writeFile11(
7291
+ join16(configDir, "aikit.json"),
6826
7292
  JSON.stringify(defaultConfig, null, 2)
6827
7293
  );
6828
7294
  const agentsMd = `# AIKit Agent Rules
@@ -6845,20 +7311,20 @@ async function initializeConfig(configDir, _isGlobal) {
6845
7311
  ## Project-Specific Rules
6846
7312
  Add your project-specific rules here.
6847
7313
  `;
6848
- await writeFile9(join14(configDir, "AGENTS.md"), agentsMd);
7314
+ await writeFile11(join16(configDir, "AGENTS.md"), agentsMd);
6849
7315
  }
6850
7316
  async function configureMcpServer(projectPath) {
6851
7317
  const currentFile = fileURLToPath3(import.meta.url);
6852
7318
  const currentDir = dirname2(currentFile);
6853
- const aikitPath = join14(currentDir, "..", "..");
6854
- const mcpServerPath = join14(aikitPath, "dist", "mcp-server.js");
7319
+ const aikitPath = join16(currentDir, "..", "..");
7320
+ const mcpServerPath = join16(aikitPath, "dist", "mcp-server.js");
6855
7321
  const configLocations = [
6856
7322
  // Global config (most common)
6857
- join14(homedir3(), ".config", "opencode", "opencode.json"),
7323
+ join16(homedir3(), ".config", "opencode", "opencode.json"),
6858
7324
  // Project-level config
6859
- join14(projectPath, ".opencode", "opencode.json"),
7325
+ join16(projectPath, ".opencode", "opencode.json"),
6860
7326
  // Alternative global location
6861
- join14(homedir3(), ".opencode", "opencode.json")
7327
+ join16(homedir3(), ".opencode", "opencode.json")
6862
7328
  ];
6863
7329
  const mcpServerConfig = {
6864
7330
  type: "local",
@@ -6867,12 +7333,12 @@ async function configureMcpServer(projectPath) {
6867
7333
  };
6868
7334
  for (const configPath of configLocations) {
6869
7335
  try {
6870
- const configDir = join14(configPath, "..");
6871
- await mkdir9(configDir, { recursive: true });
7336
+ const configDir = join16(configPath, "..");
7337
+ await mkdir11(configDir, { recursive: true });
6872
7338
  let config = {};
6873
- if (existsSync6(configPath)) {
7339
+ if (existsSync7(configPath)) {
6874
7340
  try {
6875
- const existing = await readFile8(configPath, "utf-8");
7341
+ const existing = await readFile9(configPath, "utf-8");
6876
7342
  config = JSON.parse(existing);
6877
7343
  } catch {
6878
7344
  config = {};
@@ -6882,7 +7348,7 @@ async function configureMcpServer(projectPath) {
6882
7348
  config.mcp = {};
6883
7349
  }
6884
7350
  config.mcp.aikit = mcpServerConfig;
6885
- await writeFile9(configPath, JSON.stringify(config, null, 2));
7351
+ await writeFile11(configPath, JSON.stringify(config, null, 2));
6886
7352
  logger.success(`
6887
7353
  \u2705 MCP server configured: ${configPath}`);
6888
7354
  logger.info(` Server: node ${mcpServerPath}`);
@@ -6891,9 +7357,9 @@ async function configureMcpServer(projectPath) {
6891
7357
  continue;
6892
7358
  }
6893
7359
  }
6894
- const instructionsPath = join14(projectPath, ".opencode", "MCP_SETUP.md");
6895
- await mkdir9(join14(projectPath, ".opencode"), { recursive: true });
6896
- await writeFile9(instructionsPath, `# AIKit MCP Server Configuration
7360
+ const instructionsPath = join16(projectPath, ".opencode", "MCP_SETUP.md");
7361
+ await mkdir11(join16(projectPath, ".opencode"), { recursive: true });
7362
+ await writeFile11(instructionsPath, `# AIKit MCP Server Configuration
6897
7363
 
6898
7364
  ## Automatic Setup Failed
6899
7365
 
@@ -7146,26 +7612,26 @@ Report what was extracted:
7146
7612
  }
7147
7613
  async function installToOpenCode(_opencodePath) {
7148
7614
  const projectPath = process.cwd();
7149
- const opencodeCommandDir = join14(projectPath, ".opencode", "command");
7150
- const aikitDir = join14(projectPath, ".aikit");
7151
- const opencodeAgentDir = join14(paths.opencodeConfig(), "agent");
7152
- await mkdir9(opencodeCommandDir, { recursive: true });
7153
- await mkdir9(join14(aikitDir, "skills"), { recursive: true });
7154
- await mkdir9(opencodeAgentDir, { recursive: true });
7615
+ const opencodeCommandDir = join16(projectPath, ".opencode", "command");
7616
+ const aikitDir = join16(projectPath, ".aikit");
7617
+ const opencodeAgentDir = join16(paths.opencodeConfig(), "agent");
7618
+ await mkdir11(opencodeCommandDir, { recursive: true });
7619
+ await mkdir11(join16(aikitDir, "skills"), { recursive: true });
7620
+ await mkdir11(opencodeAgentDir, { recursive: true });
7155
7621
  for (const [name, content] of Object.entries(AGENT_FILES)) {
7156
- const filePath = join14(opencodeAgentDir, `${name}.md`);
7622
+ const filePath = join16(opencodeAgentDir, `${name}.md`);
7157
7623
  try {
7158
7624
  await access5(filePath);
7159
- const existingContent = await readFile8(filePath, "utf8");
7625
+ const existingContent = await readFile9(filePath, "utf8");
7160
7626
  if (!existingContent.includes("mode: subagent")) {
7161
7627
  const matter5 = await import("gray-matter");
7162
7628
  const { data: frontmatter, content: body } = matter5.default(existingContent);
7163
7629
  frontmatter.mode = "subagent";
7164
7630
  const updatedContent = matter5.default.stringify(body, frontmatter);
7165
- await writeFile9(filePath, updatedContent, "utf8");
7631
+ await writeFile11(filePath, updatedContent, "utf8");
7166
7632
  }
7167
7633
  } catch {
7168
- await writeFile9(filePath, content, "utf8");
7634
+ await writeFile11(filePath, content, "utf8");
7169
7635
  }
7170
7636
  }
7171
7637
  const config = await loadConfig();
@@ -7174,8 +7640,8 @@ async function installToOpenCode(_opencodePath) {
7174
7640
  const skills = await skillEngine.listSkills();
7175
7641
  const commands = await commandRunner.listCommands();
7176
7642
  const opencodeCommands = {};
7177
- const skillsList = skills.map((s) => `| \`/ak_sk_${s.name.replace(/\s+/g, "-")}\` | ${s.description} |`).join("\n");
7178
- opencodeCommands["ak_cm_skills"] = `List all available AIKit skills and how to use them.
7643
+ const skillsList = skills.map((s) => `| \`/${s.name.replace(/\s+/g, "-")}\` | ${s.description} |`).join("\n");
7644
+ opencodeCommands["skills"] = `List all available AIKit skills and how to use them.
7179
7645
 
7180
7646
  READ .aikit/AGENTS.md
7181
7647
 
@@ -7185,9 +7651,9 @@ READ .aikit/AGENTS.md
7185
7651
  |---------|-------------|
7186
7652
  ${skillsList}
7187
7653
 
7188
- Type any command to use that skill. For example: \`/ak_sk_test-driven-development\``;
7654
+ Type any command to use that skill. For example: \`/test-driven-development\``;
7189
7655
  for (const skill of skills) {
7190
- const commandName = `ak_sk_${skill.name.replace(/\s+/g, "-").toLowerCase()}`;
7656
+ const commandName = skill.name.replace(/\s+/g, "-").toLowerCase();
7191
7657
  const skillPath = skill.filePath;
7192
7658
  const relativePath = skillPath.startsWith(projectPath) ? skillPath.replace(projectPath, "").replace(/\\/g, "/").replace(/^\//, "") : `.aikit/skills/${skill.name.replace(/\s+/g, "-").toLowerCase()}.md`;
7193
7659
  const useWhen = skill.useWhen || `The user asks you to ${skill.name}`;
@@ -7209,21 +7675,20 @@ Complete the checklist at the end of the skill.`;
7209
7675
  }
7210
7676
  for (const cmd of commands) {
7211
7677
  if (opencodeCommands[cmd.name]) continue;
7212
- const commandName = `ak_cm_${cmd.name.replace(/\//g, "").replace(/\s+/g, "-")}`;
7678
+ const commandName = cmd.name.replace(/\//g, "").replace(/\s+/g, "-");
7213
7679
  const examples = cmd.examples.map((e) => {
7214
- const prefixed = e.replace(/\//g, "/ak_cm_");
7215
- return `- \`${prefixed}\``;
7680
+ return `- \`${e}\``;
7216
7681
  }).join("\n");
7217
7682
  if (cmd.name === "analyze-figma") {
7218
7683
  opencodeCommands[commandName] = generateAnalyzeFigmaCommand();
7219
7684
  } else {
7220
- opencodeCommands[commandName] = `# Command: /ak_cm_${cmd.name}
7685
+ opencodeCommands[commandName] = `# Command: /${cmd.name}
7221
7686
 
7222
7687
  ## Description
7223
7688
  ${cmd.description}
7224
7689
 
7225
7690
  ## Usage
7226
- \`${cmd.usage.replace(/\//g, "/ak_cm_")}\`
7691
+ \`${cmd.usage}\`
7227
7692
 
7228
7693
  ## Examples
7229
7694
  ${examples}
@@ -7241,8 +7706,8 @@ The arguments are available in this command response - look at the command workf
7241
7706
  4. They have already provided it - extract and use it!
7242
7707
 
7243
7708
  **Example Scenario**:
7244
- - User runs: \`/ak_cm_${cmd.name} snake game with html & css\`
7245
- - Command: \`/ak_cm_${cmd.name}\`
7709
+ - User runs: \`/${cmd.name} snake game with html & css\`
7710
+ - Command: \`/${cmd.name}\`
7246
7711
  - Arguments to use: \`snake game with html & css\`
7247
7712
  - You must use "snake game with html & css" as provided in the workflow!
7248
7713
 
@@ -7257,8 +7722,8 @@ ${cmd.content}
7257
7722
  }
7258
7723
  let count = 0;
7259
7724
  for (const [name, content] of Object.entries(opencodeCommands)) {
7260
- const filePath = join14(opencodeCommandDir, `${name}.md`);
7261
- await writeFile9(filePath, content.trim());
7725
+ const filePath = join16(opencodeCommandDir, `${name}.md`);
7726
+ await writeFile11(filePath, content.trim());
7262
7727
  logger.info(` \u2713 Created /${name} command`);
7263
7728
  count++;
7264
7729
  }
@@ -7267,8 +7732,8 @@ Created ${count} OpenCode commands in .opencode/command/`);
7267
7732
  await configureMcpServer(projectPath);
7268
7733
  logger.info("\nUsage in OpenCode:");
7269
7734
  logger.info(" Press Ctrl+K to open command picker");
7270
- logger.info(" Or type /ak_cm_skills to see all available skills");
7271
- logger.info(` Available: ${skills.length} skills (ak_sk_*), ${commands.length} commands (ak_cm_*)`);
7735
+ logger.info(" Or type /skills to see all available skills");
7736
+ logger.info(` Available: ${skills.length} skills, ${commands.length} commands`);
7272
7737
  logger.info(" MCP server configured - tools available via MCP protocol");
7273
7738
  }
7274
7739
  function groupBy(array, keyFn) {
@@ -7295,9 +7760,15 @@ async function startSession(name, goals) {
7295
7760
  console.log("\nCommands:");
7296
7761
  console.log(" /session:update [notes] - Add progress notes");
7297
7762
  console.log(" /session:end - End session with summary");
7298
- console.log(" /session:current - Show session status\n");
7763
+ console.log(" /session:current - Show session status");
7764
+ console.log(" /session:use <id> - Switch to a different session\n");
7299
7765
  } catch (error) {
7300
- logger.error("Failed to start session:", error);
7766
+ if (error instanceof Error && error.message.includes("not initialized")) {
7767
+ logger.error(error.message);
7768
+ console.log('Run "aikit init" first to initialize AIKit in this directory.\n');
7769
+ } else {
7770
+ logger.error("Failed to start session:", error);
7771
+ }
7301
7772
  }
7302
7773
  }
7303
7774
  async function updateSession(notes) {
@@ -7317,7 +7788,10 @@ async function updateSession(notes) {
7317
7788
  console.log();
7318
7789
  }
7319
7790
  } catch (error) {
7320
- if (error instanceof Error && error.message.includes("No active session")) {
7791
+ if (error instanceof Error && error.message.includes("not initialized")) {
7792
+ logger.error(error.message);
7793
+ console.log('Run "aikit init" first to initialize AIKit in this directory.\n');
7794
+ } else if (error instanceof Error && error.message.includes("No active session")) {
7321
7795
  logger.error("No active session. Use /session:start first");
7322
7796
  } else {
7323
7797
  logger.error("Failed to update session:", error);
@@ -7356,7 +7830,10 @@ Use /session:show ${session.id} for details
7356
7830
  `);
7357
7831
  }
7358
7832
  } catch (error) {
7359
- if (error instanceof Error && error.message.includes("No active session")) {
7833
+ if (error instanceof Error && error.message.includes("not initialized")) {
7834
+ logger.error(error.message);
7835
+ console.log('Run "aikit init" first to initialize AIKit in this directory.\n');
7836
+ } else if (error instanceof Error && error.message.includes("No active session")) {
7360
7837
  logger.error("No active session. Use /session:start first");
7361
7838
  } else {
7362
7839
  logger.error("Failed to end session:", error);
@@ -7374,12 +7851,16 @@ async function showCurrentSession() {
7374
7851
  return;
7375
7852
  }
7376
7853
  const duration = Math.floor((Date.now() - new Date(session.startTime).getTime()) / 6e4);
7854
+ const terminalInfo = await manager.getTerminalInfo();
7377
7855
  console.log("\n\u{1F4CD} Current Session");
7378
7856
  console.log("\u2501".repeat(60));
7379
7857
  console.log(`
7380
7858
  Session: ${session.name}`);
7381
7859
  console.log(`ID: ${session.id}`);
7382
7860
  console.log(`Started: ${Math.floor(duration / 60)}h ${duration % 60}m ago`);
7861
+ if (terminalInfo.tty) {
7862
+ console.log(`Terminal: ${terminalInfo.tty}`);
7863
+ }
7383
7864
  if (session.goals.length > 0) {
7384
7865
  console.log(`
7385
7866
  Goals:`);
@@ -7411,10 +7892,16 @@ Beads Task:`);
7411
7892
  }
7412
7893
  console.log("\nCommands:");
7413
7894
  console.log(" /session:update [notes] - Add progress");
7895
+ console.log(" /session:use <id> - Switch to another session");
7414
7896
  console.log(" /session:end - Close session");
7415
7897
  console.log("\u2501".repeat(60) + "\n");
7416
7898
  } catch (error) {
7417
- logger.error("Failed to show current session:", error);
7899
+ if (error instanceof Error && error.message.includes("not initialized")) {
7900
+ logger.error(error.message);
7901
+ console.log('Run "aikit init" first to initialize AIKit in this directory.\n');
7902
+ } else {
7903
+ logger.error("Failed to show current session:", error);
7904
+ }
7418
7905
  }
7419
7906
  }
7420
7907
  async function listSessions() {
@@ -7455,7 +7942,12 @@ Total: ${sessions.length} session${sessions.length > 1 ? "s" : ""}
7455
7942
  console.log(" /session:resume <id> - Resume session");
7456
7943
  console.log(" /session:search <query> - Search sessions\n");
7457
7944
  } catch (error) {
7458
- logger.error("Failed to list sessions:", error);
7945
+ if (error instanceof Error && error.message.includes("not initialized")) {
7946
+ logger.error(error.message);
7947
+ console.log('Run "aikit init" first to initialize AIKit in this directory.\n');
7948
+ } else {
7949
+ logger.error("Failed to list sessions:", error);
7950
+ }
7459
7951
  }
7460
7952
  }
7461
7953
  async function showSession(sessionId) {
@@ -7513,7 +8005,12 @@ Goals:`);
7513
8005
  }
7514
8006
  console.log("\n" + "\u2501".repeat(60) + "\n");
7515
8007
  } catch (error) {
7516
- logger.error("Failed to show session:", error);
8008
+ if (error instanceof Error && error.message.includes("not initialized")) {
8009
+ logger.error(error.message);
8010
+ console.log('Run "aikit init" first to initialize AIKit in this directory.\n');
8011
+ } else {
8012
+ logger.error("Failed to show session:", error);
8013
+ }
7517
8014
  }
7518
8015
  }
7519
8016
  async function searchSessions(query) {
@@ -7551,9 +8048,84 @@ Total: ${sessions.length} matching session${sessions.length > 1 ? "s" : ""}
7551
8048
  console.log(" /session:show <id> - View session details");
7552
8049
  console.log(" /session:resume <id> - Resume session\n");
7553
8050
  } catch (error) {
7554
- logger.error("Failed to search sessions:", error);
8051
+ if (error instanceof Error && error.message.includes("not initialized")) {
8052
+ logger.error(error.message);
8053
+ console.log('Run "aikit init" first to initialize AIKit in this directory.\n');
8054
+ } else {
8055
+ logger.error("Failed to search sessions:", error);
8056
+ }
7555
8057
  }
7556
8058
  }
8059
+ async function resumeSession(sessionId) {
8060
+ try {
8061
+ const { SessionManager: SessionManager2 } = await Promise.resolve().then(() => (init_sessions(), sessions_exports));
8062
+ const manager = new SessionManager2();
8063
+ const session = await manager.resumeSession(sessionId);
8064
+ logger.success("\u2713 Session resumed");
8065
+ console.log(` ID: ${session.id}`);
8066
+ console.log(` Name: ${session.name}`);
8067
+ console.log(` Status: ${session.status}`);
8068
+ console.log(` Started: ${new Date(session.startTime).toLocaleString()}`);
8069
+ if (session.goals.length > 0) {
8070
+ console.log(` Goals:`);
8071
+ session.goals.forEach((goal) => console.log(` - ${goal}`));
8072
+ }
8073
+ console.log("\nCommands:");
8074
+ console.log(" /session:update [notes] - Add progress notes");
8075
+ console.log(" /session:end - End session with summary");
8076
+ console.log(" /session:current - Show session status");
8077
+ console.log(" /session:use <id> - Switch to a different session\n");
8078
+ } catch (error) {
8079
+ if (error instanceof Error && error.message.includes("not initialized")) {
8080
+ logger.error(error.message);
8081
+ console.log('Run "aikit init" first to initialize AIKit in this directory.\n');
8082
+ } else if (error instanceof Error && error.message.includes("not found")) {
8083
+ logger.error(error.message);
8084
+ console.log("Use /session:list to see all sessions\n");
8085
+ } else {
8086
+ logger.error("Failed to resume session:", error);
8087
+ }
8088
+ }
8089
+ }
8090
+ async function switchSession(sessionId) {
8091
+ try {
8092
+ const { SessionManager: SessionManager2 } = await Promise.resolve().then(() => (init_sessions(), sessions_exports));
8093
+ const manager = new SessionManager2();
8094
+ const session = await manager.getSession(sessionId);
8095
+ if (!session) {
8096
+ logger.error(`Session not found: ${sessionId}`);
8097
+ console.log("Use /session:list to see all sessions\n");
8098
+ return;
8099
+ }
8100
+ await manager.switchSession(sessionId);
8101
+ logger.success("\u2713 Switched to session");
8102
+ console.log(` ID: ${session.id}`);
8103
+ console.log(` Name: ${session.name}`);
8104
+ console.log(` Status: ${session.status}`);
8105
+ console.log(` Started: ${new Date(session.startTime).toLocaleString()}`);
8106
+ if (session.goals.length > 0) {
8107
+ console.log(` Goals:`);
8108
+ session.goals.forEach((goal) => console.log(` - ${goal}`));
8109
+ }
8110
+ console.log("\nCommands:");
8111
+ console.log(" /session:update [notes] - Add progress notes");
8112
+ console.log(" /session:end - End session with summary");
8113
+ console.log(" /session:current - Show session status\n");
8114
+ } catch (error) {
8115
+ if (error instanceof Error && error.message.includes("not initialized")) {
8116
+ logger.error(error.message);
8117
+ console.log('Run "aikit init" first to initialize AIKit in this directory.\n');
8118
+ } else if (error instanceof Error && error.message.includes("not found")) {
8119
+ logger.error(error.message);
8120
+ console.log("Use /session:list to see all sessions\n");
8121
+ } else {
8122
+ logger.error("Failed to switch session:", error);
8123
+ }
8124
+ }
8125
+ }
8126
+
8127
+ // src/cli/commands/init.ts
8128
+ init_sessions();
7557
8129
 
7558
8130
  // src/platform/adapters.ts
7559
8131
  init_esm_shims();
@@ -7561,33 +8133,31 @@ init_esm_shims();
7561
8133
  // src/platform/opencode-adapter.ts
7562
8134
  init_esm_shims();
7563
8135
  init_paths();
7564
- import { readFile as readFile9, writeFile as writeFile10, mkdir as mkdir10, access as access6 } from "fs/promises";
7565
- import { join as join15 } from "path";
8136
+ import { readFile as readFile10, writeFile as writeFile12, mkdir as mkdir12, access as access6 } from "fs/promises";
8137
+ import { join as join17 } from "path";
7566
8138
  var OpenCodeAdapter = class {
7567
8139
  platform = "opencode" /* OPENCODE */;
7568
8140
  displayName = "OpenCode";
7569
8141
  getCommandsDir() {
7570
- return join15(process.cwd(), ".opencode", "command");
8142
+ return join17(process.cwd(), ".opencode", "command");
7571
8143
  }
7572
8144
  getSkillsDir() {
7573
- return join15(process.cwd(), ".opencode", "skill");
8145
+ return join17(process.cwd(), ".opencode", "skill");
7574
8146
  }
7575
8147
  getAgentsDir() {
7576
- return join15(paths.opencodeConfig(), "agent");
8148
+ return join17(paths.opencodeConfig(), "agent");
7577
8149
  }
7578
8150
  async transformCommand(command) {
7579
- const sanitizedName = command.name.replace(/:/g, "-");
7580
- const name = `ak_cm_${sanitizedName}`;
8151
+ const name = command.name.replace(/:/g, "-");
7581
8152
  const content = this.generateCommandContent(command);
7582
8153
  return { name, content };
7583
8154
  }
7584
8155
  async transformSkill(skill) {
7585
- const skillName = `ak_sk_${skill.name}`;
7586
8156
  const skillContent = this.generateSkillContent(skill);
7587
8157
  const result = {
7588
- name: skillName,
8158
+ name: skill.name,
7589
8159
  directory: "",
7590
- files: { [`${skillName}.md`]: skillContent }
8160
+ files: { [`${skill.name}.md`]: skillContent }
7591
8161
  };
7592
8162
  return result;
7593
8163
  }
@@ -7598,47 +8168,46 @@ var OpenCodeAdapter = class {
7598
8168
  }
7599
8169
  async installCommand(name, content) {
7600
8170
  const dir = this.getCommandsDir();
7601
- await mkdir10(dir, { recursive: true });
7602
- await writeFile10(join15(dir, `${name}.md`), content);
8171
+ await mkdir12(dir, { recursive: true });
8172
+ await writeFile12(join17(dir, `${name}.md`), content);
7603
8173
  }
7604
8174
  async installSkill(_name, directory, files) {
7605
8175
  const baseDir = this.getSkillsDir();
7606
- const targetDir = directory ? join15(baseDir, directory) : baseDir;
7607
- await mkdir10(targetDir, { recursive: true });
8176
+ const targetDir = directory ? join17(baseDir, directory) : baseDir;
8177
+ await mkdir12(targetDir, { recursive: true });
7608
8178
  for (const [filename, content] of Object.entries(files)) {
7609
- await writeFile10(join15(targetDir, filename), content);
8179
+ await writeFile12(join17(targetDir, filename), content);
7610
8180
  }
7611
8181
  }
7612
8182
  async installAgent(name, content) {
7613
8183
  const dir = this.getAgentsDir();
7614
- await mkdir10(dir, { recursive: true });
7615
- const filePath = join15(dir, `${name}.md`);
8184
+ await mkdir12(dir, { recursive: true });
8185
+ const filePath = join17(dir, `${name}.md`);
7616
8186
  try {
7617
8187
  await access6(filePath);
7618
- const existingContent = await readFile9(filePath, "utf-8");
8188
+ const existingContent = await readFile10(filePath, "utf-8");
7619
8189
  if (!existingContent.includes("mode: subagent")) {
7620
8190
  const matter5 = await import("gray-matter");
7621
8191
  const { data: frontmatter, content: body } = matter5.default(existingContent);
7622
8192
  frontmatter.mode = "subagent";
7623
8193
  const updatedContent = matter5.default.stringify(body, frontmatter);
7624
- await writeFile10(filePath, updatedContent, "utf-8");
8194
+ await writeFile12(filePath, updatedContent, "utf-8");
7625
8195
  }
7626
8196
  } catch {
7627
- await writeFile10(filePath, content, "utf-8");
8197
+ await writeFile12(filePath, content, "utf-8");
7628
8198
  }
7629
8199
  }
7630
8200
  generateCommandContent(command) {
7631
8201
  const examples = command.examples.map((e) => {
7632
- const prefixed = e.replace(/\//g, "/ak_cm_");
7633
- return `- \`${prefixed}\``;
8202
+ return `- \`${e}\``;
7634
8203
  }).join("\n");
7635
- return `# Command: /ak_cm_${command.name}
8204
+ return `# Command: /${command.name}
7636
8205
 
7637
8206
  ## Description
7638
8207
  ${command.description}
7639
8208
 
7640
8209
  ## Usage
7641
- \`${command.usage.replace(/\//g, "/ak_cm_")}\`
8210
+ \`${command.usage}\`
7642
8211
 
7643
8212
  ## Examples
7644
8213
  ${examples}
@@ -7656,8 +8225,8 @@ The arguments are available in this command response - look at the command workf
7656
8225
  4. They have already provided it - extract and use it!
7657
8226
 
7658
8227
  **Example Scenario**:
7659
- - User runs: \`/ak_cm_${command.name} snake game with html & css\`
7660
- - Command: \`/ak_cm_${command.name}\`
8228
+ - User runs: \`/${command.name} snake game with html & css\`
8229
+ - Command: \`/${command.name}\`
7661
8230
  - Arguments to use: \`snake game with html & css\`
7662
8231
  - You must use "snake game with html & css" as provided in the workflow!
7663
8232
 
@@ -7700,12 +8269,14 @@ ${agent.systemPrompt}`;
7700
8269
  // src/platform/claude-adapter.ts
7701
8270
  init_esm_shims();
7702
8271
  init_paths();
7703
- import { writeFile as writeFile11, mkdir as mkdir11 } from "fs/promises";
7704
- import { join as join16 } from "path";
8272
+ import { writeFile as writeFile13, mkdir as mkdir13 } from "fs/promises";
8273
+ import { join as join18 } from "path";
7705
8274
  import matter4 from "gray-matter";
7706
8275
  var ClaudeAdapter = class {
7707
8276
  platform = "claude" /* CLAUDE */;
7708
8277
  displayName = "Claude Code CLI";
8278
+ // Track installed commands for manifest generation
8279
+ installedCommands = [];
7709
8280
  getCommandsDir() {
7710
8281
  return paths.claudeCommands(true);
7711
8282
  }
@@ -7736,26 +8307,27 @@ var ClaudeAdapter = class {
7736
8307
  }
7737
8308
  async installCommand(name, content) {
7738
8309
  const dir = this.getCommandsDir();
7739
- await mkdir11(dir, { recursive: true });
7740
- await writeFile11(join16(dir, `${name}.md`), content);
8310
+ await mkdir13(dir, { recursive: true });
8311
+ await writeFile13(join18(dir, `${name}.md`), content);
8312
+ this.installedCommands.push(name);
7741
8313
  }
7742
8314
  async installSkill(_name, directory, files) {
7743
8315
  const baseDir = this.getSkillsDir();
7744
- const targetDir = join16(baseDir, directory);
7745
- await mkdir11(targetDir, { recursive: true });
8316
+ const targetDir = join18(baseDir, directory);
8317
+ await mkdir13(targetDir, { recursive: true });
7746
8318
  for (const [filename, content] of Object.entries(files)) {
7747
- await writeFile11(join16(targetDir, filename), content);
8319
+ await writeFile13(join18(targetDir, filename), content);
7748
8320
  }
7749
8321
  }
7750
8322
  async installAgent(name, content) {
7751
8323
  const dir = this.getAgentsDir();
7752
- await mkdir11(dir, { recursive: true });
7753
- await writeFile11(join16(dir, `${name}.md`), content);
8324
+ await mkdir13(dir, { recursive: true });
8325
+ await writeFile13(join18(dir, `${name}.md`), content);
7754
8326
  }
7755
8327
  generateCommandContent(command) {
7756
8328
  let workflow = command.content;
7757
8329
  workflow = workflow.replace(/## ⚠️ CRITICAL: The User Has Already Provided Arguments!.*?(?![\n])?.*/gs, "").replace(/\*\*The user has provided arguments with this command!\*\*/g, "").replace(/\*\*The arguments are available in this command response.*?\*\*/g, "").replace(/\*\*YOUR JOB\*\*:.*/gs, "").replace(/1\. Follow command workflow steps.*?\n2\. The workflow will tell you.*?\n3\. Use those arguments.*?\n4\. They have already provided it.*?\n5\. DO NOT ask.*?\n6\. DO: Follow workflow.*?\n+\**Example Scenario\*\*:.*/gs, "").replace(/\*\*User runs:.*?\*\*:\n.*?\n+- Command:.*?\n+- Arguments to use:.*?\n+- You must use.*?\n+- DO NOT:.*?\n+- DO:.*?\n+\*\*\*/g, "").replace(/\*\*\*/g, "");
7758
- workflow = workflow.replace(/^# Command: \/ak_cm_[\s-]+\n+/g, "");
8330
+ workflow = workflow.replace(/^# Command: \/[a-z_]*[\s-]+\n+/g, "");
7759
8331
  workflow = workflow.replace(/\$ARGUMENTS/g, "$ARGUMENTS").replace(/\$1/g, "$1").replace(/\$2/g, "$2");
7760
8332
  const frontmatter = {
7761
8333
  description: command.description,
@@ -7794,6 +8366,26 @@ ${skill.content}
7794
8366
  };
7795
8367
  return matter4.stringify(agent.systemPrompt, frontmatter);
7796
8368
  }
8369
+ /**
8370
+ * Generate commands.json manifest file
8371
+ * This ensures local commands are discovered by Claude Code
8372
+ * and take precedence over parent directory commands
8373
+ *
8374
+ * Reference: https://github.com/anthropics/claude-code/issues/14243
8375
+ */
8376
+ async generateCommandsManifest() {
8377
+ const commandsDir = this.getCommandsDir();
8378
+ const manifestPath = join18(commandsDir, "commands.json");
8379
+ const sortedCommands = [...this.installedCommands].sort();
8380
+ const manifest = {
8381
+ commands: sortedCommands,
8382
+ // Add version for future compatibility
8383
+ version: "1.0",
8384
+ generatedBy: "aikit",
8385
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString()
8386
+ };
8387
+ await writeFile13(manifestPath, JSON.stringify(manifest, null, 2));
8388
+ }
7797
8389
  };
7798
8390
 
7799
8391
  // src/platform/adapters.ts
@@ -7816,7 +8408,7 @@ var SUPPORTED_PLATFORMS = [
7816
8408
  function registerInitCommand(program2) {
7817
8409
  program2.command("init [platform]").description("Initialize AIKit configuration for a specific platform").option("-g, --global", "Initialize global configuration").option("-p, --project", "Initialize project-level configuration").action(async (platformArg, options) => {
7818
8410
  const configDir = options.global ? paths.globalConfig() : paths.projectConfig();
7819
- console.log(chalk2.bold("\n\u{1F680} AIKit Setup\n"));
8411
+ console.log(chalk3.bold("\n\u{1F680} AIKit Setup\n"));
7820
8412
  logger.info(`Initializing AIKit in ${configDir}...`);
7821
8413
  try {
7822
8414
  await initializeConfig(configDir, options.global);
@@ -7828,9 +8420,9 @@ function registerInitCommand(program2) {
7828
8420
  } else {
7829
8421
  const platforms = await CliDetector.detectPlatforms();
7830
8422
  const installed = CliDetector.filterInstalledPlatforms(platforms);
7831
- console.log(chalk2.bold("\n\u{1F50D} Available CLI Tools\n"));
8423
+ console.log(chalk3.bold("\n\u{1F50D} Available CLI Tools\n"));
7832
8424
  for (const p of platforms) {
7833
- const status = p.installed ? chalk2.green("\u2713") : chalk2.gray("\u25CB");
8425
+ const status = p.installed ? chalk3.green("\u2713") : chalk3.gray("\u25CB");
7834
8426
  console.log(` ${status} ${p.displayName}`);
7835
8427
  }
7836
8428
  const { platform } = await inquirer.prompt([
@@ -7886,10 +8478,15 @@ function registerInitCommand(program2) {
7886
8478
  logger.info("Setting up git hooks...");
7887
8479
  await beads.setupGitHooks();
7888
8480
  logger.success("\u2713 Git hooks configured");
8481
+ const sessionManager = new SessionManager();
8482
+ await sessionManager.init();
8483
+ logger.success("\u2713 Sessions folder initialized");
8484
+ const { tracker } = await sessionManager.initTerminalSession();
8485
+ logger.success(`\u2713 Session tracker initialized (${tracker.split("/").pop()})`);
7889
8486
  const adapter = createAdapter(selectedPlatform);
7890
8487
  logger.info(`Installing AIKit for ${adapter.displayName}...`);
7891
8488
  await installToPlatform(adapter, config);
7892
- console.log(chalk2.bold("\n\u2728 AIKit is ready!\n"));
8489
+ console.log(chalk3.bold("\n\u2728 AIKit is ready!\n"));
7893
8490
  if (selectedPlatform === "opencode" /* OPENCODE */) {
7894
8491
  showOpenCodeUsage();
7895
8492
  } else if (selectedPlatform === "claude" /* CLAUDE */) {
@@ -7930,22 +8527,22 @@ async function installToPlatform(adapter, config) {
7930
8527
  }
7931
8528
  function showOpenCodeUsage() {
7932
8529
  console.log("Usage in OpenCode:");
7933
- console.log(chalk2.cyan(" /skills") + " - List all available skills");
7934
- console.log(chalk2.cyan(" /plan") + " - Create implementation plan");
7935
- console.log(chalk2.cyan(" /tdd") + " - Test-driven development");
7936
- console.log(chalk2.cyan(" /debug") + " - Systematic debugging");
7937
- console.log(chalk2.cyan(" /review") + " - Code review checklist");
7938
- console.log(chalk2.cyan(" /git") + " - Git workflow");
7939
- console.log(chalk2.cyan(" /frontend-aesthetics") + " - UI/UX guidelines");
7940
- console.log("\nPress " + chalk2.bold("Ctrl+K") + " in OpenCode to see all commands.\n");
8530
+ console.log(chalk3.cyan(" /skills") + " - List all available skills");
8531
+ console.log(chalk3.cyan(" /plan") + " - Create implementation plan");
8532
+ console.log(chalk3.cyan(" /tdd") + " - Test-driven development");
8533
+ console.log(chalk3.cyan(" /debug") + " - Systematic debugging");
8534
+ console.log(chalk3.cyan(" /review") + " - Code review checklist");
8535
+ console.log(chalk3.cyan(" /git") + " - Git workflow");
8536
+ console.log(chalk3.cyan(" /frontend-aesthetics") + " - UI/UX guidelines");
8537
+ console.log("\nPress " + chalk3.bold("Ctrl+K") + " in OpenCode to see all commands.\n");
7941
8538
  }
7942
8539
  function showClaudeUsage() {
7943
8540
  console.log("Usage in Claude Code CLI:");
7944
- console.log(chalk2.cyan(" /help") + " - List all available commands");
7945
- console.log(chalk2.cyan(" /plan") + " - Create implementation plan");
7946
- console.log(chalk2.cyan(" /implement") + " - Implement a task");
7947
- console.log(chalk2.cyan(" /test") + " - Run tests");
7948
- console.log("\nType " + chalk2.bold('"/help"') + " in Claude to see all commands.\n");
8541
+ console.log(chalk3.cyan(" /help") + " - List all available commands");
8542
+ console.log(chalk3.cyan(" /plan") + " - Create implementation plan");
8543
+ console.log(chalk3.cyan(" /implement") + " - Implement a task");
8544
+ console.log(chalk3.cyan(" /test") + " - Run tests");
8545
+ console.log("\nType " + chalk3.bold('"/help"') + " in Claude to see all commands.\n");
7949
8546
  }
7950
8547
 
7951
8548
  // src/cli/commands/install.ts
@@ -7953,6 +8550,7 @@ init_esm_shims();
7953
8550
  init_logger();
7954
8551
  import inquirer2 from "inquirer";
7955
8552
  init_config();
8553
+ init_sessions();
7956
8554
  function registerInstallCommand(program2) {
7957
8555
  program2.command("install [platform]").description("Install AIKit to specific CLI tool configuration").action(async (platformArg) => {
7958
8556
  try {
@@ -7983,6 +8581,11 @@ function registerInstallCommand(program2) {
7983
8581
  selectedPlatform = platform;
7984
8582
  }
7985
8583
  logger.info(`Installing AIKit for ${selectedPlatform}...`);
8584
+ const sessionManager = new SessionManager();
8585
+ await sessionManager.init();
8586
+ logger.success("\u2713 Sessions folder initialized");
8587
+ const { tracker } = await sessionManager.initTerminalSession();
8588
+ logger.success(`\u2713 Session tracker initialized (${tracker.split("/").pop()})`);
7986
8589
  const config = await loadConfig();
7987
8590
  const adapter = createAdapter(selectedPlatform);
7988
8591
  const skillEngine = config.skills.enabled ? new SkillEngine(config) : null;
@@ -8015,6 +8618,10 @@ function registerInstallCommand(program2) {
8015
8618
  logger.info(` \u2713 Created ${name} agent`);
8016
8619
  }
8017
8620
  }
8621
+ if (selectedPlatform === "claude" && adapter.generateCommandsManifest) {
8622
+ await adapter.generateCommandsManifest();
8623
+ logger.success("\u2713 Generated commands manifest");
8624
+ }
8018
8625
  logger.success(`
8019
8626
  \u2713 AIKit installed to ${adapter.displayName}!`);
8020
8627
  } catch (error) {
@@ -8027,21 +8634,21 @@ function registerInstallCommand(program2) {
8027
8634
  // src/cli/commands/sync.ts
8028
8635
  init_esm_shims();
8029
8636
  init_config();
8030
- import chalk4 from "chalk";
8637
+ import chalk5 from "chalk";
8031
8638
 
8032
8639
  // src/core/sync-engine.ts
8033
8640
  init_esm_shims();
8034
- import { readFile as readFile13, writeFile as writeFile15, copyFile, mkdir as mkdir13 } from "fs/promises";
8035
- import { join as join20, dirname as dirname4 } from "path";
8641
+ import { readFile as readFile14, writeFile as writeFile17, copyFile, mkdir as mkdir15 } from "fs/promises";
8642
+ import { join as join22, dirname as dirname4 } from "path";
8036
8643
  import inquirer3 from "inquirer";
8037
- import chalk3 from "chalk";
8644
+ import chalk4 from "chalk";
8038
8645
 
8039
8646
  // src/core/version-manager.ts
8040
8647
  init_esm_shims();
8041
8648
  init_paths();
8042
8649
  init_logger();
8043
- import { readFile as readFile10, readdir as readdir8, writeFile as writeFile12, stat } from "fs/promises";
8044
- import { join as join17 } from "path";
8650
+ import { readFile as readFile11, readdir as readdir9, writeFile as writeFile14, stat } from "fs/promises";
8651
+ import { join as join19 } from "path";
8045
8652
  import { createHash } from "crypto";
8046
8653
  var VersionManager = class {
8047
8654
  config;
@@ -8052,9 +8659,9 @@ var VersionManager = class {
8052
8659
  * Get current installed version
8053
8660
  */
8054
8661
  async getCurrentVersion() {
8055
- const versionPath = join17(paths.globalConfig(), ".version.json");
8662
+ const versionPath = join19(paths.globalConfig(), ".version.json");
8056
8663
  try {
8057
- const content = await readFile10(versionPath, "utf-8");
8664
+ const content = await readFile11(versionPath, "utf-8");
8058
8665
  return JSON.parse(content);
8059
8666
  } catch {
8060
8667
  return null;
@@ -8065,7 +8672,7 @@ var VersionManager = class {
8065
8672
  */
8066
8673
  getPackageVersion() {
8067
8674
  try {
8068
- const packageJson = __require(join17(process.cwd(), "package.json"));
8675
+ const packageJson = __require(join19(process.cwd(), "package.json"));
8069
8676
  return packageJson.version || "0.0.0";
8070
8677
  } catch {
8071
8678
  return "0.0.0";
@@ -8123,9 +8730,9 @@ var VersionManager = class {
8123
8730
  const removedSkills = [];
8124
8731
  const conflicts = [];
8125
8732
  const installedSkills = /* @__PURE__ */ new Map();
8126
- const installedPath = join17(paths.globalConfig(), ".installed-skills.json");
8733
+ const installedPath = join19(paths.globalConfig(), ".installed-skills.json");
8127
8734
  try {
8128
- const installedData = await readFile10(installedPath, "utf-8");
8735
+ const installedData = await readFile11(installedPath, "utf-8");
8129
8736
  const installedList = JSON.parse(installedData);
8130
8737
  installedList.forEach((skill) => {
8131
8738
  installedSkills.set(skill.name, skill);
@@ -8173,9 +8780,9 @@ var VersionManager = class {
8173
8780
  const hashes = [];
8174
8781
  try {
8175
8782
  const loadFromDir = async (dir) => {
8176
- const files = await readdir8(dir);
8783
+ const files = await readdir9(dir);
8177
8784
  for (const file of files) {
8178
- const filePath = join17(dir, file);
8785
+ const filePath = join19(dir, file);
8179
8786
  const stats = await stat(filePath);
8180
8787
  if (stats.isDirectory()) {
8181
8788
  await loadFromDir(filePath);
@@ -8201,7 +8808,7 @@ var VersionManager = class {
8201
8808
  */
8202
8809
  async calculateSkillHash(filePath) {
8203
8810
  try {
8204
- const content = await readFile10(filePath, "utf-8");
8811
+ const content = await readFile11(filePath, "utf-8");
8205
8812
  return createHash("sha256").update(content).digest("hex");
8206
8813
  } catch {
8207
8814
  return "";
@@ -8222,9 +8829,9 @@ var VersionManager = class {
8222
8829
  * Save installed skills info
8223
8830
  */
8224
8831
  async saveInstalledSkills(skills) {
8225
- const installedPath = join17(paths.globalConfig(), ".installed-skills.json");
8832
+ const installedPath = join19(paths.globalConfig(), ".installed-skills.json");
8226
8833
  try {
8227
- await writeFile12(installedPath, JSON.stringify(skills, null, 2));
8834
+ await writeFile14(installedPath, JSON.stringify(skills, null, 2));
8228
8835
  } catch (error) {
8229
8836
  logger.error("Failed to save installed skills info:", error);
8230
8837
  }
@@ -8245,8 +8852,8 @@ var VersionManager = class {
8245
8852
  packageVersion: this.getPackageVersion(),
8246
8853
  migrationHistory: migration ? [...current.migrationHistory, migration] : current.migrationHistory
8247
8854
  };
8248
- const versionPath = join17(paths.globalConfig(), ".version.json");
8249
- await writeFile12(versionPath, JSON.stringify(updated, null, 2));
8855
+ const versionPath = join19(paths.globalConfig(), ".version.json");
8856
+ await writeFile14(versionPath, JSON.stringify(updated, null, 2));
8250
8857
  }
8251
8858
  /**
8252
8859
  * Check if migration is needed
@@ -8261,8 +8868,8 @@ var VersionManager = class {
8261
8868
  // src/core/backup-manager.ts
8262
8869
  init_esm_shims();
8263
8870
  init_logger();
8264
- import { readFile as readFile11, writeFile as writeFile13, readdir as readdir9, stat as stat2, unlink, mkdir as mkdir12 } from "fs/promises";
8265
- import { join as join18, dirname as dirname3 } from "path";
8871
+ import { readFile as readFile12, writeFile as writeFile15, readdir as readdir10, stat as stat2, unlink as unlink2, mkdir as mkdir14 } from "fs/promises";
8872
+ import { join as join20, dirname as dirname3 } from "path";
8266
8873
  import { createHash as createHash2 } from "crypto";
8267
8874
  var BackupManager = class {
8268
8875
  configPath;
@@ -8270,7 +8877,7 @@ var BackupManager = class {
8270
8877
  maxBackups;
8271
8878
  constructor(configPath, maxBackups = 5) {
8272
8879
  this.configPath = configPath;
8273
- this.backupsDir = join18(configPath, ".backups");
8880
+ this.backupsDir = join20(configPath, ".backups");
8274
8881
  this.maxBackups = maxBackups;
8275
8882
  }
8276
8883
  /**
@@ -8278,10 +8885,10 @@ var BackupManager = class {
8278
8885
  */
8279
8886
  async createBackup(fromVersion, toVersion) {
8280
8887
  try {
8281
- await mkdir12(this.backupsDir, { recursive: true });
8888
+ await mkdir14(this.backupsDir, { recursive: true });
8282
8889
  const backupId = `${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
8283
- const backupPath = join18(this.backupsDir, `${backupId}-v${toVersion}`);
8284
- await mkdir12(backupPath, { recursive: true });
8890
+ const backupPath = join20(this.backupsDir, `${backupId}-v${toVersion}`);
8891
+ await mkdir14(backupPath, { recursive: true });
8285
8892
  logger.info(`Creating backup: ${backupPath}`);
8286
8893
  const files = [];
8287
8894
  const backupItems = [
@@ -8302,8 +8909,8 @@ var BackupManager = class {
8302
8909
  files,
8303
8910
  success: true
8304
8911
  };
8305
- const manifestPath = join18(backupPath, "backup-manifest.json");
8306
- await writeFile13(manifestPath, JSON.stringify(manifest, null, 2));
8912
+ const manifestPath = join20(backupPath, "backup-manifest.json");
8913
+ await writeFile15(manifestPath, JSON.stringify(manifest, null, 2));
8307
8914
  await this.cleanupOldBackups();
8308
8915
  logger.success(`\u2713 Backup created: ${backupId}`);
8309
8916
  return backupId;
@@ -8316,20 +8923,20 @@ var BackupManager = class {
8316
8923
  * Backup a file or directory
8317
8924
  */
8318
8925
  async backupItem(sourceDir, item, targetDir) {
8319
- const sourcePath = join18(sourceDir, item);
8320
- const targetPath = join18(targetDir, item);
8926
+ const sourcePath = join20(sourceDir, item);
8927
+ const targetPath = join20(targetDir, item);
8321
8928
  const files = [];
8322
8929
  try {
8323
8930
  const stats = await stat2(sourcePath);
8324
8931
  if (stats.isDirectory()) {
8325
- await mkdir12(targetPath, { recursive: true });
8326
- const entries = await readdir9(sourcePath);
8932
+ await mkdir14(targetPath, { recursive: true });
8933
+ const entries = await readdir10(sourcePath);
8327
8934
  for (const entry of entries) {
8328
8935
  const entryFiles = await this.backupItem(sourcePath, entry, targetPath);
8329
8936
  files.push(...entryFiles);
8330
8937
  }
8331
8938
  } else if (stats.isFile()) {
8332
- await mkdir12(dirname3(targetPath), { recursive: true });
8939
+ await mkdir14(dirname3(targetPath), { recursive: true });
8333
8940
  await this.copyFile(sourcePath, targetPath);
8334
8941
  const hash = await this.calculateHash(targetPath);
8335
8942
  files.push({
@@ -8347,15 +8954,15 @@ var BackupManager = class {
8347
8954
  * Copy file with hash calculation
8348
8955
  */
8349
8956
  async copyFile(source, target) {
8350
- const content = await readFile11(source);
8351
- await writeFile13(target, content);
8957
+ const content = await readFile12(source);
8958
+ await writeFile15(target, content);
8352
8959
  }
8353
8960
  /**
8354
8961
  * Calculate file hash
8355
8962
  */
8356
8963
  async calculateHash(filePath) {
8357
8964
  try {
8358
- const content = await readFile11(filePath);
8965
+ const content = await readFile12(filePath);
8359
8966
  return createHash2("sha256").update(content).digest("hex");
8360
8967
  } catch {
8361
8968
  return "";
@@ -8366,13 +8973,13 @@ var BackupManager = class {
8366
8973
  */
8367
8974
  async listBackups() {
8368
8975
  try {
8369
- const entries = await readdir9(this.backupsDir);
8976
+ const entries = await readdir10(this.backupsDir);
8370
8977
  const backups = [];
8371
8978
  for (const entry of entries) {
8372
- const backupPath = join18(this.backupsDir, entry);
8373
- const manifestPath = join18(backupPath, "backup-manifest.json");
8979
+ const backupPath = join20(this.backupsDir, entry);
8980
+ const manifestPath = join20(backupPath, "backup-manifest.json");
8374
8981
  try {
8375
- const manifestContent = await readFile11(manifestPath, "utf-8");
8982
+ const manifestContent = await readFile12(manifestPath, "utf-8");
8376
8983
  const manifest = JSON.parse(manifestContent);
8377
8984
  const size = await this.calculateBackupSize(backupPath);
8378
8985
  backups.push({
@@ -8398,9 +9005,9 @@ var BackupManager = class {
8398
9005
  let totalSize = 0;
8399
9006
  try {
8400
9007
  const calculate = async (dir) => {
8401
- const entries = await readdir9(dir);
9008
+ const entries = await readdir10(dir);
8402
9009
  for (const entry of entries) {
8403
- const entryPath = join18(dir, entry);
9010
+ const entryPath = join20(dir, entry);
8404
9011
  const stats = await stat2(entryPath);
8405
9012
  if (stats.isDirectory()) {
8406
9013
  await calculate(entryPath);
@@ -8432,9 +9039,9 @@ var BackupManager = class {
8432
9039
  return false;
8433
9040
  }
8434
9041
  for (const file of backup.manifest.files) {
8435
- const sourcePath = join18(backup.path, file.path);
8436
- const targetPath = join18(this.configPath, file.path);
8437
- await mkdir12(dirname3(targetPath), { recursive: true });
9042
+ const sourcePath = join20(backup.path, file.path);
9043
+ const targetPath = join20(this.configPath, file.path);
9044
+ await mkdir14(dirname3(targetPath), { recursive: true });
8438
9045
  await this.copyFile(sourcePath, targetPath);
8439
9046
  }
8440
9047
  logger.success(`\u2713 Backup restored: ${backupId}`);
@@ -8449,10 +9056,10 @@ var BackupManager = class {
8449
9056
  */
8450
9057
  async validateBackup(backup) {
8451
9058
  try {
8452
- const manifestPath = join18(backup.path, "backup-manifest.json");
8453
- await readFile11(manifestPath, "utf-8");
9059
+ const manifestPath = join20(backup.path, "backup-manifest.json");
9060
+ await readFile12(manifestPath, "utf-8");
8454
9061
  for (const file of backup.manifest.files) {
8455
- const filePath = join18(backup.path, file.path);
9062
+ const filePath = join20(backup.path, file.path);
8456
9063
  await stat2(filePath);
8457
9064
  const currentHash = await this.calculateHash(filePath);
8458
9065
  if (currentHash !== file.hash) {
@@ -8476,14 +9083,14 @@ var BackupManager = class {
8476
9083
  if (!backup) {
8477
9084
  return false;
8478
9085
  }
8479
- const entries = await readdir9(backup.path);
9086
+ const entries = await readdir10(backup.path);
8480
9087
  for (const entry of entries) {
8481
- const entryPath = join18(backup.path, entry);
9088
+ const entryPath = join20(backup.path, entry);
8482
9089
  const stats = await stat2(entryPath);
8483
9090
  if (stats.isDirectory()) {
8484
9091
  await this.removeDirectory(entryPath);
8485
9092
  } else {
8486
- await unlink(entryPath);
9093
+ await unlink2(entryPath);
8487
9094
  }
8488
9095
  }
8489
9096
  logger.success(`\u2713 Backup deleted: ${backupId}`);
@@ -8497,17 +9104,17 @@ var BackupManager = class {
8497
9104
  * Remove directory recursively
8498
9105
  */
8499
9106
  async removeDirectory(dirPath) {
8500
- const entries = await readdir9(dirPath);
9107
+ const entries = await readdir10(dirPath);
8501
9108
  for (const entry of entries) {
8502
- const entryPath = join18(dirPath, entry);
9109
+ const entryPath = join20(dirPath, entry);
8503
9110
  const stats = await stat2(entryPath);
8504
9111
  if (stats.isDirectory()) {
8505
9112
  await this.removeDirectory(entryPath);
8506
9113
  } else {
8507
- await unlink(entryPath);
9114
+ await unlink2(entryPath);
8508
9115
  }
8509
9116
  }
8510
- await unlink(dirPath);
9117
+ await unlink2(dirPath);
8511
9118
  }
8512
9119
  /**
8513
9120
  * Cleanup old backups (keep only maxBackups)
@@ -8545,14 +9152,14 @@ var BackupManager = class {
8545
9152
  // src/core/migration-manager.ts
8546
9153
  init_esm_shims();
8547
9154
  init_logger();
8548
- import { readFile as readFile12, writeFile as writeFile14, readdir as readdir10 } from "fs/promises";
8549
- import { join as join19 } from "path";
9155
+ import { readFile as readFile13, writeFile as writeFile16, readdir as readdir11 } from "fs/promises";
9156
+ import { join as join21 } from "path";
8550
9157
  var MigrationManager = class {
8551
9158
  configPath;
8552
9159
  migrationsDir;
8553
9160
  constructor(configPath) {
8554
9161
  this.configPath = configPath;
8555
- this.migrationsDir = join19(process.cwd(), "src/core/migrations");
9162
+ this.migrationsDir = join21(process.cwd(), "src/core/migrations");
8556
9163
  }
8557
9164
  /**
8558
9165
  * Load all available migrations
@@ -8560,11 +9167,11 @@ var MigrationManager = class {
8560
9167
  async loadMigrations() {
8561
9168
  const migrations = [];
8562
9169
  try {
8563
- const files = await readdir10(this.migrationsDir);
9170
+ const files = await readdir11(this.migrationsDir);
8564
9171
  for (const file of files) {
8565
9172
  if (file.endsWith(".js") && file.startsWith("migrate-")) {
8566
9173
  try {
8567
- const module = await import(join19(this.migrationsDir, file));
9174
+ const module = await import(join21(this.migrationsDir, file));
8568
9175
  const migration = module.default || module.migration;
8569
9176
  if (migration) {
8570
9177
  migrations.push(migration);
@@ -8583,9 +9190,9 @@ var MigrationManager = class {
8583
9190
  * Get applied migrations
8584
9191
  */
8585
9192
  async getAppliedMigrations() {
8586
- const migrationHistoryPath = join19(this.configPath, ".migration-history.json");
9193
+ const migrationHistoryPath = join21(this.configPath, ".migration-history.json");
8587
9194
  try {
8588
- const content = await readFile12(migrationHistoryPath, "utf-8");
9195
+ const content = await readFile13(migrationHistoryPath, "utf-8");
8589
9196
  const history = JSON.parse(content);
8590
9197
  return history.filter((m) => m.status === "completed").map((m) => m.to);
8591
9198
  } catch {
@@ -8671,16 +9278,16 @@ var MigrationManager = class {
8671
9278
  * Update migration history
8672
9279
  */
8673
9280
  async updateMigrationHistory(entries) {
8674
- const historyPath = join19(this.configPath, ".migration-history.json");
9281
+ const historyPath = join21(this.configPath, ".migration-history.json");
8675
9282
  try {
8676
9283
  let history = [];
8677
9284
  try {
8678
- const content = await readFile12(historyPath, "utf-8");
9285
+ const content = await readFile13(historyPath, "utf-8");
8679
9286
  history = JSON.parse(content);
8680
9287
  } catch {
8681
9288
  }
8682
9289
  history.push(...entries);
8683
- await writeFile14(historyPath, JSON.stringify(history, null, 2));
9290
+ await writeFile16(historyPath, JSON.stringify(history, null, 2));
8684
9291
  } catch (error) {
8685
9292
  logger.error("Failed to update migration history:", error);
8686
9293
  }
@@ -8689,14 +9296,14 @@ var MigrationManager = class {
8689
9296
  * Update migration history status
8690
9297
  */
8691
9298
  async updateMigrationHistoryStatus(version, status) {
8692
- const historyPath = join19(this.configPath, ".migration-history.json");
9299
+ const historyPath = join21(this.configPath, ".migration-history.json");
8693
9300
  try {
8694
- const content = await readFile12(historyPath, "utf-8");
9301
+ const content = await readFile13(historyPath, "utf-8");
8695
9302
  const history = JSON.parse(content);
8696
9303
  const updated = history.map(
8697
9304
  (m) => m.to === version ? { ...m, status } : m
8698
9305
  );
8699
- await writeFile14(historyPath, JSON.stringify(updated, null, 2));
9306
+ await writeFile16(historyPath, JSON.stringify(updated, null, 2));
8700
9307
  } catch (error) {
8701
9308
  logger.error("Failed to update migration history status:", error);
8702
9309
  }
@@ -8705,9 +9312,9 @@ var MigrationManager = class {
8705
9312
  * Get migration history
8706
9313
  */
8707
9314
  async getMigrationHistory() {
8708
- const historyPath = join19(this.configPath, ".migration-history.json");
9315
+ const historyPath = join21(this.configPath, ".migration-history.json");
8709
9316
  try {
8710
- const content = await readFile12(historyPath, "utf-8");
9317
+ const content = await readFile13(historyPath, "utf-8");
8711
9318
  return JSON.parse(content);
8712
9319
  } catch {
8713
9320
  return [];
@@ -8747,7 +9354,7 @@ var SyncEngine = class {
8747
9354
  if (changes.hasUpdate) {
8748
9355
  this.displayUpdateInfo(changes);
8749
9356
  } else {
8750
- console.log(chalk3.green("\u2713 Your AIKit is up to date"));
9357
+ console.log(chalk4.green("\u2713 Your AIKit is up to date"));
8751
9358
  console.log(` Installed: ${changes.fromVersion}`);
8752
9359
  console.log(` Latest: ${changes.toVersion}`);
8753
9360
  }
@@ -8762,15 +9369,15 @@ var SyncEngine = class {
8762
9369
  */
8763
9370
  async previewUpdate() {
8764
9371
  try {
8765
- console.log(chalk3.bold("\n\u{1F50D} Previewing update...\n"));
9372
+ console.log(chalk4.bold("\n\u{1F50D} Previewing update...\n"));
8766
9373
  const changes = await this.versionManager.checkForUpdates();
8767
9374
  if (!changes.hasUpdate) {
8768
- console.log(chalk3.green("\u2713 No updates available"));
9375
+ console.log(chalk4.green("\u2713 No updates available"));
8769
9376
  return false;
8770
9377
  }
8771
9378
  await this.displayChanges(changes);
8772
- console.log(chalk3.yellow("\n\u26A0\uFE0F This is a preview - no changes will be made."));
8773
- console.log(chalk3.gray("Use `aikit sync apply` to apply these changes."));
9379
+ console.log(chalk4.yellow("\n\u26A0\uFE0F This is a preview - no changes will be made."));
9380
+ console.log(chalk4.gray("Use `aikit sync apply` to apply these changes."));
8774
9381
  return true;
8775
9382
  } catch (error) {
8776
9383
  logger.error("Failed to preview update:", error);
@@ -8784,7 +9391,7 @@ var SyncEngine = class {
8784
9391
  try {
8785
9392
  const changes = await this.versionManager.checkForUpdates();
8786
9393
  if (!changes.hasUpdate) {
8787
- console.log(chalk3.green("\u2713 Already up to date"));
9394
+ console.log(chalk4.green("\u2713 Already up to date"));
8788
9395
  return {
8789
9396
  success: true,
8790
9397
  newSkills: [],
@@ -8802,7 +9409,7 @@ var SyncEngine = class {
8802
9409
  default: false
8803
9410
  }]);
8804
9411
  if (!confirmed) {
8805
- console.log(chalk3.yellow("Update cancelled"));
9412
+ console.log(chalk4.yellow("Update cancelled"));
8806
9413
  return {
8807
9414
  success: false,
8808
9415
  newSkills: [],
@@ -8814,7 +9421,7 @@ var SyncEngine = class {
8814
9421
  }
8815
9422
  let backupId = void 0;
8816
9423
  if (!options.dryRun && options.backup !== false) {
8817
- console.log(chalk3.bold("\n\u{1F4E6} Creating backup..."));
9424
+ console.log(chalk4.bold("\n\u{1F4E6} Creating backup..."));
8818
9425
  const backupResult = await this.backupManager.createBackup(
8819
9426
  changes.fromVersion,
8820
9427
  changes.toVersion
@@ -8827,19 +9434,19 @@ var SyncEngine = class {
8827
9434
  for (const conflict of changes.conflicts) {
8828
9435
  await this.resolveConflict(conflict);
8829
9436
  }
8830
- console.log(chalk3.bold("\n\u{1F504} Running migrations..."));
9437
+ console.log(chalk4.bold("\n\u{1F504} Running migrations..."));
8831
9438
  const migrationResult = await this.migrationManager.runPendingMigrations();
8832
9439
  if (!migrationResult.success) {
8833
9440
  throw new Error(`Migration failed: ${migrationResult.failed.join(", ")}`);
8834
9441
  }
8835
- console.log(chalk3.bold("\n\u{1F4DD} Updating skills..."));
9442
+ console.log(chalk4.bold("\n\u{1F4DD} Updating skills..."));
8836
9443
  const updateResult = await this.updateSkills(changes, options);
8837
9444
  await this.versionManager.updateVersion(changes.toVersion);
8838
9445
  if (backupId) {
8839
9446
  const allSkills = await this.versionManager.loadSkillHashes(paths.skills(paths.globalConfig()));
8840
9447
  await this.versionManager.saveInstalledSkills(allSkills);
8841
9448
  }
8842
- console.log(chalk3.green("\n\u2705 Update complete!"));
9449
+ console.log(chalk4.green("\n\u2705 Update complete!"));
8843
9450
  this.displaySummary({
8844
9451
  success: true,
8845
9452
  backupId,
@@ -8854,7 +9461,7 @@ var SyncEngine = class {
8854
9461
  };
8855
9462
  } catch (error) {
8856
9463
  logger.error("Update failed:", error);
8857
- console.log(chalk3.red("\n\u274C Update failed"));
9464
+ console.log(chalk4.red("\n\u274C Update failed"));
8858
9465
  return {
8859
9466
  success: false,
8860
9467
  newSkills: [],
@@ -8869,11 +9476,11 @@ var SyncEngine = class {
8869
9476
  */
8870
9477
  async rollback(backupId) {
8871
9478
  try {
8872
- console.log(chalk3.bold("\n\u{1F504} Rollback...\n"));
9479
+ console.log(chalk4.bold("\n\u{1F504} Rollback...\n"));
8873
9480
  if (!backupId) {
8874
9481
  const backups = await this.backupManager.listBackups();
8875
9482
  if (backups.length === 0) {
8876
- console.log(chalk3.yellow("No backups available"));
9483
+ console.log(chalk4.yellow("No backups available"));
8877
9484
  return false;
8878
9485
  }
8879
9486
  const { selectedBackup } = await inquirer3.prompt([{
@@ -8888,12 +9495,12 @@ var SyncEngine = class {
8888
9495
  backupId = selectedBackup;
8889
9496
  }
8890
9497
  if (!backupId) {
8891
- console.log(chalk3.yellow("No backup ID provided"));
9498
+ console.log(chalk4.yellow("No backup ID provided"));
8892
9499
  return false;
8893
9500
  }
8894
9501
  const success = await this.backupManager.restoreBackup(backupId);
8895
9502
  if (success) {
8896
- console.log(chalk3.green("\u2713 Rollback complete"));
9503
+ console.log(chalk4.green("\u2713 Rollback complete"));
8897
9504
  return true;
8898
9505
  }
8899
9506
  return false;
@@ -8906,36 +9513,36 @@ var SyncEngine = class {
8906
9513
  * Display update information
8907
9514
  */
8908
9515
  displayUpdateInfo(changes) {
8909
- console.log(chalk3.bold("\n\u{1F4E2} New version available!\n"));
8910
- console.log(` ${chalk3.cyan("Current:")} ${changes.fromVersion}`);
8911
- console.log(` ${chalk3.cyan("Latest:")} ${changes.toVersion}
9516
+ console.log(chalk4.bold("\n\u{1F4E2} New version available!\n"));
9517
+ console.log(` ${chalk4.cyan("Current:")} ${changes.fromVersion}`);
9518
+ console.log(` ${chalk4.cyan("Latest:")} ${changes.toVersion}
8912
9519
  `);
8913
9520
  }
8914
9521
  /**
8915
9522
  * Display changes summary
8916
9523
  */
8917
9524
  async displayChanges(changes) {
8918
- console.log(chalk3.bold("\u{1F4CA} Changes detected:\n"));
9525
+ console.log(chalk4.bold("\u{1F4CA} Changes detected:\n"));
8919
9526
  if (changes.newSkills.length > 0) {
8920
- console.log(chalk3.green(" New Skills:"));
9527
+ console.log(chalk4.green(" New Skills:"));
8921
9528
  changes.newSkills.forEach((skill) => {
8922
9529
  console.log(` + ${skill.name} (${skill.category})`);
8923
9530
  });
8924
9531
  }
8925
9532
  if (changes.modifiedSkills.length > 0) {
8926
- console.log(chalk3.yellow(" Updated Skills:"));
9533
+ console.log(chalk4.yellow(" Updated Skills:"));
8927
9534
  changes.modifiedSkills.forEach((skill) => {
8928
9535
  console.log(` ~ ${skill.name}`);
8929
9536
  });
8930
9537
  }
8931
9538
  if (changes.removedSkills.length > 0) {
8932
- console.log(chalk3.red(" Removed Skills:"));
9539
+ console.log(chalk4.red(" Removed Skills:"));
8933
9540
  changes.removedSkills.forEach((skill) => {
8934
9541
  console.log(` - ${skill.name}`);
8935
9542
  });
8936
9543
  }
8937
9544
  if (changes.conflicts.length > 0) {
8938
- console.log(chalk3.bold.red(" \u26A0\uFE0F Conflicts:"));
9545
+ console.log(chalk4.bold.red(" \u26A0\uFE0F Conflicts:"));
8939
9546
  changes.conflicts.forEach((conflict) => {
8940
9547
  console.log(` ! ${conflict.skillName} (user modified)`);
8941
9548
  });
@@ -8945,10 +9552,10 @@ var SyncEngine = class {
8945
9552
  * Resolve a conflict
8946
9553
  */
8947
9554
  async resolveConflict(conflict) {
8948
- console.log(chalk3.bold.red(`
9555
+ console.log(chalk4.bold.red(`
8949
9556
  \u26A0\uFE0F Conflict detected: ${conflict.skillName}
8950
9557
  `));
8951
- console.log(chalk3.yellow("Your version differs from official version."));
9558
+ console.log(chalk4.yellow("Your version differs from official version."));
8952
9559
  const { action } = await inquirer3.prompt([{
8953
9560
  type: "list",
8954
9561
  name: "action",
@@ -8974,7 +9581,7 @@ var SyncEngine = class {
8974
9581
  if (action === "overwrite") {
8975
9582
  return;
8976
9583
  }
8977
- console.log(chalk3.yellow(" Your version will be preserved as -custom.md"));
9584
+ console.log(chalk4.yellow(" Your version will be preserved as -custom.md"));
8978
9585
  }
8979
9586
  /**
8980
9587
  * Update skills based on changes
@@ -8990,21 +9597,21 @@ var SyncEngine = class {
8990
9597
  await this.installSkill(globalSkillsPath, skill, projectSkillsPath);
8991
9598
  }
8992
9599
  newSkills.push(skill.name);
8993
- console.log(chalk3.green(` + ${skill.name}`));
9600
+ console.log(chalk4.green(` + ${skill.name}`));
8994
9601
  }
8995
9602
  for (const skill of changes.modifiedSkills) {
8996
9603
  if (!options.dryRun) {
8997
9604
  await this.installSkill(globalSkillsPath, skill, projectSkillsPath);
8998
9605
  }
8999
9606
  updatedSkills.push(skill.name);
9000
- console.log(chalk3.yellow(` ~ ${skill.name}`));
9607
+ console.log(chalk4.yellow(` ~ ${skill.name}`));
9001
9608
  }
9002
9609
  for (const skill of changes.removedSkills) {
9003
9610
  if (!options.dryRun) {
9004
9611
  await this.archiveSkill(projectSkillsPath, skill);
9005
9612
  }
9006
9613
  removedSkills.push(skill.name);
9007
- console.log(chalk3.red(` - ${skill.name} (archived)`));
9614
+ console.log(chalk4.red(` - ${skill.name} (archived)`));
9008
9615
  }
9009
9616
  return {
9010
9617
  newSkills,
@@ -9016,19 +9623,19 @@ var SyncEngine = class {
9016
9623
  * Install a skill
9017
9624
  */
9018
9625
  async installSkill(sourceDir, skill, targetDir) {
9019
- const sourcePath = join20(sourceDir, skill.category, `${skill.name}.md`);
9020
- const targetPath = join20(targetDir, skill.category, `${skill.name}.md`);
9021
- await mkdir13(dirname4(targetPath), { recursive: true });
9626
+ const sourcePath = join22(sourceDir, skill.category, `${skill.name}.md`);
9627
+ const targetPath = join22(targetDir, skill.category, `${skill.name}.md`);
9628
+ await mkdir15(dirname4(targetPath), { recursive: true });
9022
9629
  await copyFile(sourcePath, targetPath);
9023
9630
  }
9024
9631
  /**
9025
9632
  * Archive a removed skill
9026
9633
  */
9027
9634
  async archiveSkill(targetDir, skill) {
9028
- const sourcePath = join20(targetDir, skill.category, `${skill.name}.md`);
9029
- const targetPath = join20(targetDir, skill.category, `${skill.name}-deprecated.md`);
9635
+ const sourcePath = join22(targetDir, skill.category, `${skill.name}.md`);
9636
+ const targetPath = join22(targetDir, skill.category, `${skill.name}-deprecated.md`);
9030
9637
  try {
9031
- const content = await readFile13(sourcePath, "utf-8");
9638
+ const content = await readFile14(sourcePath, "utf-8");
9032
9639
  const deprecatedNotice = `---
9033
9640
  \u26A0\uFE0F DEPRECATED: This skill has been removed
9034
9641
 
@@ -9037,11 +9644,11 @@ Reason: Check release notes for replacement
9037
9644
  ---
9038
9645
 
9039
9646
  ${content}`;
9040
- await mkdir13(dirname4(targetPath), { recursive: true });
9041
- await writeFile15(targetPath, deprecatedNotice);
9647
+ await mkdir15(dirname4(targetPath), { recursive: true });
9648
+ await writeFile17(targetPath, deprecatedNotice);
9042
9649
  } catch (error) {
9043
9650
  if (error.code === "ENOENT") {
9044
- console.log(chalk3.yellow(` - ${skill.name} (not found, skipping)`));
9651
+ console.log(chalk4.yellow(` - ${skill.name} (not found, skipping)`));
9045
9652
  } else {
9046
9653
  throw error;
9047
9654
  }
@@ -9051,24 +9658,24 @@ ${content}`;
9051
9658
  * Display sync summary
9052
9659
  */
9053
9660
  displaySummary(result) {
9054
- console.log(chalk3.bold("\n\u{1F4CB} Summary:\n"));
9055
- console.log(` Updated from: ${chalk3.cyan(result.backupId || "N/A")}`);
9056
- console.log(` Updated to: ${chalk3.cyan("current")}`);
9661
+ console.log(chalk4.bold("\n\u{1F4CB} Summary:\n"));
9662
+ console.log(` Updated from: ${chalk4.cyan(result.backupId || "N/A")}`);
9663
+ console.log(` Updated to: ${chalk4.cyan("current")}`);
9057
9664
  console.log();
9058
9665
  if (result.newSkills.length > 0) {
9059
- console.log(chalk3.green(` ${result.newSkills.length} new skills installed`));
9666
+ console.log(chalk4.green(` ${result.newSkills.length} new skills installed`));
9060
9667
  }
9061
9668
  if (result.updatedSkills.length > 0) {
9062
- console.log(chalk3.yellow(` ${result.updatedSkills.length} skills updated`));
9669
+ console.log(chalk4.yellow(` ${result.updatedSkills.length} skills updated`));
9063
9670
  }
9064
9671
  if (result.removedSkills.length > 0) {
9065
- console.log(chalk3.red(` ${result.removedSkills.length} skills archived`));
9672
+ console.log(chalk4.red(` ${result.removedSkills.length} skills archived`));
9066
9673
  }
9067
9674
  if (result.migrationsRun.length > 0) {
9068
- console.log(chalk3.blue(` ${result.migrationsRun.length} migrations run`));
9675
+ console.log(chalk4.blue(` ${result.migrationsRun.length} migrations run`));
9069
9676
  }
9070
9677
  if (result.backupId) {
9071
- console.log(chalk3.gray(`
9678
+ console.log(chalk4.gray(`
9072
9679
  Rollback available: aikit sync rollback ${result.backupId}`));
9073
9680
  }
9074
9681
  }
@@ -9098,7 +9705,7 @@ function registerSyncCommand(program2) {
9098
9705
  break;
9099
9706
  default:
9100
9707
  logger.error(`Unknown subcommand: ${subcommand}`);
9101
- console.log(chalk4.gray("Available subcommands: check, preview, apply, rollback"));
9708
+ console.log(chalk5.gray("Available subcommands: check, preview, apply, rollback"));
9102
9709
  process.exit(1);
9103
9710
  }
9104
9711
  }
@@ -9108,7 +9715,7 @@ function registerSyncCommand(program2) {
9108
9715
  // src/cli/commands/skills.ts
9109
9716
  init_esm_shims();
9110
9717
  init_config();
9111
- import chalk5 from "chalk";
9718
+ import chalk6 from "chalk";
9112
9719
  init_logger();
9113
9720
  function registerSkillsCommand(program2) {
9114
9721
  const skillsCmd = program2.command("skills").description("Manage skills");
@@ -9119,31 +9726,31 @@ function registerSkillsCommand(program2) {
9119
9726
  const { ToolConfigManager: ToolConfigManager2 } = await Promise.resolve().then(() => (init_tool_config(), tool_config_exports));
9120
9727
  const toolConfigManager = new ToolConfigManager2(config);
9121
9728
  const tools = await toolConfigManager.listTools();
9122
- console.log(chalk5.bold("\n\u{1F4DA} Available Skills:\n"));
9729
+ console.log(chalk6.bold("\n\u{1F4DA} Available Skills:\n"));
9123
9730
  for (const skill of skills) {
9124
- console.log(` ${chalk5.cyan(skill.name)} - ${skill.description}`);
9731
+ console.log(` ${chalk6.cyan(skill.name)} - ${skill.description}`);
9125
9732
  }
9126
- console.log(chalk5.bold("\n\u{1F527} Available Tools:\n"));
9733
+ console.log(chalk6.bold("\n\u{1F527} Available Tools:\n"));
9127
9734
  for (const tool of tools) {
9128
9735
  let statusIcon = " ";
9129
9736
  let statusText = "";
9130
9737
  if (tool.status === "ready") {
9131
- statusIcon = chalk5.green("\u2713");
9132
- statusText = chalk5.gray("(ready)");
9738
+ statusIcon = chalk6.green("\u2713");
9739
+ statusText = chalk6.gray("(ready)");
9133
9740
  } else if (tool.status === "needs_config") {
9134
- statusIcon = chalk5.yellow("\u26A0");
9135
- statusText = chalk5.yellow("(needs config)");
9741
+ statusIcon = chalk6.yellow("\u26A0");
9742
+ statusText = chalk6.yellow("(needs config)");
9136
9743
  } else if (tool.status === "error") {
9137
- statusIcon = chalk5.red("\u2717");
9138
- statusText = chalk5.red("(error)");
9744
+ statusIcon = chalk6.red("\u2717");
9745
+ statusText = chalk6.red("(error)");
9139
9746
  }
9140
- console.log(` ${statusIcon} ${chalk5.cyan(tool.name)} - ${tool.description} ${statusText}`);
9747
+ console.log(` ${statusIcon} ${chalk6.cyan(tool.name)} - ${tool.description} ${statusText}`);
9141
9748
  if (tool.errorMessage) {
9142
- console.log(` ${chalk5.red("Error:")} ${tool.errorMessage}`);
9749
+ console.log(` ${chalk6.red("Error:")} ${tool.errorMessage}`);
9143
9750
  }
9144
9751
  }
9145
9752
  console.log();
9146
- console.log(chalk5.gray('Tip: Use "aikit skills <tool-name> config" to configure a tool\n'));
9753
+ console.log(chalk6.gray('Tip: Use "aikit skills <tool-name> config" to configure a tool\n'));
9147
9754
  });
9148
9755
  skillsCmd.command("show <name>").description("Show skill details").action(async (name) => {
9149
9756
  const config = await loadConfig();
@@ -9153,11 +9760,11 @@ function registerSkillsCommand(program2) {
9153
9760
  logger.error(`Skill not found: ${name}`);
9154
9761
  process.exit(1);
9155
9762
  }
9156
- console.log(chalk5.bold(`
9763
+ console.log(chalk6.bold(`
9157
9764
  \u{1F4D6} Skill: ${skill.name}
9158
9765
  `));
9159
- console.log(chalk5.gray(skill.description));
9160
- console.log(chalk5.bold("\nWorkflow:"));
9766
+ console.log(chalk6.gray(skill.description));
9767
+ console.log(chalk6.bold("\nWorkflow:"));
9161
9768
  console.log(skill.content);
9162
9769
  });
9163
9770
  skillsCmd.command("create <name>").description("Create a new skill").action(async (name) => {
@@ -9173,11 +9780,11 @@ function registerSkillsCommand(program2) {
9173
9780
  if (result.count === 0) {
9174
9781
  logger.info("Skills already in sync or no global skills to sync");
9175
9782
  } else {
9176
- console.log(chalk5.bold(`
9783
+ console.log(chalk6.bold(`
9177
9784
  \u2713 Synced ${result.count} skills to project:
9178
9785
  `));
9179
9786
  for (const skill of result.synced) {
9180
- console.log(` ${chalk5.cyan("\u2022")} ${skill}`);
9787
+ console.log(` ${chalk6.cyan("\u2022")} ${skill}`);
9181
9788
  }
9182
9789
  console.log();
9183
9790
  }
@@ -9193,7 +9800,7 @@ function registerSkillsCommand(program2) {
9193
9800
  await configureToolAction(toolName);
9194
9801
  } else {
9195
9802
  logger.error(`Unknown command: ${toolName || "unknown"} ${action || ""}`);
9196
- console.log(chalk5.gray("\nAvailable commands:"));
9803
+ console.log(chalk6.gray("\nAvailable commands:"));
9197
9804
  console.log(" aikit skills list - List all skills and tools");
9198
9805
  console.log(" aikit skills show <name> - Show skill details");
9199
9806
  console.log(" aikit skills config <tool-name> - Configure a tool");
@@ -9211,20 +9818,20 @@ async function configureToolAction(toolName) {
9211
9818
  const tool = await toolConfigManager.getToolConfig(toolName);
9212
9819
  if (!tool) {
9213
9820
  logger.error(`Tool not found: ${toolName}`);
9214
- console.log(chalk5.gray("\nAvailable tools:"));
9821
+ console.log(chalk6.gray("\nAvailable tools:"));
9215
9822
  const tools = await toolConfigManager.listTools();
9216
9823
  for (const t of tools) {
9217
- console.log(` - ${chalk5.cyan(t.name)}`);
9824
+ console.log(` - ${chalk6.cyan(t.name)}`);
9218
9825
  }
9219
9826
  console.log();
9220
- console.log(chalk5.gray("Tip: If you meant to show a skill, use: aikit skills show <name>"));
9827
+ console.log(chalk6.gray("Tip: If you meant to show a skill, use: aikit skills show <name>"));
9221
9828
  console.log();
9222
9829
  process.exit(1);
9223
9830
  }
9224
- console.log(chalk5.bold(`
9831
+ console.log(chalk6.bold(`
9225
9832
  \u{1F527} Configuring: ${tool.name}
9226
9833
  `));
9227
- console.log(chalk5.gray(tool.description));
9834
+ console.log(chalk6.gray(tool.description));
9228
9835
  console.log();
9229
9836
  if (tool.configMethod === "oauth") {
9230
9837
  if (toolName === "figma-analysis") {
@@ -9232,12 +9839,12 @@ async function configureToolAction(toolName) {
9232
9839
  const oauth = new FigmaOAuth2(toolConfigManager);
9233
9840
  try {
9234
9841
  const token = await oauth.authenticate();
9235
- console.log(chalk5.gray("\nValidating token..."));
9842
+ console.log(chalk6.gray("\nValidating token..."));
9236
9843
  const isValid = await oauth.validateToken(token);
9237
9844
  if (isValid) {
9238
9845
  logger.success(`
9239
9846
  \u2705 ${tool.name} configured successfully!`);
9240
- console.log(chalk5.gray("\nYou can now use the /analyze-figma command in OpenCode.\n"));
9847
+ console.log(chalk6.gray("\nYou can now use the /analyze-figma command in OpenCode.\n"));
9241
9848
  } else {
9242
9849
  await toolConfigManager.updateToolConfig(toolName, {
9243
9850
  status: "error",
@@ -9268,9 +9875,9 @@ async function configureToolAction(toolName) {
9268
9875
 
9269
9876
  // src/cli/commands/misc.ts
9270
9877
  init_esm_shims();
9271
- import chalk6 from "chalk";
9272
- import { readFile as readFile15, writeFile as writeFile17 } from "fs/promises";
9273
- import { join as join22 } from "path";
9878
+ import chalk7 from "chalk";
9879
+ import { readFile as readFile16, writeFile as writeFile19 } from "fs/promises";
9880
+ import { join as join24 } from "path";
9274
9881
  init_config();
9275
9882
  init_memory();
9276
9883
  init_beads();
@@ -9281,10 +9888,10 @@ function registerAgentsCommand(program2) {
9281
9888
  const config = await loadConfig();
9282
9889
  const manager = new AgentManager(config);
9283
9890
  const agents = manager.listAgents();
9284
- console.log(chalk6.bold("\n\u{1F916} Available Agents:\n"));
9891
+ console.log(chalk7.bold("\n\u{1F916} Available Agents:\n"));
9285
9892
  for (const agent of agents) {
9286
- console.log(` ${chalk6.cyan(`@${agent.name}`)} - ${agent.description}`);
9287
- console.log(chalk6.gray(` Use when: ${agent.useWhen}`));
9893
+ console.log(` ${chalk7.cyan(`@${agent.name}`)} - ${agent.description}`);
9894
+ console.log(chalk7.gray(` Use when: ${agent.useWhen}`));
9288
9895
  }
9289
9896
  console.log();
9290
9897
  });
@@ -9296,13 +9903,13 @@ function registerCommandsCommand(program2) {
9296
9903
  const config = await loadConfig();
9297
9904
  const runner = new CommandRunner(config);
9298
9905
  const commands = await runner.listCommands();
9299
- console.log(chalk6.bold("\n\u26A1 Available Commands:\n"));
9906
+ console.log(chalk7.bold("\n\u26A1 Available Commands:\n"));
9300
9907
  const groups = groupBy(commands, (c) => c.category);
9301
9908
  for (const [category, cmds] of Object.entries(groups)) {
9302
- console.log(chalk6.bold.yellow(`
9909
+ console.log(chalk7.bold.yellow(`
9303
9910
  ${category}:`));
9304
9911
  for (const cmd of cmds) {
9305
- console.log(` ${chalk6.cyan(`/${cmd.name}`)} - ${cmd.description}`);
9912
+ console.log(` ${chalk7.cyan(`/${cmd.name}`)} - ${cmd.description}`);
9306
9913
  }
9307
9914
  }
9308
9915
  console.log();
@@ -9314,15 +9921,15 @@ function registerModeCommand(program2) {
9314
9921
  modeCmd.command("get").description("Get current AIKit mode").action(async () => {
9315
9922
  const config = await loadConfig();
9316
9923
  const { mode } = config;
9317
- console.log(chalk6.bold("\n\u{1F4CB} Current Mode:\n"));
9318
- console.log(` ${chalk6.cyan(mode || "build")}`);
9924
+ console.log(chalk7.bold("\n\u{1F4CB} Current Mode:\n"));
9925
+ console.log(` ${chalk7.cyan(mode || "build")}`);
9319
9926
  console.log();
9320
- console.log(chalk6.bold("Available Modes:\n"));
9321
- console.log(` ${chalk6.cyan("plan")} - Create detailed implementation plans`);
9322
- console.log(` ${chalk6.cyan("build")} - Direct execution mode`);
9323
- console.log(` ${chalk6.cyan("one-shot")} - End-to-end autonomous execution`);
9927
+ console.log(chalk7.bold("Available Modes:\n"));
9928
+ console.log(` ${chalk7.cyan("plan")} - Create detailed implementation plans`);
9929
+ console.log(` ${chalk7.cyan("build")} - Direct execution mode`);
9930
+ console.log(` ${chalk7.cyan("one-shot")} - End-to-end autonomous execution`);
9324
9931
  console.log();
9325
- console.log(chalk6.gray('Use "aikit mode set <mode>" to change mode.'));
9932
+ console.log(chalk7.gray('Use "aikit mode set <mode>" to change mode.'));
9326
9933
  });
9327
9934
  modeCmd.command("set <mode>").description("Set AIKit mode (plan, build, one-shot)").action(async (mode) => {
9328
9935
  const config = await loadConfig();
@@ -9330,16 +9937,16 @@ function registerModeCommand(program2) {
9330
9937
  try {
9331
9938
  const validModes = ["plan", "build", "one-shot"];
9332
9939
  if (!validModes.includes(mode)) {
9333
- console.log(chalk6.red(`Invalid mode. Available modes: ${validModes.join(", ")}`));
9940
+ console.log(chalk7.red(`Invalid mode. Available modes: ${validModes.join(", ")}`));
9334
9941
  return;
9335
9942
  }
9336
- const configData = JSON.parse(await readFile15(join22(configPath, "aikit.json"), "utf-8"));
9943
+ const configData = JSON.parse(await readFile16(join24(configPath, "aikit.json"), "utf-8"));
9337
9944
  configData.mode = mode;
9338
- await writeFile17(join22(configPath, "aikit.json"), JSON.stringify(configData, null, 2));
9339
- console.log(chalk6.green(`\u2713 Mode set to: ${mode}`));
9340
- console.log(chalk6.gray(`Configuration updated at: ${configPath}/aikit.json`));
9945
+ await writeFile19(join24(configPath, "aikit.json"), JSON.stringify(configData, null, 2));
9946
+ console.log(chalk7.green(`\u2713 Mode set to: ${mode}`));
9947
+ console.log(chalk7.gray(`Configuration updated at: ${configPath}/aikit.json`));
9341
9948
  } catch (error) {
9342
- console.log(chalk6.red(`Failed to set mode: ${error instanceof Error ? error.message : String(error)}`));
9949
+ console.log(chalk7.red(`Failed to set mode: ${error instanceof Error ? error.message : String(error)}`));
9343
9950
  }
9344
9951
  });
9345
9952
  return modeCmd;
@@ -9350,9 +9957,9 @@ function registerToolsCommand(program2) {
9350
9957
  const config = await loadConfig();
9351
9958
  const registry = new ToolRegistry(config);
9352
9959
  const tools = await registry.listTools();
9353
- console.log(chalk6.bold("\n\u{1F527} Available Tools:\n"));
9960
+ console.log(chalk7.bold("\n\u{1F527} Available Tools:\n"));
9354
9961
  for (const tool of tools) {
9355
- console.log(` ${chalk6.cyan(tool.name)} - ${tool.description}`);
9962
+ console.log(` ${chalk7.cyan(tool.name)} - ${tool.description}`);
9356
9963
  }
9357
9964
  console.log();
9358
9965
  });
@@ -9364,10 +9971,10 @@ function registerPluginsCommand(program2) {
9364
9971
  const config = await loadConfig();
9365
9972
  const system = new PluginSystem(config);
9366
9973
  const plugins = await system.listPlugins();
9367
- console.log(chalk6.bold("\n\u{1F50C} Available Plugins:\n"));
9974
+ console.log(chalk7.bold("\n\u{1F50C} Available Plugins:\n"));
9368
9975
  for (const plugin of plugins) {
9369
- const status = plugin.enabled ? chalk6.green("\u2713") : chalk6.gray("\u25CB");
9370
- console.log(` ${status} ${chalk6.cyan(plugin.name)} - ${plugin.description}`);
9976
+ const status = plugin.enabled ? chalk7.green("\u2713") : chalk7.gray("\u25CB");
9977
+ console.log(` ${status} ${chalk7.cyan(plugin.name)} - ${plugin.description}`);
9371
9978
  }
9372
9979
  console.log();
9373
9980
  });
@@ -9379,10 +9986,10 @@ function registerMemoryCommand(program2) {
9379
9986
  const config = await loadConfig();
9380
9987
  const memory = new MemoryManager(config);
9381
9988
  const entries = await memory.list();
9382
- console.log(chalk6.bold("\n\u{1F9E0} Memory Entries:\n"));
9989
+ console.log(chalk7.bold("\n\u{1F9E0} Memory Entries:\n"));
9383
9990
  for (const entry of entries) {
9384
- console.log(` ${chalk6.cyan(entry.key)} - ${entry.summary}`);
9385
- console.log(chalk6.gray(` Updated: ${entry.updatedAt}`));
9991
+ console.log(` ${chalk7.cyan(entry.key)} - ${entry.summary}`);
9992
+ console.log(chalk7.gray(` Updated: ${entry.updatedAt}`));
9386
9993
  }
9387
9994
  console.log();
9388
9995
  });
@@ -9403,7 +10010,7 @@ function registerBeadsCommand(program2) {
9403
10010
  beadsCmd.command("status").description("Show current Beads status").action(async () => {
9404
10011
  const beads = new BeadsIntegration();
9405
10012
  const status = await beads.getStatus();
9406
- console.log(chalk6.bold("\n\u{1F4FF} Beads Status:\n"));
10013
+ console.log(chalk7.bold("\n\u{1F4FF} Beads Status:\n"));
9407
10014
  console.log(` Active tasks: ${status.activeTasks}`);
9408
10015
  console.log(` Completed: ${status.completedTasks}`);
9409
10016
  console.log(` Current: ${status.currentTask || "None"}`);
@@ -9413,12 +10020,12 @@ function registerBeadsCommand(program2) {
9413
10020
  }
9414
10021
  function registerStatusCommand(program2) {
9415
10022
  program2.command("status").description("Show AIKit status").action(async () => {
9416
- console.log(chalk6.bold(`
10023
+ console.log(chalk7.bold(`
9417
10024
  \u{1F680} AIKit v${getVersion()}
9418
10025
  `));
9419
10026
  try {
9420
10027
  const config = await loadConfig();
9421
- console.log(chalk6.green("\u2713 Configuration loaded"));
10028
+ console.log(chalk7.green("\u2713 Configuration loaded"));
9422
10029
  const skillEngine = new SkillEngine(config);
9423
10030
  const skills = await skillEngine.listSkills();
9424
10031
  console.log(` Skills: ${skills.length}`);
@@ -9433,9 +10040,9 @@ function registerStatusCommand(program2) {
9433
10040
  console.log(` Tools: ${tools.length}`);
9434
10041
  const beads = new BeadsIntegration();
9435
10042
  const beadsStatus = await beads.isInstalled();
9436
- console.log(` Beads: ${beadsStatus ? chalk6.green("Installed") : chalk6.yellow("Not installed")}`);
10043
+ console.log(` Beads: ${beadsStatus ? chalk7.green("Installed") : chalk7.yellow("Not installed")}`);
9437
10044
  } catch (error) {
9438
- console.log(chalk6.yellow('\u26A0 AIKit not initialized. Run "aikit init" to get started.'));
10045
+ console.log(chalk7.yellow('\u26A0 AIKit not initialized. Run "aikit init" to get started.'));
9439
10046
  }
9440
10047
  console.log();
9441
10048
  });
@@ -9466,6 +10073,12 @@ function registerSessionCommand(program2) {
9466
10073
  sessionCmd.command("search <query>").description("Search sessions by keyword").action(async (query) => {
9467
10074
  await searchSessions(query);
9468
10075
  });
10076
+ sessionCmd.command("resume <sessionId>").description("Resume a past session (set as active)").action(async (sessionId) => {
10077
+ await resumeSession(sessionId);
10078
+ });
10079
+ sessionCmd.command("use <sessionId>").description("Switch to a different session in current terminal").action(async (sessionId) => {
10080
+ await switchSession(sessionId);
10081
+ });
9469
10082
  return sessionCmd;
9470
10083
  }
9471
10084
 
@@ -9486,4 +10099,9 @@ registerBeadsCommand(program);
9486
10099
  registerSessionCommand(program);
9487
10100
  registerStatusCommand(program);
9488
10101
  program.parse();
10102
+ checkForUpdatesAsync().catch((err) => {
10103
+ if (process.env.AIKIT_DEBUG) {
10104
+ console.error("Update check failed:", err);
10105
+ }
10106
+ });
9489
10107
  //# sourceMappingURL=cli.js.map