alchemylab 1.0.13 → 1.1.0
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/478.js +6 -6
- package/dist/60.js +10 -10
- package/dist/800.js +7 -8
- package/dist/cli.js +254 -196
- package/dist/http-server.js +1449 -1760
- package/dist/index.js +1439 -1732
- package/dist/mcp-direct.js +604 -897
- package/dist/plugins/hooks/lib/dedup-utils.js +0 -28
- package/package.json +2 -1
package/dist/478.js
CHANGED
|
@@ -4,11 +4,11 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectConfigServ
|
|
|
4
4
|
const o=r(t(1943)),i=r(t(6928)),s=r(t(857)),a=t(4139),n=t(8824)
|
|
5
5
|
exports.ProjectConfigService=class{constructor(e){this.logger=e.child({component:"project-config"})}async readProjectId(e){try{const t=i.default.join(e,a.ALCHEMY_DIR_NAME,"project.json"),r=await o.default.readFile(t,"utf-8"),s=JSON.parse(r)
|
|
6
6
|
return s.id?s.id+"":null}catch(e){return this.logger.debug("Could not read project ID",{error:(0,n.getErrorMessage)(e)}),null}}async readProjectConfig(e){try{const t=i.default.join(e,a.ALCHEMY_DIR_NAME,"config.json"),r=await o.default.readFile(t,"utf-8")
|
|
7
|
-
return JSON.parse(r)}catch(e){return this.logger.debug("Could not read project config",{error:(0,n.getErrorMessage)(e)}),{}}}async
|
|
8
|
-
await o.default.mkdir(
|
|
9
|
-
let
|
|
10
|
-
try{const e=await o.default.readFile(
|
|
11
|
-
|
|
7
|
+
return JSON.parse(r)}catch(e){return this.logger.debug("Could not read project config",{error:(0,n.getErrorMessage)(e)}),{}}}async saveProjectConfig(e,t){try{const r=i.default.join(e,a.ALCHEMY_DIR_NAME),s=i.default.join(r,"config.json")
|
|
8
|
+
await o.default.mkdir(r,{recursive:!0})
|
|
9
|
+
let n={}
|
|
10
|
+
try{const e=await o.default.readFile(s,"utf-8")
|
|
11
|
+
n=JSON.parse(e)}catch(e){this.logger.debug("No existing config.json, creating new one")}void 0!==t&&(n.autoJournal=t),n.lockTimeout||(n.lockTimeout=3600),n.worktreeCleanupDelay||(n.worktreeCleanupDelay=900),n.maxWorktreeAge||(n.maxWorktreeAge=24),n.cleanupInterval||(n.cleanupInterval=15),void 0===n.preserveBranchesOnCleanup&&(n.preserveBranchesOnCleanup=!0),n.maxConcurrentSessions||(n.maxConcurrentSessions=10),n.sessionTimeoutWarning||(n.sessionTimeoutWarning=45),await o.default.writeFile(s,JSON.stringify(n,null,2),"utf-8"),this.logger.info("Saved project config",{configPath:s})}catch(e){this.logger.error("Failed to save project config",{error:(0,n.getErrorMessage)(e)})}}getToolPreferencesPath(){const e=s.default.homedir()
|
|
12
12
|
return i.default.join(e,".alchemy_lab","tool-preferences.json")}async loadToolPreferences(e){const t=this.getToolPreferencesPath()
|
|
13
13
|
try{const r=await o.default.readFile(t,"utf-8"),i=JSON.parse(r)
|
|
14
14
|
return e&&i[e]?i[e]:e?null:i}catch(t){return this.logger.debug("No user preferences found",{error:(0,n.getErrorMessage)(t)}),e?null:{}}}async saveToolPreferences(e,t,r,s){const a=this.getToolPreferencesPath(),n=i.default.dirname(a)
|
|
@@ -45,7 +45,7 @@ if(this.logger.info("Found local project",{projectId:t.id,projectName:t.name}),t
|
|
|
45
45
|
try{const r=await this.remoteApi.fetchProject(t.id)
|
|
46
46
|
if(r?.metadata){const{autoJournal:o}=r.metadata
|
|
47
47
|
if(void 0!==o){const r=new a.ProjectConfigService(this.logger)
|
|
48
|
-
await r.
|
|
48
|
+
await r.saveProjectConfig(e,o),this.logger.info("Synced remote settings to local config",{projectId:t.id,autoJournal:o})}}}catch(e){this.logger.warn("Failed to sync remote settings to local config",{projectId:t.id,error:e instanceof Error?e.message:e+""})}this.logger.info("Successfully synchronized project",{projectId:t.id,projectName:t.name,basePath:e})}else this.logger.warn("Failed to verify/create project on remote server",{projectId:t.id,basePath:e})}catch(t){this.logger.error("Error during project synchronization",{basePath:e,error:t instanceof Error?t.stack:t+""})}}async loadLocalProject(e){try{this.logger.info("Loading local project from directory",{basePath:e})
|
|
49
49
|
const t=await this.fileSystem.readProjectFile(e)
|
|
50
50
|
return t&&t.id?(this.registry.register(t),this.logger.info("Successfully loaded local project",{projectId:t.id,basePath:e}),t):(this.logger.info("No valid local project found",{basePath:e}),null)}catch(t){return this.logger.error("Error loading local project",{basePath:e,error:t instanceof Error?t.stack:t+""}),null}}async getOrCreateProject(e,t={}){this.logger.info("\u{1f680} getOrCreateProject called",{basePath:e,hasProjectData:!!Object.keys(t).length,projectData:Object.keys(t)})
|
|
51
51
|
try{this.logger.info("Attempting to load existing local project",{basePath:e})
|
package/dist/60.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict"
|
|
2
2
|
exports.id=60,exports.ids=[60],exports.modules={9060(e,exports,t){var i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3
3
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConfigManager=void 0,exports.createConfigManager=function(e){return new c(e)}
|
|
4
|
-
const
|
|
4
|
+
const a=i(t(1943)),r=i(t(6928)),n=i(t(857)),o=t(4139),s=t(8824),l={lockOverride:{enabled:!0,passwordValidityMinutes:5}},d={remoteServerUrl:"https://api.alchemylabcode.com",nodePath:"node"}
|
|
5
5
|
class c{constructor(e){this.logger=e.child({component:"config-manager"}),this.installationConfigDir=this.getInstallationConfigDir()}getInstallationConfigDir(){const e=__dirname||process.cwd(),t=n.default.homedir()
|
|
6
|
-
return e.includes("node_modules")?
|
|
7
|
-
return{...t,...
|
|
8
|
-
return this.readConfig(t,l)}async updateProjectConfig(e,t){const i=
|
|
9
|
-
await this.writeConfig(i,
|
|
10
|
-
try{const e=await
|
|
11
|
-
return{id:i.id,name:i.name,createdAt:i.createdAt,status:i.status}}catch(e){return"ENOENT"===e.code||this.logger.warn("Error reading project metadata",{projectJsonPath:t,error:(0,s.getErrorMessage)(e)}),null}}async getInstallationConfig(){const e=
|
|
12
|
-
return this.readConfig(e,d)}async updateInstallationConfig(e){const t=
|
|
13
|
-
await this.writeConfig(t,i),this.logger.info("Updated installation config",{updates:e})}async getEffectiveConfig(e){const[t,i,
|
|
14
|
-
return{remoteServerUrl:
|
|
6
|
+
return e.includes("node_modules")?r.default.join(t,".alchemy_lab","config"):r.default.join(t,".alchemy_lab","config-dev")}async ensureDirectory(e){try{await a.default.access(e)}catch(t){await a.default.mkdir(e,{recursive:!0}),this.logger.debug("Created directory",{dirPath:e})}}async readConfig(e,t){try{const i=await a.default.readFile(e,"utf8"),r=JSON.parse(i)
|
|
7
|
+
return{...t,...r}}catch(i){return"ENOENT"===i.code||this.logger.warn("Error reading config file, using defaults",{filePath:e,error:(0,s.getErrorMessage)(i)}),t}}async writeConfig(e,t){await this.ensureDirectory(r.default.dirname(e)),await a.default.writeFile(e,JSON.stringify(t,null,2),"utf8"),this.logger.debug("Wrote config file",{filePath:e})}async getProjectConfig(e){const t=r.default.join(e,o.ALCHEMY_DIR_NAME,"config.json")
|
|
8
|
+
return this.readConfig(t,l)}async updateProjectConfig(e,t){const i=r.default.join(e,o.ALCHEMY_DIR_NAME,"config.json"),a={...await this.getProjectConfig(e),...t}
|
|
9
|
+
await this.writeConfig(i,a),this.logger.info("Updated project config",{projectPath:e,updates:t})}async getProjectMetadata(e){const t=r.default.join(e,o.ALCHEMY_DIR_NAME,"project.json")
|
|
10
|
+
try{const e=await a.default.readFile(t,"utf8"),i=JSON.parse(e)
|
|
11
|
+
return{id:i.id,name:i.name,createdAt:i.createdAt,status:i.status}}catch(e){return"ENOENT"===e.code||this.logger.warn("Error reading project metadata",{projectJsonPath:t,error:(0,s.getErrorMessage)(e)}),null}}async getInstallationConfig(){const e=r.default.join(this.installationConfigDir,"config.json")
|
|
12
|
+
return this.readConfig(e,d)}async updateInstallationConfig(e){const t=r.default.join(this.installationConfigDir,"config.json"),i={...await this.getInstallationConfig(),...e}
|
|
13
|
+
await this.writeConfig(t,i),this.logger.info("Updated installation config",{updates:e})}async getEffectiveConfig(e){const[t,i,a]=await Promise.all([this.getProjectConfig(e),this.getProjectMetadata(e),this.getInstallationConfig()])
|
|
14
|
+
return{remoteServerUrl:a.remoteServerUrl||d.remoteServerUrl,nodePath:a.nodePath||d.nodePath,projectId:i?.id,projectName:i?.name,lockOverride:{enabled:t.lockOverride?.enabled??l.lockOverride.enabled,passwordValidityMinutes:t.lockOverride?.passwordValidityMinutes??l.lockOverride.passwordValidityMinutes}}}getInstallationConfigPath(){return this.installationConfigDir}}exports.ConfigManager=c}}
|
package/dist/800.js
CHANGED
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
"use strict"
|
|
2
2
|
exports.id=800,exports.ids=[800],exports.modules={3800(e,exports,t){var r,o=this&&this.__createBinding||(Object.create?function(e,t,r,o){void 0===o&&(o=r)
|
|
3
3
|
var i=Object.getOwnPropertyDescriptor(t,r)
|
|
4
|
-
i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:()=>t[r]}),Object.defineProperty(e,o,i)}:function(e,t,r,o){void 0===o&&(o=r),e[o]=t[r]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),
|
|
4
|
+
i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:()=>t[r]}),Object.defineProperty(e,o,i)}:function(e,t,r,o){void 0===o&&(o=r),e[o]=t[r]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),c=this&&this.__importStar||(r=function(e){return r=Object.getOwnPropertyNames||function(e){var t=[]
|
|
5
5
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
6
6
|
return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
7
7
|
var t={}
|
|
8
|
-
if(null!=e)for(var
|
|
8
|
+
if(null!=e)for(var c=r(e),s=0;s<c.length;s++)"default"!==c[s]&&o(t,e,c[s])
|
|
9
9
|
return i(t,e),t})
|
|
10
10
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.SimpleProjectCreationLock=void 0
|
|
11
|
-
const c
|
|
12
|
-
exports.SimpleProjectCreationLock=class{constructor(e,t){this.maxWaitMs=3e4,this.checkIntervalMs=500,this.lockFilePath=
|
|
13
|
-
this.logger.info("Multi-agent mode: attempting to acquire project creation lock",{processId:process.pid,lockFile:this.lockFilePath})
|
|
11
|
+
const s=c(t(1943)),a=c(t(6928)),n=t(4139)
|
|
12
|
+
exports.SimpleProjectCreationLock=class{constructor(e,t){this.maxWaitMs=3e4,this.checkIntervalMs=500,this.lockFilePath=a.join(e,".alchemy-project-creation.lock"),this.projectFilePath=a.join(e,n.ALCHEMY_DIR_NAME,"project.json"),this.logger=t.child({component:"simple-project-creation-lock"})}async acquireLock(){this.logger.info("Attempting to acquire project creation lock",{processId:process.pid,lockFile:this.lockFilePath})
|
|
14
13
|
const e=await this.loadExistingProject()
|
|
15
14
|
if(e)return this.logger.info("Project already exists, no creation needed",{projectId:e.id}),{acquired:!1,shouldCreate:!1,projectData:e}
|
|
16
15
|
try{const e={processId:process.pid,timestamp:Date.now(),lockFile:this.lockFilePath}
|
|
17
|
-
return await
|
|
16
|
+
return await s.writeFile(this.lockFilePath,JSON.stringify(e,null,2),{flag:"wx"}),this.logger.info("Successfully acquired project creation lock",{processId:process.pid,lockFile:this.lockFilePath}),{acquired:!0,shouldCreate:!0}}catch(e){return"EEXIST"===e.code?(this.logger.info("Lock already held by another process, will wait",{processId:process.pid}),await this.waitForProjectCreation()):(this.logger.error("Error acquiring project creation lock",{error:e.message}),{acquired:!0,shouldCreate:!0})}}async releaseLock(){try{await s.unlink(this.lockFilePath),this.logger.info("Released project creation lock",{processId:process.pid})}catch(e){"ENOENT"!==e.code&&this.logger.warn("Failed to release project creation lock",{error:e.message})}}async waitForProjectCreation(){const e=Math.floor(this.maxWaitMs/this.checkIntervalMs)
|
|
18
17
|
this.logger.info("Waiting for project creation by another process",{maxAttempts:e,processId:process.pid})
|
|
19
18
|
for(let t=1;e>=t;t++){await this.sleep(this.checkIntervalMs)
|
|
20
19
|
const r=await this.loadExistingProject()
|
|
21
20
|
if(r)return this.logger.info("Project creation completed by another process",{projectId:r.id,attempt:t,processId:process.pid}),{acquired:!1,shouldCreate:!1,projectData:r}
|
|
22
|
-
if(!await this.lockFileExists()&&(this.logger.warn("Lock disappeared but no project found, creation may have failed",{attempt:t,processId:process.pid}),t>e/2))return this.logger.info("Attempting to acquire lock after apparent creation failure"),{acquired:!0,shouldCreate:!0}}return this.logger.error("Timeout waiting for project creation",{maxWaitMs:this.maxWaitMs,processId:process.pid}),{acquired:!0,shouldCreate:!0}}async loadExistingProject(){try{const e=await
|
|
23
|
-
if(t&&t.id)return t}catch(e){"ENOENT"!==e.code&&this.logger.debug("Failed to load existing project",{error:e.message})}return null}async lockFileExists(){try{return await
|
|
21
|
+
if(!await this.lockFileExists()&&(this.logger.warn("Lock disappeared but no project found, creation may have failed",{attempt:t,processId:process.pid}),t>e/2))return this.logger.info("Attempting to acquire lock after apparent creation failure"),{acquired:!0,shouldCreate:!0}}return this.logger.error("Timeout waiting for project creation",{maxWaitMs:this.maxWaitMs,processId:process.pid}),{acquired:!0,shouldCreate:!0}}async loadExistingProject(){try{const e=await s.readFile(this.projectFilePath,"utf8"),t=JSON.parse(e)
|
|
22
|
+
if(t&&t.id)return t}catch(e){"ENOENT"!==e.code&&this.logger.debug("Failed to load existing project",{error:e.message})}return null}async lockFileExists(){try{return await s.access(this.lockFilePath),!0}catch{return!1}}sleep(e){return new Promise((t=>setTimeout(t,e)))}}}}
|