alchemylab 2.1.0 → 2.1.1

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 CHANGED
@@ -1,15 +1,42 @@
1
1
  "use strict"
2
- exports.id=478,exports.ids=[478],exports.modules={18029:function(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
2
+ exports.ids=[478],exports.modules={53102(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
3
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.DefaultProjectFileSystem=void 0
4
+ const i=r(t(79896)),o=r(t(16928)),s=t(14139)
5
+ exports.DefaultProjectFileSystem=class{constructor(e){this.logger=e.child({component:"project-file-system"})}async readProjectFile(e){try{const t=o.default.join(e,"project.json"),r=o.default.join(e,s.ALCHEMY_DIR_NAME,"project.json")
6
+ let a=r
7
+ if(i.default.existsSync(t))a=t,this.logger.info("Found project file in base directory",{path:a})
8
+ else{if(!i.default.existsSync(r))return this.logger.info("Project file does not exist in either location",{directPath:t,nestedPath:r}),null
9
+ this.logger.info("Found project file in alchemy_lab subdirectory",{path:a})}const n=await i.default.promises.readFile(a,"utf8"),c=JSON.parse(n)
10
+ return c.id?(this.logger.info("Read project file successfully",{projectId:c.id,path:a}),c):(this.logger.warn("Project file has no ID",{path:a}),null)}catch(t){return this.logger.error("Failed to read project file",{basePath:e,error:t instanceof Error?t.stack:String(t)}),null}}async writeProjectFile(e,t){try{const r=o.default.join(t,"project.json"),a=o.default.join(t,s.ALCHEMY_DIR_NAME,"project.json")
11
+ let n=r
12
+ !i.default.existsSync(r)&&i.default.existsSync(a)?(n=a,this.logger.info("Using existing nested path for project file",{path:n})):this.logger.info("Using direct path for project file",{path:n}),await this.ensureDirectoryExists(o.default.dirname(n)),await i.default.promises.writeFile(n,JSON.stringify(e,null,2),"utf8"),this.logger.info("Wrote project file successfully",{projectId:e.id,path:n})}catch(r){throw this.logger.error("Failed to write project file",{projectId:e.id,basePath:t,error:r instanceof Error?r.stack:String(r)}),r}}async ensureDirectoryExists(e){try{i.default.existsSync(e)||(await i.default.promises.mkdir(e,{recursive:!0}),this.logger.info("Created directory",{path:e}))}catch(t){throw this.logger.error("Failed to create directory",{path:e,error:t instanceof Error?t.stack:String(t)}),t}}}},18029(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
3
13
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectIDBackwardCompat=exports.ProjectIDFactory=exports.ProjectID=void 0
4
14
  const i=r(t(76982))
5
15
  class o{static create(){return exports.ProjectIDFactory.create()}static fromString(e){return exports.ProjectIDFactory.fromString(e)}static isValid(e){return exports.ProjectIDFactory.isValid(e)}constructor(e){this.id=e}toString(){return this.id}equals(e){return this.id===e.toString()}isStandardFormat(){return this.id.includes("_")&&this.id.startsWith("prj_")}}exports.ProjectID=o,exports.ProjectIDFactory={create(){const e=Date.now().toString().substring(5),t=i.default.randomBytes(4).toString("hex")
6
16
  return o.fromString(`prj_${e}_${t}`)},fromString(e){return this.isValid(e)?new o(e):null},isValid(e){if(!e||"string"!=typeof e||e.length<5||!e.startsWith("prj"))return!1
7
17
  if(e.includes("_")){const t=e.split("_")
8
- return t.length>=3&&"prj"===t[0]}return!1}},exports.ProjectIDBackwardCompat={create:exports.ProjectIDFactory.create,fromString:exports.ProjectIDFactory.fromString,isValid:exports.ProjectIDFactory.isValid},Object.assign(o,exports.ProjectIDBackwardCompat)},52568:function(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
18
+ return t.length>=3&&"prj"===t[0]}return!1}},exports.ProjectIDBackwardCompat={create:exports.ProjectIDFactory.create,fromString:exports.ProjectIDFactory.fromString,isValid:exports.ProjectIDFactory.isValid},Object.assign(o,exports.ProjectIDBackwardCompat)},75478(e,exports,t){exports.ProjectSynchronizer=exports.ProjectFileSystem=exports.ProjectRegistry=void 0
19
+ var r=t(89955)
20
+ Object.defineProperty(exports,"ProjectRegistry",{enumerable:!0,get:function(){return r.ProjectRegistry}})
21
+ var i=t(53102)
22
+ Object.defineProperty(exports,"ProjectFileSystem",{enumerable:!0,get:function(){return i.DefaultProjectFileSystem}})
23
+ var o=t(52568)
24
+ Object.defineProperty(exports,"ProjectSynchronizer",{enumerable:!0,get:function(){return o.ProjectSynchronizer}}),t(26975)},89955(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
25
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectRegistry=void 0
26
+ const i=r(t(79896)),o=r(t(16928))
27
+ exports.ProjectRegistry=class{constructor(e,t={}){this.projects=new Map,this.verifiedIds=new Set,this.verifiedNames=new Map,this.logger=e.child({component:"project-registry"}),this.options={persistToDisk:t.persistToDisk??!1,storageDirectory:t.storageDirectory??"./temp-projects"},this.options.persistToDisk?this.logger.warn("Project persistence to disk is enabled - this may be legacy functionality"):this.logger.info("Project persistence to disk is disabled - this is the recommended configuration"),this.logger.info("ProjectRegistry initialized",{options:this.options,persistenceEnabled:this.options.persistToDisk})}register(e,t={}){if(!e.id)return void this.logger.warn("Attempted to register project without ID")
28
+ const r=t.markVerified??!1,i=t.saveToFile??this.options.persistToDisk
29
+ this.projects.set(e.id,e),r&&(this.verifiedIds.add(e.id),e.name&&this.verifiedNames.set(e.id,e.name)),this.logger.info("Registered project",{projectId:e.id,projectName:e.name,markVerified:r,saveToFile:i}),i&&(this.options.persistToDisk?this.saveProjectToFile(e):this.logger.debug("Skipping project file persistence (disabled in configuration)",{projectId:e.id}))}hasProject(e){return this.projects.has(e)}markVerified(e){this.verifiedIds.add(e),this.logger.info("Marked project as verified",{projectId:e})}isVerified(e){return this.verifiedIds.has(e)}markVerifiedWithName(e,t){this.verifiedIds.add(e),this.verifiedNames.set(e,t),this.logger.info("Marked project as verified with name",{projectId:e,projectName:t})}isVerifiedWithName(e,t){return this.verifiedIds.has(e)&&this.verifiedNames.get(e)===t}getVerifiedName(e){return this.verifiedNames.get(e)}getProject(e){return this.projects.get(e)}getAllProjects(){return Array.from(this.projects.values())}clearVerificationCache(e){e?(this.verifiedIds.delete(e),this.verifiedNames.delete(e),this.logger.info("Cleared verification for project",{projectId:e})):(this.verifiedIds.clear(),this.verifiedNames.clear(),this.logger.info("Cleared all project verifications"))}saveProjectToFile(e){try{if(!i.default.existsSync(this.options.storageDirectory))try{this.logger.info("Creating storage directory",{directory:this.options.storageDirectory,absolutePath:o.default.resolve(this.options.storageDirectory)}),i.default.mkdirSync(this.options.storageDirectory,{recursive:!0}),this.logger.info("Storage directory created successfully",{directory:this.options.storageDirectory,absolutePath:o.default.resolve(this.options.storageDirectory)})}catch(e){return void this.logger.error("Failed to create storage directory",{directory:this.options.storageDirectory,absolutePath:o.default.resolve(this.options.storageDirectory),error:e instanceof Error?e.stack:String(e)})}const t=o.default.join(this.options.storageDirectory,`project-${e.id}.json`)
30
+ i.default.writeFileSync(t,JSON.stringify(e,null,2),"utf8"),this.logger.info("Saved project to file",{projectId:e.id,filePath:t})}catch(t){this.logger.error("Failed to save project to file",{projectId:e.id,error:t instanceof Error?t.stack:String(t)})}}async loadFromDisk(){try{if(!i.default.existsSync(this.options.storageDirectory))try{return this.logger.info("Storage directory does not exist, creating it",{directory:this.options.storageDirectory,absolutePath:o.default.resolve(this.options.storageDirectory)}),i.default.mkdirSync(this.options.storageDirectory,{recursive:!0}),void this.logger.info("Storage directory created successfully",{directory:this.options.storageDirectory,absolutePath:o.default.resolve(this.options.storageDirectory)})}catch(e){return void this.logger.error("Failed to create storage directory",{directory:this.options.storageDirectory,absolutePath:o.default.resolve(this.options.storageDirectory),error:e instanceof Error?e.stack:String(e)})}const e=i.default.readdirSync(this.options.storageDirectory).filter(e=>e.startsWith("project-")&&e.endsWith(".json"))
31
+ this.logger.info("Loading projects from disk",{directory:this.options.storageDirectory,fileCount:e.length})
32
+ let t=0
33
+ for(const r of e)try{const e=o.default.join(this.options.storageDirectory,r),s=i.default.readFileSync(e,"utf8"),a=JSON.parse(s)
34
+ if(!a.id){this.logger.warn("Skipping project file with missing ID",{filePath:e})
35
+ continue}this.register(a,{saveToFile:!1}),t++}catch(e){this.logger.error("Error loading project file",{file:r,error:e instanceof Error?e.stack:String(e)})}this.logger.info("Finished loading projects from disk",{totalLoaded:t,totalFiles:e.length})}catch(e){this.logger.error("Failed to load projects from disk",{error:e instanceof Error?e.stack:String(e)})}}setStorageDirectory(e){this.options.storageDirectory=e,this.logger.info("Set storage directory",{directory:e})}setPersistToDisk(e){this.options.persistToDisk=e,this.logger.info("Set persist to disk",{persistToDisk:e})}}},52568(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
9
36
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectSynchronizer=void 0
10
37
  const i=r(t(16928)),o=t(18029),s=t(58824)
11
38
  exports.ProjectSynchronizer=class{constructor(e,t,r,i,o={}){this.logger=e.child({component:"project-synchronizer"}),this.registry=t,this.remoteApi=r,this.fileSystem=i,this.options={createRemoteProjects:o.createRemoteProjects??!0,maxRetryAttempts:o.maxRetryAttempts??3,retryDelayMs:o.retryDelayMs??1e3},this.logger.info("ProjectSynchronizer initialized",{options:this.options})}async ensureProjectExists(e){const t=Math.random().toString(36).substring(2,8)
12
- this.logger.info("\u{1f4de} SYNC-TRACE: ensureProjectExists called",{callId:t,projectId:e,stackTrace:(new Error).stack?.split("\n").slice(1,4).map((e=>e.trim())).join(" -> ")||"unknown"})
39
+ this.logger.info("\u{1f4de} SYNC-TRACE: ensureProjectExists called",{callId:t,projectId:e,stackTrace:(new Error).stack?.split("\n").slice(1,4).map(e=>e.trim()).join(" -> ")||"unknown"})
13
40
  try{if(!this.remoteApi.isOnline())return this.logger.info("\u{1f4de} SYNC-TRACE: System offline, returning original ID",{callId:t,projectId:e}),e
14
41
  if(this.logger.info("\u{1f4de} SYNC-TRACE: System online, proceeding",{callId:t,projectId:e}),this.registry.isVerified(e))return this.logger.info("\u{1f4de} SYNC-TRACE: Cache hit - already verified",{callId:t,projectId:e}),e
15
42
  this.logger.info("\u{1f4de} SYNC-TRACE: Cache miss - checking remote server",{callId:t,projectId:e})
@@ -31,7 +58,7 @@ if(this.registry.register(i),t&&await this.fileSystem.writeProjectFile(i,t),this
31
58
  this.logger.info("Starting project synchronization from directory",{basePath:e})
32
59
  const t=await this.fileSystem.readProjectFile(e)
33
60
  if(!t||!t.id)return void this.logger.info("No valid local project found, skipping synchronization",{basePath:e})
34
- this.logger.info("Found local project",{projectId:t.id,projectName:t.name}),this.logger.info("Registering project in registry before synchronization",{projectId:t.id,projectName:t.name}),this.registry.register(t),this.logger.info("Ensuring project exists on remote server",{projectId:t.id}),await this.ensureProjectExists(t.id)?(this.logger.info("Project exists on remote, checking metadata sync",{projectId:t.id,projectName:t.name,basePath:e}),t.metadata&&Object.keys(t.metadata).length>0&&(this.logger.info("Syncing project metadata to remote (async)",{projectId:t.id,metadataKeys:Object.keys(t.metadata)}),this.remoteApi.updateProject(t.id,{metadata:t.metadata}).then((()=>{this.logger.info("Project metadata synced successfully",{projectId:t.id})})).catch((e=>{this.logger.warn("Failed to sync project metadata",{projectId:t.id,error:e instanceof Error?e.message:String(e)})}))),this.logger.info("Successfully synchronized project",{projectId:t.id,projectName:t.name,basePath:e})):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:String(t)})}}async loadLocalProject(e){try{this.logger.info("Loading local project from directory",{basePath:e})
61
+ this.logger.info("Found local project",{projectId:t.id,projectName:t.name}),this.logger.info("Registering project in registry before synchronization",{projectId:t.id,projectName:t.name}),this.registry.register(t),this.logger.info("Ensuring project exists on remote server",{projectId:t.id}),await this.ensureProjectExists(t.id)?(this.logger.info("Project exists on remote, checking metadata sync",{projectId:t.id,projectName:t.name,basePath:e}),t.metadata&&Object.keys(t.metadata).length>0&&(this.logger.info("Syncing project metadata to remote (async)",{projectId:t.id,metadataKeys:Object.keys(t.metadata)}),this.remoteApi.updateProject(t.id,{metadata:t.metadata}).then(()=>{this.logger.info("Project metadata synced successfully",{projectId:t.id})}).catch(e=>{this.logger.warn("Failed to sync project metadata",{projectId:t.id,error:e instanceof Error?e.message:String(e)})})),this.logger.info("Successfully synchronized project",{projectId:t.id,projectName:t.name,basePath:e})):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:String(t)})}}async loadLocalProject(e){try{this.logger.info("Loading local project from directory",{basePath:e})
35
62
  const t=await this.fileSystem.readProjectFile(e)
36
63
  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:String(t)}),null}}async getOrCreateProject(e,t={}){this.logger.info("\u{1f680} getOrCreateProject called",{basePath:e,hasProjectData:!!Object.keys(t).length,projectData:Object.keys(t)})
37
64
  try{this.logger.info("Attempting to load existing local project",{basePath:e})
@@ -54,36 +81,9 @@ if(t.name===e.name)return this.logger.info("Project name matches remote, marking
54
81
  this.logger.info("Project name mismatch, updating remote name",{projectId:e.id,localName:e.name,remoteName:t.name})
55
82
  const r=this.options.maxRetryAttempts,i=this.options.retryDelayMs
56
83
  for(let t=1;t<=r;t++)try{return await this.remoteApi.updateProject(e.id,{name:e.name}),this.logger.info("Project name updated successfully",{projectId:e.id,newName:e.name}),this.registry.markVerifiedWithName&&this.registry.markVerifiedWithName(e.id,e.name),!0}catch(o){if(!(t<r))throw o
57
- this.logger.warn(`Failed to update project name, retrying (${t}/${r})`,{projectId:e.id,error:o instanceof Error?o.message:String(o)}),await new Promise((e=>setTimeout(e,i)))}return!1}catch(t){return this.logger.error("Failed to verify/fix project name",{projectId:e.id,projectName:e.name,error:t instanceof Error?t.stack:String(t)}),!1}}async syncProject(e,t){try{if(!this.remoteApi.isOnline())return this.logger.info("Skipping project synchronization - system is offline",{projectId:e}),!1
84
+ this.logger.warn(`Failed to update project name, retrying (${t}/${r})`,{projectId:e.id,error:o instanceof Error?o.message:String(o)}),await new Promise(e=>setTimeout(e,i))}return!1}catch(t){return this.logger.error("Failed to verify/fix project name",{projectId:e.id,projectName:e.name,error:t instanceof Error?t.stack:String(t)}),!1}}async syncProject(e,t){try{if(!this.remoteApi.isOnline())return this.logger.info("Skipping project synchronization - system is offline",{projectId:e}),!1
58
85
  let r=null
59
86
  if(t&&(r=await this.loadLocalProject(t),r&&r.id!==e&&(this.logger.warn("Project ID mismatch between request and loaded project",{requestedId:e,loadedId:r.id}),r=null)),!r){const t=this.registry.getProject(e)
60
87
  t&&(r=t)}if(!r)return this.logger.info("Project not found locally, attempting to fetch from remote",{projectId:e}),r=await this.remoteApi.fetchProject(e),r?(this.registry.register(r),t&&await this.fileSystem.writeProjectFile(r,t),!0):(this.logger.warn("Project not found locally or remotely",{projectId:e}),!1)
61
88
  if(!await this.ensureProjectExists(e))return!1
62
- if(await this.verifyAndFixProjectName(r)||this.logger.warn("Failed to verify/fix project name",{projectId:r.id,projectName:r.name}),r.metadata&&Object.keys(r.metadata).length>0)try{this.logger.info("Syncing project metadata to remote",{projectId:r.id,metadataKeys:Object.keys(r.metadata)}),await this.remoteApi.updateProject(r.id,{metadata:r.metadata}),this.logger.info("Project metadata synced successfully",{projectId:r.id})}catch(e){this.logger.warn("Failed to sync project metadata",{projectId:r.id,error:e instanceof Error?e.message:String(e)})}return this.logger.info("Project synchronization completed successfully",{projectId:e}),!0}catch(r){return this.logger.error("Error synchronizing project",{projectId:e,basePath:t,error:r instanceof Error?r.stack:String(r)}),!1}}}},53102:function(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
63
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.DefaultProjectFileSystem=void 0
64
- const i=r(t(79896)),o=r(t(16928)),s=t(14139)
65
- exports.DefaultProjectFileSystem=class{constructor(e){this.logger=e.child({component:"project-file-system"})}async readProjectFile(e){try{const t=o.default.join(e,"project.json"),r=o.default.join(e,s.ALCHEMY_DIR_NAME,"project.json")
66
- let a=r
67
- if(i.default.existsSync(t))a=t,this.logger.info("Found project file in base directory",{path:a})
68
- else{if(!i.default.existsSync(r))return this.logger.info("Project file does not exist in either location",{directPath:t,nestedPath:r}),null
69
- this.logger.info("Found project file in alchemy_lab subdirectory",{path:a})}const n=await i.default.promises.readFile(a,"utf8"),c=JSON.parse(n)
70
- return c.id?(this.logger.info("Read project file successfully",{projectId:c.id,path:a}),c):(this.logger.warn("Project file has no ID",{path:a}),null)}catch(t){return this.logger.error("Failed to read project file",{basePath:e,error:t instanceof Error?t.stack:String(t)}),null}}async writeProjectFile(e,t){try{const r=o.default.join(t,"project.json"),a=o.default.join(t,s.ALCHEMY_DIR_NAME,"project.json")
71
- let n=r
72
- !i.default.existsSync(r)&&i.default.existsSync(a)?(n=a,this.logger.info("Using existing nested path for project file",{path:n})):this.logger.info("Using direct path for project file",{path:n}),await this.ensureDirectoryExists(o.default.dirname(n)),await i.default.promises.writeFile(n,JSON.stringify(e,null,2),"utf8"),this.logger.info("Wrote project file successfully",{projectId:e.id,path:n})}catch(r){throw this.logger.error("Failed to write project file",{projectId:e.id,basePath:t,error:r instanceof Error?r.stack:String(r)}),r}}async ensureDirectoryExists(e){try{i.default.existsSync(e)||(await i.default.promises.mkdir(e,{recursive:!0}),this.logger.info("Created directory",{path:e}))}catch(t){throw this.logger.error("Failed to create directory",{path:e,error:t instanceof Error?t.stack:String(t)}),t}}}},75478:(e,exports,t)=>{exports.ProjectSynchronizer=exports.ProjectFileSystem=exports.ProjectRegistry=void 0
73
- var r=t(89955)
74
- Object.defineProperty(exports,"ProjectRegistry",{enumerable:!0,get:function(){return r.ProjectRegistry}})
75
- var i=t(53102)
76
- Object.defineProperty(exports,"ProjectFileSystem",{enumerable:!0,get:function(){return i.DefaultProjectFileSystem}})
77
- var o=t(52568)
78
- Object.defineProperty(exports,"ProjectSynchronizer",{enumerable:!0,get:function(){return o.ProjectSynchronizer}}),t(26975)},89955:function(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
79
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectRegistry=void 0
80
- const i=r(t(79896)),o=r(t(16928))
81
- exports.ProjectRegistry=class{constructor(e,t={}){this.projects=new Map,this.verifiedIds=new Set,this.verifiedNames=new Map,this.logger=e.child({component:"project-registry"}),this.options={persistToDisk:t.persistToDisk??!1,storageDirectory:t.storageDirectory??"./temp-projects"},this.options.persistToDisk?this.logger.warn("Project persistence to disk is enabled - this may be legacy functionality"):this.logger.info("Project persistence to disk is disabled - this is the recommended configuration"),this.logger.info("ProjectRegistry initialized",{options:this.options,persistenceEnabled:this.options.persistToDisk})}register(e,t={}){if(!e.id)return void this.logger.warn("Attempted to register project without ID")
82
- const r=t.markVerified??!1,i=t.saveToFile??this.options.persistToDisk
83
- this.projects.set(e.id,e),r&&(this.verifiedIds.add(e.id),e.name&&this.verifiedNames.set(e.id,e.name)),this.logger.info("Registered project",{projectId:e.id,projectName:e.name,markVerified:r,saveToFile:i}),i&&(this.options.persistToDisk?this.saveProjectToFile(e):this.logger.debug("Skipping project file persistence (disabled in configuration)",{projectId:e.id}))}hasProject(e){return this.projects.has(e)}markVerified(e){this.verifiedIds.add(e),this.logger.info("Marked project as verified",{projectId:e})}isVerified(e){return this.verifiedIds.has(e)}markVerifiedWithName(e,t){this.verifiedIds.add(e),this.verifiedNames.set(e,t),this.logger.info("Marked project as verified with name",{projectId:e,projectName:t})}isVerifiedWithName(e,t){return this.verifiedIds.has(e)&&this.verifiedNames.get(e)===t}getVerifiedName(e){return this.verifiedNames.get(e)}getProject(e){return this.projects.get(e)}getAllProjects(){return Array.from(this.projects.values())}clearVerificationCache(e){e?(this.verifiedIds.delete(e),this.verifiedNames.delete(e),this.logger.info("Cleared verification for project",{projectId:e})):(this.verifiedIds.clear(),this.verifiedNames.clear(),this.logger.info("Cleared all project verifications"))}saveProjectToFile(e){try{if(!i.default.existsSync(this.options.storageDirectory))try{this.logger.info("Creating storage directory",{directory:this.options.storageDirectory,absolutePath:o.default.resolve(this.options.storageDirectory)}),i.default.mkdirSync(this.options.storageDirectory,{recursive:!0}),this.logger.info("Storage directory created successfully",{directory:this.options.storageDirectory,absolutePath:o.default.resolve(this.options.storageDirectory)})}catch(e){return void this.logger.error("Failed to create storage directory",{directory:this.options.storageDirectory,absolutePath:o.default.resolve(this.options.storageDirectory),error:e instanceof Error?e.stack:String(e)})}const t=o.default.join(this.options.storageDirectory,`project-${e.id}.json`)
84
- i.default.writeFileSync(t,JSON.stringify(e,null,2),"utf8"),this.logger.info("Saved project to file",{projectId:e.id,filePath:t})}catch(t){this.logger.error("Failed to save project to file",{projectId:e.id,error:t instanceof Error?t.stack:String(t)})}}async loadFromDisk(){try{if(!i.default.existsSync(this.options.storageDirectory))try{return this.logger.info("Storage directory does not exist, creating it",{directory:this.options.storageDirectory,absolutePath:o.default.resolve(this.options.storageDirectory)}),i.default.mkdirSync(this.options.storageDirectory,{recursive:!0}),void this.logger.info("Storage directory created successfully",{directory:this.options.storageDirectory,absolutePath:o.default.resolve(this.options.storageDirectory)})}catch(e){return void this.logger.error("Failed to create storage directory",{directory:this.options.storageDirectory,absolutePath:o.default.resolve(this.options.storageDirectory),error:e instanceof Error?e.stack:String(e)})}const e=i.default.readdirSync(this.options.storageDirectory).filter((e=>e.startsWith("project-")&&e.endsWith(".json")))
85
- this.logger.info("Loading projects from disk",{directory:this.options.storageDirectory,fileCount:e.length})
86
- let t=0
87
- for(const r of e)try{const e=o.default.join(this.options.storageDirectory,r),s=i.default.readFileSync(e,"utf8"),a=JSON.parse(s)
88
- if(!a.id){this.logger.warn("Skipping project file with missing ID",{filePath:e})
89
- continue}this.register(a,{saveToFile:!1}),t++}catch(e){this.logger.error("Error loading project file",{file:r,error:e instanceof Error?e.stack:String(e)})}this.logger.info("Finished loading projects from disk",{totalLoaded:t,totalFiles:e.length})}catch(e){this.logger.error("Failed to load projects from disk",{error:e instanceof Error?e.stack:String(e)})}}setStorageDirectory(e){this.options.storageDirectory=e,this.logger.info("Set storage directory",{directory:e})}setPersistToDisk(e){this.options.persistToDisk=e,this.logger.info("Set persist to disk",{persistToDisk:e})}}}}
89
+ if(await this.verifyAndFixProjectName(r)||this.logger.warn("Failed to verify/fix project name",{projectId:r.id,projectName:r.name}),r.metadata&&Object.keys(r.metadata).length>0)try{this.logger.info("Syncing project metadata to remote",{projectId:r.id,metadataKeys:Object.keys(r.metadata)}),await this.remoteApi.updateProject(r.id,{metadata:r.metadata}),this.logger.info("Project metadata synced successfully",{projectId:r.id})}catch(e){this.logger.warn("Failed to sync project metadata",{projectId:r.id,error:e instanceof Error?e.message:String(e)})}return this.logger.info("Project synchronization completed successfully",{projectId:e}),!0}catch(r){return this.logger.error("Error synchronizing project",{projectId:e,basePath:t,error:r instanceof Error?r.stack:String(r)}),!1}}}}}
package/dist/579.js CHANGED
@@ -1,11 +1,11 @@
1
1
  "use strict"
2
- exports.id=579,exports.ids=[579],exports.modules={74579:(e,exports,t)=>{function n(e){const t=/(?:^|[\s:])([A-Za-z0-9_.+-]+): (?:command )?not found(?=\s|$)/m.exec(e)
3
- return t?t[1]:null}async function a(e,n,a){const{actionServerFetch:s}=await Promise.resolve().then(t.bind(t,79414))
4
- return(await s(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n),signal:AbortSignal.timeout(a)})).json().catch((()=>({})))}exports.trialFailures=function(e){const t=[]
2
+ exports.ids=[579],exports.modules={74579(e,exports,t){function n(e){const t=/(?:^|[\s:])([A-Za-z0-9_.+-]+): (?:command )?not found(?=\s|$)/m.exec(e)
3
+ return t?t[1]:null}async function a(e,n,a){const{actionServerFetch:s}=await Promise.resolve().then(()=>t(79414))
4
+ return(await s(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n),signal:AbortSignal.timeout(a)})).json().catch(()=>({}))}exports.trialFailures=function(e){const t=[]
5
5
  for(const a of e){const e=n(a.output)
6
- e?t.push(`${a.name}: the environment has no \`${e}\` (the command ran, but the shell said "${e}: not found")`):0!==a.exit&&t.push(`${a.name}: exited ${a.exit}: ${a.output.replace(/\s+/g," ").trim().slice(0,240)}`)}return t},exports.trialRun=async function(e){const t=await a("/api/experiments/start",{sessionId:e.sessionId,environmentId:e.environmentId,...e.branchName?{branchName:e.branchName}:{}},18e4).catch((()=>null)),n=t?.success?t?.data?.handle:null
6
+ e?t.push(`${a.name}: the environment has no \`${e}\` (the command ran, but the shell said "${e}: not found")`):0!==a.exit&&t.push(`${a.name}: exited ${a.exit}: ${a.output.replace(/\s+/g," ").trim().slice(0,240)}`)}return t},exports.trialRun=async function(e){const t=await a("/api/experiments/start",{sessionId:e.sessionId,environmentId:e.environmentId,...e.branchName?{branchName:e.branchName}:{}},18e4).catch(()=>null),n=t?.success?t?.data?.handle:null
7
7
  if(!n)return null
8
8
  const s=[]
9
- try{for(const t of e.setup){const e=await a("/api/experiments/exec",{handle:n,command:t,timeoutMs:3e5,why:"trial of a check before it is registered (setup)"},32e4).catch((()=>null)),o=e?.data??{}
10
- if(!e?.success||0!==o.exit)return s.push({name:`setup: ${t.slice(0,60)}`,command:t,exit:"number"==typeof o.exit?o.exit:-1,output:`${o.stdout??""}\n${o.stderr??e?.error??""}`}),s}for(const t of e.commands){const e=1e3*Math.min(Math.max(t.timeout,10),300),o=await a("/api/experiments/exec",{handle:n,command:t.command,timeoutMs:e,why:"trial of a check before it is registered"},e+2e4).catch((()=>null)),i=o?.data??{}
11
- s.push({name:t.name,command:t.command,exit:"number"==typeof i.exit?i.exit:-1,output:`${i.stdout??""}\n${i.stderr??(o?.success?"":o?.error??"no result")}`})}}finally{await a("/api/experiments/stop",{handle:n},3e4).catch((()=>null))}return s}}}
9
+ try{for(const t of e.setup){const e=await a("/api/experiments/exec",{handle:n,command:t,timeoutMs:3e5,why:"trial of a check before it is registered (setup)"},32e4).catch(()=>null),o=e?.data??{}
10
+ if(!e?.success||0!==o.exit)return s.push({name:`setup: ${t.slice(0,60)}`,command:t,exit:"number"==typeof o.exit?o.exit:-1,output:`${o.stdout??""}\n${o.stderr??e?.error??""}`}),s}for(const t of e.commands){const e=1e3*Math.min(Math.max(t.timeout,10),300),o=await a("/api/experiments/exec",{handle:n,command:t.command,timeoutMs:e,why:"trial of a check before it is registered"},e+2e4).catch(()=>null),i=o?.data??{}
11
+ s.push({name:t.name,command:t.command,exit:"number"==typeof i.exit?i.exit:-1,output:`${i.stdout??""}\n${i.stderr??(o?.success?"":o?.error??"no result")}`})}}finally{await a("/api/experiments/stop",{handle:n},3e4).catch(()=>null)}return s}}}
package/dist/60.js CHANGED
@@ -1,14 +1,14 @@
1
1
  "use strict"
2
- exports.id=60,exports.ids=[60],exports.modules={49060:function(t,exports,e){var a=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}}
2
+ exports.ids=[60],exports.modules={49060(t,exports,e){var a=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}}
3
3
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConfigManager=void 0,exports.createConfigManager=function(t){return new g(t)}
4
- const i=a(e(91943)),n=a(e(16928)),o=a(e(70857)),r=e(14139),s=e(58824),c={},l={remoteServerUrl:"https://api.alchemylabcode.com",nodePath:"node"}
5
- class g{constructor(t){this.logger=t.child({component:"config-manager"}),this.installationConfigDir=this.getInstallationConfigDir()}getInstallationConfigDir(){const t=__dirname||process.cwd(),e=o.default.homedir()
4
+ const i=a(e(91943)),n=a(e(16928)),r=a(e(70857)),o=e(14139),s=e(58824),l={},c={remoteServerUrl:"https://api.alchemylabcode.com",nodePath:"node"}
5
+ class g{constructor(t){this.logger=t.child({component:"config-manager"}),this.installationConfigDir=this.getInstallationConfigDir()}getInstallationConfigDir(){const t=__dirname||process.cwd(),e=r.default.homedir()
6
6
  return t.includes("node_modules")?n.default.join(e,".alchemy_lab","config"):n.default.join(e,".alchemy_lab","config-dev")}async ensureDirectory(t){try{await i.default.access(t)}catch(e){await i.default.mkdir(t,{recursive:!0}),this.logger.debug("Created directory",{dirPath:t})}}async readConfig(t,e){try{const a=await i.default.readFile(t,"utf8"),n=JSON.parse(a)
7
- return{...e,...n}}catch(a){return"ENOENT"===a.code||this.logger.warn("Error reading config file, using defaults",{filePath:t,error:(0,s.getErrorMessage)(a)}),e}}async writeConfig(t,e){await this.ensureDirectory(n.default.dirname(t)),await i.default.writeFile(t,JSON.stringify(e,null,2),"utf8"),this.logger.debug("Wrote config file",{filePath:t})}async getProjectConfig(t){const e=n.default.join(t,r.ALCHEMY_DIR_NAME,"config.json")
8
- return this.readConfig(e,c)}async updateProjectConfig(t,e){const a=n.default.join(t,r.ALCHEMY_DIR_NAME,"config.json"),i={...await this.getProjectConfig(t),...e}
9
- await this.writeConfig(a,i),this.logger.info("Updated project config",{projectPath:t,updates:e})}async getProjectMetadata(t){const e=n.default.join(t,r.ALCHEMY_DIR_NAME,"project.json")
7
+ return{...e,...n}}catch(a){return"ENOENT"===a.code||this.logger.warn("Error reading config file, using defaults",{filePath:t,error:(0,s.getErrorMessage)(a)}),e}}async writeConfig(t,e){await this.ensureDirectory(n.default.dirname(t)),await i.default.writeFile(t,JSON.stringify(e,null,2),"utf8"),this.logger.debug("Wrote config file",{filePath:t})}async getProjectConfig(t){const e=n.default.join(t,o.ALCHEMY_DIR_NAME,"config.json")
8
+ return this.readConfig(e,l)}async updateProjectConfig(t,e){const a=n.default.join(t,o.ALCHEMY_DIR_NAME,"config.json"),i={...await this.getProjectConfig(t),...e}
9
+ await this.writeConfig(a,i),this.logger.info("Updated project config",{projectPath:t,updates:e})}async getProjectMetadata(t){const e=n.default.join(t,o.ALCHEMY_DIR_NAME,"project.json")
10
10
  try{const t=await i.default.readFile(e,"utf8"),a=JSON.parse(t)
11
11
  return{id:a.id,name:a.name,createdAt:a.createdAt,status:a.status}}catch(t){return"ENOENT"===t.code||this.logger.warn("Error reading project metadata",{projectJsonPath:e,error:(0,s.getErrorMessage)(t)}),null}}async getInstallationConfig(){const t=n.default.join(this.installationConfigDir,"config.json")
12
- return this.readConfig(t,l)}async updateInstallationConfig(t){const e=n.default.join(this.installationConfigDir,"config.json"),a={...await this.getInstallationConfig(),...t}
12
+ return this.readConfig(t,c)}async updateInstallationConfig(t){const e=n.default.join(this.installationConfigDir,"config.json"),a={...await this.getInstallationConfig(),...t}
13
13
  await this.writeConfig(e,a),this.logger.info("Updated installation config",{updates:t})}async getEffectiveConfig(t){const[e,a,i]=await Promise.all([this.getProjectConfig(t),this.getProjectMetadata(t),this.getInstallationConfig()])
14
- return{remoteServerUrl:i.remoteServerUrl||l.remoteServerUrl,nodePath:i.nodePath||l.nodePath,projectId:a?.id,projectName:a?.name}}getInstallationConfigPath(){return this.installationConfigDir}}exports.ConfigManager=g}}
14
+ return{remoteServerUrl:i.remoteServerUrl||c.remoteServerUrl,nodePath:i.nodePath||c.nodePath,projectId:a?.id,projectName:a?.name}}getInstallationConfigPath(){return this.installationConfigDir}}exports.ConfigManager=g}}
package/dist/729.js CHANGED
@@ -1,28 +1,28 @@
1
1
  "use strict"
2
- exports.id=729,exports.ids=[729],exports.modules={92729:(e,exports,t)=>{async function n(e){if(p&&Date.now()-p.at<d)return p.servers
2
+ exports.ids=[729],exports.modules={92729(e,exports,t){async function n(e){if(d&&Date.now()-d.at<3e4)return d.servers
3
3
  try{const t=await e.apiClient.get(`/api/projects/${e.projectId}/mcp-servers`),n=t?.data??t??[]
4
- if(Array.isArray(n))return p={at:Date.now(),servers:n},n}catch(t){e.logger.warn("MCP gate: could not read the registry",{error:(0,c.getErrorMessage)(t)})}return p?.servers??[]}function r(e){return e.filter((e=>e.enabled)).map((e=>e.name))}function o(e,t){const n=[...t].sort(((e,t)=>t.length-e.length))
4
+ if(Array.isArray(n))return d={at:Date.now(),servers:n},n}catch(t){e.logger.warn("MCP gate: could not read the registry",{error:(0,c.getErrorMessage)(t)})}return d?.servers??[]}function r(e){return e.filter(e=>e.enabled).map(e=>e.name)}function o(e,t){const n=[...t].sort((e,t)=>t.length-e.length)
5
5
  for(const t of n){const n=`${t}_`
6
6
  if(e.startsWith(n)&&e.length>n.length)return{server:t,tool:e.slice(n.length)}}return null}function s(e,t=200){if(!e||"object"!=typeof e||Array.isArray(e))return""
7
7
  const n=Object.entries(e)
8
8
  if(0===n.length)return""
9
- const r=e=>{const t=u.indexOf(e)
10
- return-1===t?u.length:t}
11
- n.sort(((e,t)=>r(e[0])-r(t[0])))
9
+ const r=e=>{const t=p.indexOf(e)
10
+ return-1===t?p.length:t}
11
+ n.sort((e,t)=>r(e[0])-r(t[0]))
12
12
  const o=[]
13
13
  for(const[e,t]of n){if(o.length>=4)break
14
14
  let n
15
15
  if("string"==typeof t)n=t.length>80?`${t.length} characters`:t
16
16
  else if("number"==typeof t||"boolean"==typeof t)n=String(t)
17
- else if(Array.isArray(t)){const e=t.filter((e=>"string"==typeof e))
17
+ else if(Array.isArray(t)){const e=t.filter(e=>"string"==typeof e)
18
18
  n=e.length===t.length&&e.join(", ").length<=80?e.join(", "):`${t.length} items`}else{if(null==t)continue
19
19
  n="an object"}o.push(`${e}: ${n}`)}const s=o.join(", ")
20
20
  return s.length>t?`${s.slice(0,t-1)}\u2026`:s}function i(e,t,n,r){const o=[`Let an agent run ${t} on "${e}", an MCP server this project is connected to?`],i=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return""
21
- const t=s(e,400).split(", ").map((e=>{const t=e.indexOf(": ")
22
- return-1===t?null:[e.slice(0,t),e.slice(t+2)]})).filter(Boolean)
21
+ const t=s(e,400).split(", ").map(e=>{const t=e.indexOf(": ")
22
+ return-1===t?null:[e.slice(0,t),e.slice(t+2)]}).filter(Boolean)
23
23
  if(0===t.length)return""
24
- const n=Math.max(...t.map((([e])=>e.length)))
25
- return t.map((([e,t])=>` ${e.padEnd(n)} ${t}`)).join("\n")}(r)
24
+ const n=Math.max(...t.map(([e])=>e.length))
25
+ return t.map(([e,t])=>` ${e.padEnd(n)} ${t}`).join("\n")}(r)
26
26
  i&&o.push(i)
27
27
  const a=n?`This runs inside "${e}", not in this project. The server's own note on ${t}: ${function(e,t=220){const n=e.trim().replace(/\s+/g," ")
28
28
  if(n.length<=t)return n
@@ -30,18 +30,18 @@ const r=n.slice(0,t),o=Math.max(r.lastIndexOf(". "),r.lastIndexOf("! "),r.lastIn
30
30
  if(o>.4*t)return r.slice(0,o+1)
31
31
  const s=r.lastIndexOf(" ")
32
32
  return`${r.slice(0,s>0?s:t)}\u2026`}(n)}`:`This runs inside "${e}", not in this project, and the server does not say what ${t} does.`
33
- return o.push(a),o.join("\n\n")}exports.invalidateMcpRegistry=function(){p=null},exports.getRegisteredMcpServers=n,exports.gatedNamespaces=r,exports.splitToolKey=o,exports.summariseArgs=s,exports.gateMcpCall=async function(e,c){const d=await n(e),p=o(c.toolName,r(d))
33
+ return o.push(a),o.join("\n\n")}exports.invalidateMcpRegistry=function(){d=null},exports.getRegisteredMcpServers=n,exports.gatedNamespaces=r,exports.splitToolKey=o,exports.summariseArgs=s,exports.gateMcpCall=async function(e,c){const d=await n(e),p=o(c.toolName,r(d))
34
34
  if(!p)return{allow:!0,verdict:"not-external",reason:"Not a registered MCP connection tool"}
35
- const u=d.find((e=>e.name===p.server))
35
+ const u=d.find(e=>e.name===p.server)
36
36
  if(!u||!u.enabled)return{allow:!1,verdict:"unknown-connection",reason:`the MCP server "${p.server}" is not enabled for this project`}
37
- if(function(e,t){const n=e?.find((e=>e.name===t))
37
+ if(function(e,t){const n=e?.find(e=>e.name===t)
38
38
  return!0===n?.readOnly}(u.toolManifest,p.tool))return{allow:!0,verdict:"read-only",reason:`the ${p.server} MCP server marks ${p.tool} read-only`}
39
- const{requestForSession:f}=await t.e(111).then(t.bind(t,56111)),h=c.sessionId?await f(e,c.sessionId):void 0,g=h??c.sessionId,v=g?`mcp:${p.server}:${g}`:`mcp:${p.server}`,y=s(c.args),$=y?`MCP ${p.server} \xb7 ${p.tool} (${y})`:`MCP ${p.server} \xb7 ${p.tool}`,m=u.toolManifest?.find((e=>e.name===p.tool))?.description
39
+ const{requestForSession:f}=await t.e(111).then(()=>t(56111)),h=c.sessionId?await f(e,c.sessionId):void 0,g=h??c.sessionId,v=g?`mcp:${p.server}:${g}`:`mcp:${p.server}`,y=s(c.args),$=y?`MCP ${p.server} \xb7 ${p.tool} (${y})`:`MCP ${p.server} \xb7 ${p.tool}`,m=u.toolManifest?.find(e=>e.name===p.tool)?.description
40
40
  if((0,a.isSessionAllowed)(v))return{allow:!0,verdict:"session-allowed",reason:h?`already allowed for ${h}`:"already allowed for this run"}
41
41
  const{id:w,promise:b,created:j}=(0,a.createApproval)(v,$)
42
42
  w&&j&&c.sessionId&&(0,l.bridgeApprovalToNotification)(e.apiClient,e.projectId,{approvalId:w,approvalKey:v,sessionId:c.sessionId,command:$,question:i(p.server,p.tool,m,c.args),approveOption:{description:`Run it once, in "${p.server}"`},denyOption:{description:"Do not run it; the agent is told it was declined"},allowSessionOption:h?{label:`Allow for the rest of ${h}`,description:`Run it, and stop asking about "${p.server}" for the rest of this request`}:{label:"Allow while this agent keeps working",description:`Run it, and stop asking about "${p.server}" until this agent finishes`}})
43
43
  const M=await b
44
44
  return"deny"===M?{allow:!1,verdict:"denied",reason:"a person declined it"}:"timeout"===M?{allow:!1,verdict:"timeout",reason:"nobody answered the approval in time"}:{allow:!0,verdict:"approved",reason:"a person approved it"}}
45
- const a=t(84352),l=t(20512),c=t(58824),d=3e4
46
- let p=null
47
- const u=["path","file","filename","file_path","filePath","paths","url","uri","endpoint","repo","repository","branch","id","key","name","title","query","q","command","sql","table"]}}
45
+ const a=t(84352),l=t(20512),c=t(58824)
46
+ let d=null
47
+ const p=["path","file","filename","file_path","filePath","paths","url","uri","endpoint","repo","repository","branch","id","key","name","title","query","q","command","sql","table"]}}
package/dist/776.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict"
2
- exports.id=776,exports.ids=[776],exports.modules={37776:function(t,exports,e){function r(t,e){return new Promise((r=>{(0,l.execFile)("git",e,{cwd:t,maxBuffer:16777216},((t,e,i)=>{r({code:t?"number"==typeof t.code?t.code:1:0,stdout:String(e??""),stderr:String(i??"")})}))}))}async function i(t){return 0===(await r(t,["rev-parse","--verify","--quiet","HEAD"])).code}function s(t){try{return u.realpathSync(t)}catch{return d.resolve(t)}}var o,a=this&&this.__createBinding||(Object.create?function(t,e,r,i){void 0===i&&(i=r)
2
+ exports.ids=[776],exports.modules={37776(t,exports,e){function r(t,e){return new Promise(r=>{(0,l.execFile)("git",e,{cwd:t,maxBuffer:16777216},(t,e,i)=>{r({code:t?"number"==typeof t.code?t.code:1:0,stdout:String(e??""),stderr:String(i??"")})})})}async function i(t){return 0===(await r(t,["rev-parse","--verify","--quiet","HEAD"])).code}function s(t){try{return u.realpathSync(t)}catch{return d.resolve(t)}}var o,a=this&&this.__createBinding||(Object.create?function(t,e,r,i){void 0===i&&(i=r)
3
3
  var s=Object.getOwnPropertyDescriptor(e,r)
4
4
  s&&!("get"in s?!e.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,i,s)}:function(t,e,r,i){void 0===i&&(i=r),t[i]=e[r]}),n=this&&this.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),c=this&&this.__importStar||(o=function(t){return o=Object.getOwnPropertyNames||function(t){var e=[]
5
5
  for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[e.length]=r)
package/dist/800.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict"
2
- exports.id=800,exports.ids=[800],exports.modules={93800:function(e,exports,t){var r,o=this&&this.__createBinding||(Object.create?function(e,t,r,o){void 0===o&&(o=r)
2
+ exports.ids=[800],exports.modules={93800(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
4
  i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return 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)Object.prototype.hasOwnProperty.call(e,r)&&(t[t.length]=r)
@@ -19,4 +19,4 @@ for(let t=1;t<=e;t++){await this.sleep(this.checkIntervalMs)
19
19
  const r=await this.loadExistingProject()
20
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}
21
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)))}}}}
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))}}}}
package/dist/816.js CHANGED
@@ -1,4 +1,3 @@
1
1
  "use strict"
2
- exports.id=816,exports.ids=[816],exports.modules={1816:(t,exports)=>{exports.formatCombinedOutput=function(t,e){const n=e.maxOut??o,u=t.length>n
3
- return{output:u?"\u2026"+t.slice(-n):t,truncatedNote:u?`\n_(output truncated: view full with \`log:${e.invocationId}\`)_`:"",logFooter:`Log: \`log:${e.invocationId}\``}}
4
- const o=3e3}}
2
+ exports.ids=[816],exports.modules={1816(t,exports){exports.formatCombinedOutput=function(t,o){const e=o.maxOut??3e3,u=t.length>e
3
+ return{output:u?"\u2026"+t.slice(-e):t,truncatedNote:u?`\n_(output truncated: view full with \`log:${o.invocationId}\`)_`:"",logFooter:`Log: \`log:${o.invocationId}\``}}}}
package/dist/939.js CHANGED
@@ -1,17 +1,17 @@
1
1
  "use strict"
2
- exports.id=939,exports.ids=[939],exports.modules={49939:function(e,exports,t){function r(e){return i.default.createHash("md5").update(e).digest("hex")}async function s(e){try{return r(await o.default.promises.readFile(e))}catch{return null}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
3
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.syncPluginsGlobal=async function(e,t,n){const i={synced:[],skipped:[],errors:[]},l=n||function(){const e=process.argv[1]
2
+ exports.ids=[939],exports.modules={49939(e,exports,t){function r(e){return i.default.createHash("md5").update(e).digest("hex")}async function s(e){try{return r(await a.default.promises.readFile(e))}catch{return null}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
3
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.syncPluginsGlobal=async function(e,t,n){const i={synced:[],skipped:[],errors:[]},c=n||function(){const e=process.argv[1]
4
4
  let t=e
5
- try{t=o.default.realpathSync(e)}catch{}return a.default.dirname(t)}(),d=a.default.join((0,u.getGlobalConfigDir)(e),"plugin")
6
- try{await o.default.promises.mkdir(d,{recursive:!0})}catch(e){return t.error("Failed to create global plugin directory",{destDir:d,error:e instanceof Error?e.message:"Unknown error"}),i}const f=a.default.join(d,"package.json"),p='{"type":"module"}\n'
7
- try{await o.default.promises.readFile(f,"utf8").catch((()=>null))!==p&&await o.default.promises.writeFile(f,p,"utf8")}catch(e){t.warn("Failed to write global plugin package.json",{error:e instanceof Error?e.message:"Unknown error"})}for(const e of c){const n=a.default.join(l,e.sourceName),u=a.default.join(d,e.destName)
8
- try{if(!o.default.existsSync(n)){t.warn(`Plugin source not found: ${e.sourceName}`,{sourcePath:n}),i.errors.push(e.destName)
9
- continue}const a=await o.default.promises.readFile(n,"utf8").catch((()=>null))
10
- if(null===a){t.warn(`Could not read plugin source: ${e.sourceName}`),i.errors.push(e.destName)
11
- continue}const c=r(a),l=await s(u)
12
- null===l||c!==l?(await o.default.promises.writeFile(u,a,"utf8"),t.info(`Synced plugin: ${e.destName}`,{destDir:d,reason:null===l?"not installed":"updated"}),i.synced.push(e.destName)):i.skipped.push(e.destName)}catch(r){t.error(`Failed to sync plugin: ${e.destName}`,{error:r instanceof Error?r.message:"Unknown error"}),i.errors.push(e.destName)}}return i.synced.length>0&&t.info("Synced global plugins",{destDir:d,synced:i.synced}),i},exports.cleanupLegacyProjectPlugins=async function(e,t){const r=a.default.join(e,".opencode","plugin"),s=[]
13
- if(!o.default.existsSync(r))return{removed:s}
14
- for(const e of l){const t=a.default.join(r,e)
15
- if(o.default.existsSync(t))try{await o.default.promises.rm(t,{recursive:!0,force:!0}),s.push(e)}catch{}}s.length>0&&t.info("Removed legacy per-project plugin copies",{projectPluginDir:r,removed:s})
16
- try{0===(await o.default.promises.readdir(r)).length&&await o.default.promises.rmdir(r)}catch{}return{removed:s}}
17
- const o=n(t(79896)),a=n(t(16928)),i=n(t(76982)),u=t(35419),c=[{sourceName:"plugins/hooks/plugin.js",destName:"event-hooks.js"},{sourceName:"plugins/inject-session.js",destName:"inject-session.js"},{sourceName:"plugins/system-logger.js",destName:"system-logger.js"}],l=[...c.map((e=>e.destName)),"package.json","lib"]}}
5
+ try{t=a.default.realpathSync(e)}catch{}return o.default.dirname(t)}(),d=o.default.join((0,u.getGlobalConfigDir)(e),"plugin")
6
+ try{await a.default.promises.mkdir(d,{recursive:!0})}catch(e){return t.error("Failed to create global plugin directory",{destDir:d,error:e instanceof Error?e.message:"Unknown error"}),i}const f=o.default.join(d,"package.json"),p='{"type":"module"}\n'
7
+ try{await a.default.promises.readFile(f,"utf8").catch(()=>null)!==p&&await a.default.promises.writeFile(f,p,"utf8")}catch(e){t.warn("Failed to write global plugin package.json",{error:e instanceof Error?e.message:"Unknown error"})}for(const e of l){const n=o.default.join(c,e.sourceName),u=o.default.join(d,e.destName)
8
+ try{if(!a.default.existsSync(n)){t.warn(`Plugin source not found: ${e.sourceName}`,{sourcePath:n}),i.errors.push(e.destName)
9
+ continue}const o=await a.default.promises.readFile(n,"utf8").catch(()=>null)
10
+ if(null===o){t.warn(`Could not read plugin source: ${e.sourceName}`),i.errors.push(e.destName)
11
+ continue}const l=r(o),c=await s(u)
12
+ null===c||l!==c?(await a.default.promises.writeFile(u,o,"utf8"),t.info(`Synced plugin: ${e.destName}`,{destDir:d,reason:null===c?"not installed":"updated"}),i.synced.push(e.destName)):i.skipped.push(e.destName)}catch(r){t.error(`Failed to sync plugin: ${e.destName}`,{error:r instanceof Error?r.message:"Unknown error"}),i.errors.push(e.destName)}}return i.synced.length>0&&t.info("Synced global plugins",{destDir:d,synced:i.synced}),i},exports.cleanupLegacyProjectPlugins=async function(e,t){const r=o.default.join(e,".opencode","plugin"),s=[]
13
+ if(!a.default.existsSync(r))return{removed:s}
14
+ for(const e of c){const t=o.default.join(r,e)
15
+ if(a.default.existsSync(t))try{await a.default.promises.rm(t,{recursive:!0,force:!0}),s.push(e)}catch{}}s.length>0&&t.info("Removed legacy per-project plugin copies",{projectPluginDir:r,removed:s})
16
+ try{0===(await a.default.promises.readdir(r)).length&&await a.default.promises.rmdir(r)}catch{}return{removed:s}}
17
+ const a=n(t(79896)),o=n(t(16928)),i=n(t(76982)),u=t(35419),l=[{sourceName:"plugins/hooks/plugin.js",destName:"event-hooks.js"},{sourceName:"plugins/inject-session.js",destName:"inject-session.js"},{sourceName:"plugins/system-logger.js",destName:"system-logger.js"}],c=[...l.map(e=>e.destName),"package.json","lib"]}}
package/dist/991.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict"
2
- exports.id=991,exports.ids=[991],exports.modules={18991:(e,exports,n)=>{async function t(e,t){const s=l.get(e)
2
+ exports.ids=[991],exports.modules={18991(e,exports,n){async function t(e,t){const s=i.get(e)
3
3
  if(s&&!s.checking){s.checking=!0
4
4
  try{const r=(0,a.getOpenCodeUrlFromConfig)(s.context.projectPath)?.replace(/\/$/,"")
5
5
  if(!r)return
@@ -7,20 +7,20 @@ if(await async function(e,n){try{const t=await fetch(`${e}/session/status`,{sign
7
7
  if(!t.ok)return!1
8
8
  const o=await t.json(),a=o?.[n]?.type
9
9
  return!!a&&"idle"!==a}catch{return!1}}(r,e))return
10
- if(!l.has(e))return
11
- if(d.has(e))return void o(e,"already-nudged")
12
- d.add(e),o(e,`nudging (${t})`)
13
- const{executeAction:i}=await Promise.resolve().then(n.bind(n,5607)),f=s.planWritten?exports.vB:c,u=await i("inject-prompt",{sessionId:e,message:f},s.context)
14
- u.success?s.context.logger.info("planner-handoff watch: nudge injected",{sessionId:e,trigger:t}):s.context.logger.warn("planner-handoff watch: nudge inject failed",{sessionId:e,trigger:t,error:u.error||u.message})}catch(n){s.context.logger.warn("planner-handoff watch: check failed",{sessionId:e,trigger:t,error:(0,r.getErrorMessage)(n)})}finally{s.checking=!1}}}function o(e,n){const t=l.get(e)
15
- t&&(clearTimeout(t.expiry),t.poll&&clearInterval(t.poll),l.delete(e),t.context.logger.info("planner-handoff watch: stopped",{sessionId:e,reason:n}))}exports.vB=void 0,exports.trackAutonomousPlanner=function(e,n){if(!n||l.has(n)||d.has(n))return
16
- const a=setTimeout((()=>{o(n,"ttl-expired")}),i)
10
+ if(!i.has(e))return
11
+ if(f.has(e))return void o(e,"already-nudged")
12
+ f.add(e),o(e,`nudging (${t})`)
13
+ const{executeAction:l}=await Promise.resolve().then(()=>n(5607)),c=s.planWritten?exports.vB:'[handoff nudge] This autonomous planning session went idle WITHOUT writing its plan. If you were waiting on a research subagent, its findings should have reached you by now -- proceed with what you have rather than waiting further. Fill in the plan document with plan_write, decompose it into requests, then call session_message_operations { operation: "offer-handoff", offerHandoff: { summary: "<one-line plan summary>", requestIds: ["req...", ...] } } and STOP. If you genuinely cannot plan this, say why in the plan document and offer handoff anyway. This reminder fires only once.',d=await l("inject-prompt",{sessionId:e,message:c},s.context)
14
+ d.success?s.context.logger.info("planner-handoff watch: nudge injected",{sessionId:e,trigger:t}):s.context.logger.warn("planner-handoff watch: nudge inject failed",{sessionId:e,trigger:t,error:d.error||d.message})}catch(n){s.context.logger.warn("planner-handoff watch: check failed",{sessionId:e,trigger:t,error:(0,r.getErrorMessage)(n)})}finally{s.checking=!1}}}function o(e,n){const t=i.get(e)
15
+ t&&(clearTimeout(t.expiry),t.poll&&clearInterval(t.poll),i.delete(e),t.context.logger.info("planner-handoff watch: stopped",{sessionId:e,reason:n}))}exports.vB=void 0,exports.trackAutonomousPlanner=function(e,n){if(!n||i.has(n)||f.has(n))return
16
+ const a=setTimeout(()=>{o(n,"ttl-expired")},216e5)
17
17
  a.unref?.()
18
18
  const r={context:e,planWritten:!1,checking:!1,expiry:a}
19
- r.poll=setInterval((()=>{t(n,"poll")}),s),r.poll.unref?.(),l.set(n,r),e.logger.info("planner-handoff watch: watching autonomous planner (nudge armed at spawn)",{sessionId:n})},exports.notifyPlannerHandoffToolEvent=function(e,n,t){const a=l.get(e)
19
+ r.poll=setInterval(()=>{t(n,"poll")},3e4),r.poll.unref?.(),i.set(n,r),e.logger.info("planner-handoff watch: watching autonomous planner (nudge armed at spawn)",{sessionId:n})},exports.notifyPlannerHandoffToolEvent=function(e,n,t){const a=i.get(e)
20
20
  if(!a)return
21
21
  const r=t&&"object"==typeof t?t.operation:void 0
22
- n.includes("session_message_operations")&&"offer-handoff"===r?o(e,"offer-handoff observed"):!a.planWritten&&n.includes("plan_write")&&"string"==typeof r&&f.has(r)&&(a.planWritten=!0,a.context.logger.info("planner-handoff watch: plan written",{sessionId:e}))},exports.notifyPlannerHandoffSessionIdle=function(e){return l.has(e)?t(e,"idle-event"):Promise.resolve()},exports.hasParkVetoingPlannerHandoffWatches=function(){for(const e of l.values())if(e.planWritten)return!0
22
+ n.includes("session_message_operations")&&"offer-handoff"===r?o(e,"offer-handoff observed"):!a.planWritten&&n.includes("plan_write")&&"string"==typeof r&&s.has(r)&&(a.planWritten=!0,a.context.logger.info("planner-handoff watch: plan written",{sessionId:e}))},exports.notifyPlannerHandoffSessionIdle=function(e){return i.has(e)?t(e,"idle-event"):Promise.resolve()},exports.hasParkVetoingPlannerHandoffWatches=function(){for(const e of i.values())if(e.planWritten)return!0
23
23
  return!1}
24
- const a=n(60833),r=n(58824),s=3e4,i=216e5,f=new Set(["create","update","append","replace"])
24
+ const a=n(60833),r=n(58824),s=new Set(["create","update","append","replace"])
25
25
  exports.vB='[handoff nudge] This autonomous planning session went idle after writing the plan without offering handoff -- the flow is waiting on that call. If the plan and its requests are complete, call session_message_operations { operation: "offer-handoff", offerHandoff: { summary: "<one-line plan summary>", requestIds: ["req...", ...] } } now, then STOP. If requests are not created yet, finish decomposing first, then offer. This reminder fires only once.'
26
- const l=new Map,c='[handoff nudge] This autonomous planning session went idle WITHOUT writing its plan. If you were waiting on a research subagent, its findings should have reached you by now -- proceed with what you have rather than waiting further. Fill in the plan document with plan_write, decompose it into requests, then call session_message_operations { operation: "offer-handoff", offerHandoff: { summary: "<one-line plan summary>", requestIds: ["req...", ...] } } and STOP. If you genuinely cannot plan this, say why in the plan document and offer handoff anyway. This reminder fires only once.',d=new Set}}
26
+ const i=new Map,f=new Set}}
package/dist/994.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict"
2
- exports.id=994,exports.ids=[994],exports.modules={75994:function(t,exports,e){var r=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}}
2
+ exports.ids=[994],exports.modules={75994(t,exports,e){var r=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}}
3
3
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.InteractiveShell=void 0
4
4
  const s=r(e(23785)),a=e(35317),i=e(83807),o=r(e(16928)),n=r(e(79896)),l=r(e(96895)),c=e(14139),u=e(44192),h=e(41152),d=e(76634),f=e(79414)
5
5
  exports.InteractiveShell=class{constructor(t){if(this.currentBranch="main",this.currentStatus=null,this.history=[],this.statusCache={map:new Map,ts:0},this.pathExecutableCache=null,this.projectPath=t.projectPath,this.currentSymlink=o.default.join(t.projectPath,c.ALCHEMY_DIR_NAME,"current"),this.currentDir=t.projectPath,this.logger=t.logger,this.historyFile=o.default.join(t.projectPath,c.ALCHEMY_DIR_NAME,"shell-history.txt"),this.projectId=t.projectId,this.remoteServerUrl=t.remoteServerUrl,this.authToken=t.authToken,t.remoteServerUrl){const e=(0,h.createMetricsCollector)(!1)
@@ -13,11 +13,11 @@ return e?.data??e??null},fetchReceiptMarkdown:async t=>{const e=await fetch(`${t
13
13
  if(!e.ok)throw new Error(`Receipt fetch failed: HTTP ${e.status}`)
14
14
  return await e.text()}})
15
15
  console.log(l.default.green(`${a.created?"PR created":"Receipt added to the existing PR"}: ${a.prUrl}`)),a.statusPosted&&console.log(l.default.gray("Commit status alchemylab/gates set on the head commit."))}catch(t){console.log(l.default.red(t instanceof Error?t.message:String(t)))}}async linearImport(t){if(t&&/^[A-Za-z][A-Za-z0-9]{1,9}-\d{1,6}$/.test(t))try{const e=(0,f.getActionServerBaseUrl)(),r=await fetch(`${e}/api/connections/linear/import`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({issueKey:t.toUpperCase()})}),s=await r.json()
16
- s.success&&s.data?.requestId?console.log(l.default.green(`Imported ${s.data.issue} as ${s.data.requestId}.`)):console.log(l.default.red(s.error||"Import failed."))}catch(t){console.log(l.default.red(t instanceof Error?t.message:String(t)))}else console.log(l.default.red("Usage: linear <issue key> e.g. linear ENG-123"))}async start(t){return this.shutdownCallback=t,this.currentBranch="main",this.updateCurrentSymlink(),this.loadHistory(),this.rl=s.default.createInterface({input:process.stdin,output:process.stdout,prompt:this.buildPrompt(),historySize:500,removeHistoryDuplicates:!0,completer:t=>this.completer(t)}),this.history.length>0&&(this.rl.history=[...this.history].reverse()),this.printHelp(!0),this.rl.prompt(),new Promise((t=>{this.rl.on("line",(async e=>{const r=e.trim()
16
+ s.success&&s.data?.requestId?console.log(l.default.green(`Imported ${s.data.issue} as ${s.data.requestId}.`)):console.log(l.default.red(s.error||"Import failed."))}catch(t){console.log(l.default.red(t instanceof Error?t.message:String(t)))}else console.log(l.default.red("Usage: linear <issue key> e.g. linear ENG-123"))}async start(t){return this.shutdownCallback=t,this.currentBranch="main",this.updateCurrentSymlink(),this.loadHistory(),this.rl=s.default.createInterface({input:process.stdin,output:process.stdout,prompt:this.buildPrompt(),historySize:500,removeHistoryDuplicates:!0,completer:t=>this.completer(t)}),this.history.length>0&&(this.rl.history=[...this.history].reverse()),this.printHelp(!0),this.rl.prompt(),new Promise(t=>{this.rl.on("line",async e=>{const r=e.trim()
17
17
  if(r){if(this.appendHistory(r),await this.processCommand(r))return this.rl.close(),void t()
18
- this.rl.prompt()}else this.rl.prompt()}))
18
+ this.rl.prompt()}else this.rl.prompt()})
19
19
  let e,r=!1
20
- this.rl.on("SIGINT",(()=>{r?(e&&clearTimeout(e),this.rl.close()):(r=!0,console.log(""),console.log(l.default.gray("Press Ctrl+C again to exit, or continue typing.")),this.rl.prompt(),e=setTimeout((()=>{r=!1}),2e3))})),this.rl.on("close",(async()=>{this.shutdownCallback&&await this.shutdownCallback(),t()}))}))}buildPrompt(){const t=l.default.green(this.currentBranch),e=this.currentStatus&&"main"!==this.currentBranch?` ${l.default.gray("|")} ${this.colorStatus(this.currentStatus)}`:""
20
+ this.rl.on("SIGINT",()=>{r?(e&&clearTimeout(e),this.rl.close()):(r=!0,console.log(""),console.log(l.default.gray("Press Ctrl+C again to exit, or continue typing.")),this.rl.prompt(),e=setTimeout(()=>{r=!1},2e3))}),this.rl.on("close",async()=>{this.shutdownCallback&&await this.shutdownCallback(),t()})})}buildPrompt(){const t=l.default.green(this.currentBranch),e=this.currentStatus&&"main"!==this.currentBranch?` ${l.default.gray("|")} ${this.colorStatus(this.currentStatus)}`:""
21
21
  return`${l.default.cyan("[")}${t}${e}${l.default.cyan("]")} ${l.default.yellow("alchemy")}${l.default.gray(">")} `}colorStatus(t){switch(t){case"completed":return l.default.green(t)
22
22
  case"in_progress":return l.default.yellow(t)
23
23
  case"open":return l.default.blue(t)
@@ -33,14 +33,14 @@ return this.statusCache={map:r,ts:Date.now()},r}catch{return this.statusCache.ma
33
33
  const t=new Set,e=(process.env.PATH||"").split(o.default.delimiter)
34
34
  for(const r of e)try{if(!n.default.existsSync(r))continue
35
35
  for(const e of n.default.readdirSync(r))t.add(e)}catch{}return this.pathExecutableCache=Array.from(t).sort(),this.pathExecutableCache}completer(t){const e=["br","branch","logs","pwd","cd ","publish ","linear ","help","exit","quit"],r=t.includes(" "),s=t.indexOf(" "),a=r?t.slice(0,s).toLowerCase():""
36
- if(r&&("br"===a||"branch"===a))return setImmediate((()=>this.rl.write("\n"))),[[],""]
37
- if(!r){const r=e.filter((e=>e.startsWith(t))),s=t?this.getPathExecutables().filter((e=>e.startsWith(t))):[],a=[...new Set([...r,...s])]
36
+ if(r&&("br"===a||"branch"===a))return setImmediate(()=>this.rl.write("\n")),[[],""]
37
+ if(!r){const r=e.filter(e=>e.startsWith(t)),s=t?this.getPathExecutables().filter(e=>e.startsWith(t)):[],a=[...new Set([...r,...s])]
38
38
  if(a.length>0)return[a,t]
39
39
  if(!t)return[e,t]}const i=t.lastIndexOf(" "),l=i>=0?t.slice(i+1):t,c=i>=0?t.slice(0,i+1):""
40
40
  try{const e=l.includes(o.default.sep)||l.includes("/"),r=e?o.default.resolve(this.currentDir,o.default.dirname(l)):this.currentDir,s=e?o.default.basename(l):l,a=e?o.default.dirname(l)+"/":""
41
41
  if(!n.default.existsSync(r))return[[],t]
42
- const i=n.default.readdirSync(r,{withFileTypes:!0}).filter((t=>t.name.startsWith(s)&&!t.name.startsWith("."))).map((t=>{const e=t.isDirectory()?t.name+"/":t.name
43
- return c+a+e}))
42
+ const i=n.default.readdirSync(r,{withFileTypes:!0}).filter(t=>t.name.startsWith(s)&&!t.name.startsWith(".")).map(t=>{const e=t.isDirectory()?t.name+"/":t.name
43
+ return c+a+e})
44
44
  if(i.length>0)return[i,t]}catch{}return[[],t]}async detectCurrentBranch(){try{const t=(0,i.simpleGit)(this.currentDir),e=(await t.branch()).current||"main"
45
45
  this.currentBranch=this.extractRequestId(e)||e}catch{this.currentBranch="main"}}async processCommand(t){const e=t.split(/\s+/),r=e[0].toLowerCase(),s=e.slice(1)
46
46
  switch(r){case"exit":case"quit":return this.shutdownCallback&&await this.shutdownCallback(),!0
@@ -57,12 +57,12 @@ this.currentDir=e}catch(t){console.log(l.default.red(`cd: ${t.message}`))}}async
57
57
  if(!n.default.existsSync(r))return void console.log(l.default.gray("No log file found yet. Logs will appear once the server processes requests."))
58
58
  const s=t[0]&&/^\d+$/.test(t[0])?parseInt(t[0],10):50
59
59
  console.log(l.default.gray(`Tailing ${r} (last ${s} lines, Ctrl+C to stop)`))
60
- const{spawn:a}=await Promise.resolve().then(e.t.bind(e,35317,23)),i=a("tail",["-n",String(s),"-f",r],{stdio:["ignore","inherit","inherit"]})
61
- return new Promise((t=>{const e=process.stdin,r=e.isRaw
60
+ const{spawn:a}=await Promise.resolve().then(()=>e.t(35317,23)),i=a("tail",["-n",String(s),"-f",r],{stdio:["ignore","inherit","inherit"]})
61
+ return new Promise(t=>{const e=process.stdin,r=e.isRaw
62
62
  this.rl.pause(),e.setRawMode(!0),e.resume()
63
63
  const s=()=>{e.removeListener("data",a)
64
64
  try{i.kill("SIGTERM")}catch{}try{e.setRawMode(r??!1)}catch{}this.rl.resume()},a=t=>{3!==t[0]&&"q"!==t.toString()||i.kill("SIGTERM")}
65
- e.on("data",a),i.on("close",(()=>{s(),t()}))}))}updateCurrentSymlink(){try{let t
65
+ e.on("data",a),i.on("close",()=>{s(),t()})})}updateCurrentSymlink(){try{let t
66
66
  if("main"===this.currentBranch)t=this.projectPath
67
67
  else{const e=o.default.join(this.projectPath,c.ALCHEMY_DIR_NAME,"worktrees",this.currentBranch)
68
68
  t=n.default.existsSync(e)?e:this.projectPath}try{n.default.unlinkSync(this.currentSymlink)}catch{}n.default.symlinkSync(t,this.currentSymlink),this.currentDir=this.currentSymlink}catch(t){this.logger.warn("Failed to update current symlink",{error:t.message})}}getVirtualCwd(){return this.currentDir}executeCommand(t){try{(0,a.execSync)(t,{cwd:this.currentDir,stdio:"inherit",env:{...process.env,PWD:this.currentDir,GIT_DIR:void 0,GIT_WORK_TREE:void 0}})}catch(t){void 0!==t.status&&null!==t.status||console.log(l.default.red(`Error: ${t.message}`))}}getWorktreeRequestIds(){const t=o.default.join(this.projectPath,c.ALCHEMY_DIR_NAME,"worktrees"),e=new Set
@@ -73,7 +73,7 @@ for(const t of r.all){if(t.startsWith("remotes/"))continue
73
73
  if("main"===t)continue
74
74
  const e=this.extractRequestId(t)
75
75
  e&&!o.has(e)&&(o.add(e),n.push(e))}for(const t of s)o.has(t)||(o.add(t),n.push(t))
76
- n.sort(((t,e)=>t.localeCompare(e)))
76
+ n.sort((t,e)=>t.localeCompare(e))
77
77
  for(const t of n){const e=this.currentBranch===t||this.currentBranch===`requests/${t}`
78
78
  c.push(this.formatRequestWithStatus(t,a.get(t),e))}if(n.push("main"),c.push("main"===this.currentBranch?l.default.green("main"):"main"),0===n.length)return void console.log(l.default.gray("No branches found."))
79
79
  if(t&&n.includes(t))return void(t!==this.currentBranch&&await this.switchBranch(t))
@@ -85,14 +85,14 @@ if(n.default.existsSync(s)&&n.default.statSync(s).isDirectory())return s
85
85
  console.log(l.default.gray(`Creating worktree for ${t}...`)),n.default.mkdirSync(r,{recursive:!0})
86
86
  const a=(0,i.simpleGit)(this.projectPath)
87
87
  return await a.raw(["worktree","add",s,e]),console.log(l.default.gray(`Worktree created at ${s}`)),s}async selectFromList(t,e,r,s,a,i){const o=t,n=r||t
88
- return new Promise((t=>{let r=0
88
+ return new Promise(t=>{let r=0
89
89
  const c=process.stdin,u=c.isRaw
90
- let h=!1,d=i||"",f=o.map(((t,e)=>e))
90
+ let h=!1,d=i||"",f=o.map((t,e)=>e)
91
91
  null!=s&&s>=0&&s<o.length&&(r=s)
92
- const p=()=>{if(!d)return void(f=o.map(((t,e)=>e)))
92
+ const p=()=>{if(!d)return void(f=o.map((t,e)=>e))
93
93
  const t=d.toLowerCase()
94
- let e=o.map(((t,e)=>({item:t,i:e}))).filter((({item:e})=>e.toLowerCase().startsWith(t)))
95
- 0===e.length&&/^\d+$/.test(t)&&(e=o.map(((t,e)=>({item:t,i:e}))).filter((({item:e})=>e.replace(/\D/g,"").endsWith(t)))),0===e.length&&(e=o.map(((t,e)=>({item:t,i:e}))).filter((({item:e})=>e.toLowerCase().includes(t)))),f=e.map((t=>t.i))},g=process.stdout.rows||24,y=Math.max(3,g-4)
94
+ let e=o.map((t,e)=>({item:t,i:e})).filter(({item:e})=>e.toLowerCase().startsWith(t))
95
+ 0===e.length&&/^\d+$/.test(t)&&(e=o.map((t,e)=>({item:t,i:e})).filter(({item:e})=>e.replace(/\D/g,"").endsWith(t))),0===e.length&&(e=o.map((t,e)=>({item:t,i:e})).filter(({item:e})=>e.toLowerCase().includes(t))),f=e.map(t=>t.i)},g=process.stdout.rows||24,y=Math.max(3,g-4)
96
96
  let m=0,w=0,$=0
97
97
  this.rl.pause()
98
98
  const S=()=>{const t=f.length,s=t>y
@@ -116,23 +116,23 @@ S(),c.setRawMode(!0),c.resume()
116
116
  const b=()=>{if(!h){h=!0,c.removeListener("data",v)
117
117
  try{c.setRawMode(u??!1)}catch{}C&&$>1&&process.stdout.write(`\r\x1b[${$-1}A\r`),process.stdout.write("\x1b[J"),this.rl.resume()}},v=e=>{if(!h)try{const s=e.toString()
118
118
  "\x1b[A"===s?f.length>0&&(r=Math.max(0,r-1),S()):"\x1b[B"===s?f.length>0&&(r=Math.min(f.length-1,r+1),S()):"\r"===s||"\n"===s?f.length>0&&(b(),t(o[f[r]])):"\x1b"===s||"\x03"===s?(b(),t(null)):a&&"\x7f"===s?d.length>0&&(d=d.slice(0,-1),p(),r=0,m=0,S()):a&&1===s.length&&s>=" "&&s<="~"&&(d+=s,p(),r=0,m=0,S())}catch{b(),t(null)}}
119
- c.on("data",v)}))}findMatchingBranches(t,e,r){const s=new Set
119
+ c.on("data",v)})}findMatchingBranches(t,e,r){const s=new Set
120
120
  for(const t of e){const e=this.extractRequestId(t)
121
121
  e&&s.add(e)}for(const t of r)s.add(t)
122
122
  const a=Array.from(s)
123
123
  if(s.has(t))return[t]
124
- const i=a.filter((e=>e.startsWith(t)))
124
+ const i=a.filter(e=>e.startsWith(t))
125
125
  if(i.length>0)return i.sort()
126
- if(/^\d+$/.test(t)){const e=a.filter((e=>e.replace(/\D/g,"").endsWith(t)))
126
+ if(/^\d+$/.test(t)){const e=a.filter(e=>e.replace(/\D/g,"").endsWith(t))
127
127
  if(e.length>0)return e.sort()}return[]}async switchBranch(t){try{if("main"===t)return this.currentBranch="main",this.currentStatus=null,this.updateCurrentSymlink(),this.updatePrompt(),console.log(l.default.green("Switched to main")),void console.log(l.default.gray(` ${this.currentDir}`))
128
128
  const e=(0,i.simpleGit)(this.projectPath),r=await e.branch(),s=this.getWorktreeRequestIds(),a=this.findMatchingBranches(t,r.all,s)
129
129
  if(0===a.length)return console.log(l.default.red(`No branch matching: ${t}`)),void console.log(l.default.gray(' Use "branches" to see available branches'))
130
130
  let o
131
131
  if(1===a.length)o=a[0]
132
- else{const e=await this.fetchBulkStatuses(),r=a.map((t=>this.formatRequestWithStatus(t,e.get(t),!1))),s=await this.selectFromList(a,`Multiple matches for "${t}" \u2014 select one:`,r,void 0,!0)
132
+ else{const e=await this.fetchBulkStatuses(),r=a.map(t=>this.formatRequestWithStatus(t,e.get(t),!1)),s=await this.selectFromList(a,`Multiple matches for "${t}" \u2014 select one:`,r,void 0,!0)
133
133
  if(!s)return void console.log(l.default.gray("Cancelled."))
134
134
  o=s}const n=r.all.includes(`requests/${o}`)?`requests/${o}`:o
135
135
  await this.ensureWorktree(o,n),this.currentBranch=o,this.updateCurrentSymlink(),this.currentStatus=await this.fetchRequestStatus(o),this.updatePrompt()
136
136
  const c=this.currentStatus?` ${l.default.gray("|")} ${this.colorStatus(this.currentStatus)}`:""
137
137
  console.log(l.default.green(`Switched to ${o}`)+c),console.log(l.default.gray(` ${this.getVirtualCwd()}`))}catch(t){console.log(l.default.red(`Failed to switch: ${t.message}`))}}printHelp(t){t?(console.log(""),console.log(l.default.gray('Type "help" for available commands. Commands run in the current branch directory.')),console.log("")):(console.log(""),console.log(l.default.bold("Interactive Shell Commands:")),console.log(` ${l.default.yellow("branch")} / ${l.default.yellow("br")} Browse and switch branches`),console.log(` ${l.default.yellow("logs")} ${l.default.gray("[N]")} Tail action server log (Ctrl+C to stop, N = lines of history)`),console.log(` ${l.default.yellow("cd")} ${l.default.gray("<dir>")} Change directory within current branch`),console.log(` ${l.default.yellow("pwd")} Show current working directory`),console.log(` ${l.default.yellow("publish")} ${l.default.gray("<req id>")} Push the request branch and open a GitHub PR with its receipt`),console.log(` ${l.default.yellow("linear")} ${l.default.gray("<ENG-123>")} Import a Linear issue as a request`),console.log(` ${l.default.yellow("help")} Show this help`),console.log(` ${l.default.yellow("exit")} / ${l.default.yellow("quit")} Stop the server and exit`),console.log(""),console.log(l.default.gray(" Any other input is executed as a shell command in the current directory.")),console.log(""))}loadHistory(){try{if(n.default.existsSync(this.historyFile)){const t=n.default.readFileSync(this.historyFile,"utf-8")
138
- this.history=t.split("\n").filter((t=>""!==t.trim())),this.history.length>500&&(this.history=this.history.slice(-500))}}catch{}}appendHistory(t){try{this.history.push(t),n.default.appendFileSync(this.historyFile,t+"\n")}catch{}}}}}
138
+ this.history=t.split("\n").filter(t=>""!==t.trim()),this.history.length>500&&(this.history=this.history.slice(-500))}}catch{}}appendHistory(t){try{this.history.push(t),n.default.appendFileSync(this.historyFile,t+"\n")}catch{}}}}}