fix: reconcile Codex marketplace source conflicts
This commit is contained in:
@@ -10,7 +10,7 @@
|
|||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
"name": "claude-mem",
|
"name": "claude-mem",
|
||||||
"version": "12.7.4",
|
"version": "12.7.5",
|
||||||
"source": "./plugin",
|
"source": "./plugin",
|
||||||
"description": "Persistent memory system for Claude Code - context compression across sessions"
|
"description": "Persistent memory system for Claude Code - context compression across sessions"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "claude-mem",
|
"name": "claude-mem",
|
||||||
"version": "12.7.4",
|
"version": "12.7.5",
|
||||||
"description": "Memory compression system for Claude Code - persist context across sessions",
|
"description": "Memory compression system for Claude Code - persist context across sessions",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Alex Newman"
|
"name": "Alex Newman"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "claude-mem",
|
"name": "claude-mem",
|
||||||
"version": "12.7.4",
|
"version": "12.7.5",
|
||||||
"description": "Memory compression system for Claude Code - persist context across sessions",
|
"description": "Memory compression system for Claude Code - persist context across sessions",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Alex Newman",
|
"name": "Alex Newman",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"name": "Claude-Mem (Persistent Memory)",
|
"name": "Claude-Mem (Persistent Memory)",
|
||||||
"description": "Official OpenClaw plugin for Claude-Mem. Records observations from embedded runner sessions and streams them to messaging channels.",
|
"description": "Official OpenClaw plugin for Claude-Mem. Records observations from embedded runner sessions and streams them to messaging channels.",
|
||||||
"kind": "memory",
|
"kind": "memory",
|
||||||
"version": "12.7.4",
|
"version": "12.7.5",
|
||||||
"author": "thedotmack",
|
"author": "thedotmack",
|
||||||
"homepage": "https://claude-mem.com",
|
"homepage": "https://claude-mem.com",
|
||||||
"skills": ["skills/make-plan", "skills/do"],
|
"skills": ["skills/make-plan", "skills/do"],
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "claude-mem",
|
"name": "claude-mem",
|
||||||
"version": "12.7.4",
|
"version": "12.7.5",
|
||||||
"description": "Memory compression system for Claude Code - persist context across sessions",
|
"description": "Memory compression system for Claude Code - persist context across sessions",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"claude",
|
"claude",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "claude-mem",
|
"name": "claude-mem",
|
||||||
"version": "12.7.4",
|
"version": "12.7.5",
|
||||||
"description": "Memory compression system for Claude Code - persist context across sessions",
|
"description": "Memory compression system for Claude Code - persist context across sessions",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Alex Newman"
|
"name": "Alex Newman"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "claude-mem",
|
"name": "claude-mem",
|
||||||
"version": "12.7.4",
|
"version": "12.7.5",
|
||||||
"description": "Memory compression system for Claude Code - persist context across sessions",
|
"description": "Memory compression system for Claude Code - persist context across sessions",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Alex Newman",
|
"name": "Alex Newman",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "claude-mem-plugin",
|
"name": "claude-mem-plugin",
|
||||||
"version": "12.7.4",
|
"version": "12.7.5",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Runtime dependencies for claude-mem bundled hooks",
|
"description": "Runtime dependencies for claude-mem bundled hooks",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ ${f}`}let a=s.lineStart;for(let u=s.lineStart-1;u>=0;u--){let l=i[u].trim();if(l
|
|||||||
${c}`}var s_=new Set([".js",".jsx",".ts",".tsx",".mjs",".cjs",".py",".pyw",".go",".rs",".rb",".java",".cs",".cpp",".cc",".cxx",".c",".h",".hpp",".hh",".swift",".kt",".kts",".php",".vue",".svelte",".ex",".exs",".lua",".scala",".sc",".sh",".bash",".zsh",".hs",".zig",".css",".scss",".toml",".yml",".yaml",".sql",".md",".mdx"]),Dx=new Set(["node_modules",".git","dist","build",".next","__pycache__",".venv","venv","env",".env","target","vendor",".cache",".turbo","coverage",".nyc_output",".claude",".smart-file-read"]),jx=512*1024;async function*i_(t,e,r=20,n){if(r<=0)return;let o;try{o=await(0,Ar.readdir)(t,{withFileTypes:!0})}catch(s){S.debug("WORKER",`walkDir: failed to read directory ${t}`,void 0,s instanceof Error?s:void 0);return}for(let s of o){if(s.name.startsWith(".")&&s.name!=="."||Dx.has(s.name))continue;let i=(0,Vn.join)(t,s.name);if(s.isDirectory())yield*i_(i,e,r-1,n);else if(s.isFile()){let a=s.name.slice(s.name.lastIndexOf("."));(s_.has(a)||n&&n.has(a))&&(yield i)}}}async function Lx(t){try{let e=await(0,Ar.stat)(t);if(e.size>jx||e.size===0)return null;let r=await(0,Ar.readFile)(t,"utf-8");return r.slice(0,1e3).includes("\0")?null:r}catch(e){return S.debug("WORKER",`safeReadFile: failed to read ${t}`,void 0,e instanceof Error?e:void 0),null}}async function a_(t,e,r={}){let n=r.maxResults||20,o=e.toLowerCase(),s=o.split(/[\s_\-./]+/).filter(w=>w.length>0),i=r.projectRoot||t,a=Wn(i),c=new Set;for(let w of Object.values(a.grammars))for(let v of w.extensions)s_.has(v)||c.add(v);let u=[];for await(let w of i_(t,t,20,c.size>0?c:void 0)){if(r.filePattern&&!(0,Vn.relative)(t,w).toLowerCase().includes(r.filePattern.toLowerCase()))continue;let v=await Lx(w);v&&u.push({absolutePath:w,relativePath:(0,Vn.relative)(t,w),content:v})}let l=r_(u,i),d=[],p=[],f=0;for(let[w,v]of l){f+=Zx(v);let k=Ps(w.toLowerCase(),s)>0,_e=[],Ee=(Lt,er)=>{for(let ae of Lt){let bt=0,Ve="",Cr=Ps(ae.name.toLowerCase(),s);Cr>0&&(bt+=Cr*3,Ve="name match"),ae.signature.toLowerCase().includes(o)&&(bt+=2,Ve=Ve?`${Ve} + signature`:"signature match"),ae.jsdoc&&ae.jsdoc.toLowerCase().includes(o)&&(bt+=1,Ve=Ve?`${Ve} + jsdoc`:"jsdoc match"),bt>0&&(k=!0,_e.push({filePath:w,symbolName:er?`${er}.${ae.name}`:ae.name,kind:ae.kind,signature:ae.signature,jsdoc:ae.jsdoc,lineStart:ae.lineStart,lineEnd:ae.lineEnd,matchReason:Ve})),ae.children&&Ee(ae.children,ae.name)}};Ee(v.symbols),k&&(d.push(v),p.push(..._e))}p.sort((w,v)=>{let x=Ps(w.symbolName.toLowerCase(),s);return Ps(v.symbolName.toLowerCase(),s)-x});let m=p.slice(0,n),_=new Set(m.map(w=>w.filePath)),y=d.filter(w=>_.has(w.filePath)).slice(0,n),b=y.reduce((w,v)=>w+v.foldedTokenEstimate,0);return{foldedFiles:y,matchingSymbols:m,totalFilesScanned:u.length,totalSymbolsFound:f,tokenEstimate:b}}function Ps(t,e){let r=0;for(let n of e)if(t===n)r+=10;else if(t.includes(n))r+=5;else{let o=0,s=0;for(let i of n){let a=t.indexOf(i,o);a!==-1&&(s++,o=a+1)}s===n.length&&(r+=1)}return r}function Zx(t){let e=t.symbols.length;for(let r of t.symbols)r.children&&(e+=r.children.length);return e}function c_(t,e){let r=[];if(r.push(`\u{1F50D} Smart Search: "${e}"`),r.push(` Scanned ${t.totalFilesScanned} files, found ${t.totalSymbolsFound} symbols`),r.push(` ${t.matchingSymbols.length} matches across ${t.foldedFiles.length} files (~${t.tokenEstimate} tokens for folded view)`),r.push(""),t.matchingSymbols.length===0)return r.push(" No matching symbols found."),r.join(`
|
${c}`}var s_=new Set([".js",".jsx",".ts",".tsx",".mjs",".cjs",".py",".pyw",".go",".rs",".rb",".java",".cs",".cpp",".cc",".cxx",".c",".h",".hpp",".hh",".swift",".kt",".kts",".php",".vue",".svelte",".ex",".exs",".lua",".scala",".sc",".sh",".bash",".zsh",".hs",".zig",".css",".scss",".toml",".yml",".yaml",".sql",".md",".mdx"]),Dx=new Set(["node_modules",".git","dist","build",".next","__pycache__",".venv","venv","env",".env","target","vendor",".cache",".turbo","coverage",".nyc_output",".claude",".smart-file-read"]),jx=512*1024;async function*i_(t,e,r=20,n){if(r<=0)return;let o;try{o=await(0,Ar.readdir)(t,{withFileTypes:!0})}catch(s){S.debug("WORKER",`walkDir: failed to read directory ${t}`,void 0,s instanceof Error?s:void 0);return}for(let s of o){if(s.name.startsWith(".")&&s.name!=="."||Dx.has(s.name))continue;let i=(0,Vn.join)(t,s.name);if(s.isDirectory())yield*i_(i,e,r-1,n);else if(s.isFile()){let a=s.name.slice(s.name.lastIndexOf("."));(s_.has(a)||n&&n.has(a))&&(yield i)}}}async function Lx(t){try{let e=await(0,Ar.stat)(t);if(e.size>jx||e.size===0)return null;let r=await(0,Ar.readFile)(t,"utf-8");return r.slice(0,1e3).includes("\0")?null:r}catch(e){return S.debug("WORKER",`safeReadFile: failed to read ${t}`,void 0,e instanceof Error?e:void 0),null}}async function a_(t,e,r={}){let n=r.maxResults||20,o=e.toLowerCase(),s=o.split(/[\s_\-./]+/).filter(w=>w.length>0),i=r.projectRoot||t,a=Wn(i),c=new Set;for(let w of Object.values(a.grammars))for(let v of w.extensions)s_.has(v)||c.add(v);let u=[];for await(let w of i_(t,t,20,c.size>0?c:void 0)){if(r.filePattern&&!(0,Vn.relative)(t,w).toLowerCase().includes(r.filePattern.toLowerCase()))continue;let v=await Lx(w);v&&u.push({absolutePath:w,relativePath:(0,Vn.relative)(t,w),content:v})}let l=r_(u,i),d=[],p=[],f=0;for(let[w,v]of l){f+=Zx(v);let k=Ps(w.toLowerCase(),s)>0,_e=[],Ee=(Lt,er)=>{for(let ae of Lt){let bt=0,Ve="",Cr=Ps(ae.name.toLowerCase(),s);Cr>0&&(bt+=Cr*3,Ve="name match"),ae.signature.toLowerCase().includes(o)&&(bt+=2,Ve=Ve?`${Ve} + signature`:"signature match"),ae.jsdoc&&ae.jsdoc.toLowerCase().includes(o)&&(bt+=1,Ve=Ve?`${Ve} + jsdoc`:"jsdoc match"),bt>0&&(k=!0,_e.push({filePath:w,symbolName:er?`${er}.${ae.name}`:ae.name,kind:ae.kind,signature:ae.signature,jsdoc:ae.jsdoc,lineStart:ae.lineStart,lineEnd:ae.lineEnd,matchReason:Ve})),ae.children&&Ee(ae.children,ae.name)}};Ee(v.symbols),k&&(d.push(v),p.push(..._e))}p.sort((w,v)=>{let x=Ps(w.symbolName.toLowerCase(),s);return Ps(v.symbolName.toLowerCase(),s)-x});let m=p.slice(0,n),_=new Set(m.map(w=>w.filePath)),y=d.filter(w=>_.has(w.filePath)).slice(0,n),b=y.reduce((w,v)=>w+v.foldedTokenEstimate,0);return{foldedFiles:y,matchingSymbols:m,totalFilesScanned:u.length,totalSymbolsFound:f,tokenEstimate:b}}function Ps(t,e){let r=0;for(let n of e)if(t===n)r+=10;else if(t.includes(n))r+=5;else{let o=0,s=0;for(let i of n){let a=t.indexOf(i,o);a!==-1&&(s++,o=a+1)}s===n.length&&(r+=1)}return r}function Zx(t){let e=t.symbols.length;for(let r of t.symbols)r.children&&(e+=r.children.length);return e}function c_(t,e){let r=[];if(r.push(`\u{1F50D} Smart Search: "${e}"`),r.push(` Scanned ${t.totalFilesScanned} files, found ${t.totalSymbolsFound} symbols`),r.push(` ${t.matchingSymbols.length} matches across ${t.foldedFiles.length} files (~${t.tokenEstimate} tokens for folded view)`),r.push(""),t.matchingSymbols.length===0)return r.push(" No matching symbols found."),r.join(`
|
||||||
`);r.push("\u2500\u2500 Matching Symbols \u2500\u2500"),r.push("");for(let n of t.matchingSymbols){if(r.push(` ${n.kind} ${n.symbolName} (${n.filePath}:${n.lineStart+1})`),r.push(` ${n.signature}`),n.jsdoc){let o=n.jsdoc.split(`
|
`);r.push("\u2500\u2500 Matching Symbols \u2500\u2500"),r.push("");for(let n of t.matchingSymbols){if(r.push(` ${n.kind} ${n.symbolName} (${n.filePath}:${n.lineStart+1})`),r.push(` ${n.signature}`),n.jsdoc){let o=n.jsdoc.split(`
|
||||||
`).find(s=>s.replace(/^[\s*/]+/,"").trim().length>0);o&&r.push(` \u{1F4AC} ${o.replace(/^[\s*/]+/,"").trim()}`)}r.push("")}r.push("\u2500\u2500 Folded File Views \u2500\u2500"),r.push("");for(let n of t.foldedFiles)r.push(Ir(n)),r.push("");return r.push("\u2500\u2500 Actions \u2500\u2500"),r.push(" To see full implementation: use smart_unfold with file path and symbol name"),r.join(`
|
`).find(s=>s.replace(/^[\s*/]+/,"").trim().length>0);o&&r.push(` \u{1F4AC} ${o.replace(/^[\s*/]+/,"").trim()}`)}r.push("")}r.push("\u2500\u2500 Folded File Views \u2500\u2500"),r.push("");for(let n of t.foldedFiles)r.push(Ir(n)),r.push("");return r.push("\u2500\u2500 Actions \u2500\u2500"),r.push(" To see full implementation: use smart_unfold with file path and symbol name"),r.join(`
|
||||||
`)}var iu=require("node:fs/promises"),zs=require("node:fs"),Qe=require("node:path"),d_=require("node:os"),p_=require("node:url"),Xx={},Ux="12.7.4";console.log=(...t)=>{S.error("CONSOLE","Intercepted console output (MCP protocol protection)",void 0,{args:t})};var f_=!1,m_=(()=>{if(typeof __dirname<"u")return __dirname;try{return(0,Qe.dirname)((0,p_.fileURLToPath)(Xx.url))}catch{return f_=!0,process.cwd()}})(),au=(0,Qe.resolve)(m_,"worker-service.cjs");function Fx(){f_&&((0,zs.existsSync)(au)||S.error("SYSTEM","mcp-server: dirname resolution failed (both __dirname and import.meta.url are unavailable). Fell back to process.cwd() and the resolved WORKER_SCRIPT_PATH does not exist. This is the actual problem \u2014 the worker bundle is fine, but mcp-server cannot locate it. Worker auto-start will fail until the dirname-resolution path is fixed.",{workerScriptPath:au,mcpServerDir:m_}))}var u_={search:"/api/search",timeline:"/api/timeline"};async function su(t,e){S.debug("SYSTEM","\u2192 Worker API",void 0,{endpoint:t,params:e});let r=new URLSearchParams;for(let[o,s]of Object.entries(e))s!=null&&r.append(o,String(s));let n=`${t}?${r}`;try{let o=await $s(n);if(!o.ok){let i=await o.text();throw new Error(`Worker API error (${o.status}): ${i}`)}let s=await o.json();return S.debug("SYSTEM","\u2190 Worker API success",void 0,{endpoint:t}),s}catch(o){return S.error("SYSTEM","\u2190 Worker API error",{endpoint:t},o instanceof Error?o:new Error(String(o))),{content:[{type:"text",text:`Error calling Worker API: ${o instanceof Error?o.message:String(o)}`}],isError:!0}}}async function qx(t,e){let r=await $s(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){let o=await r.text();throw new Error(`Worker API error (${r.status}): ${o}`)}let n=await r.json();return S.debug("HTTP","Worker API success (POST)",void 0,{endpoint:t}),{content:[{type:"text",text:JSON.stringify(n,null,2)}]}}async function Mr(t,e){S.debug("HTTP","Worker API request (POST)",void 0,{endpoint:t});try{return await qx(t,e)}catch(r){return S.error("HTTP","Worker API error (POST)",{endpoint:t},r instanceof Error?r:new Error(String(r))),{content:[{type:"text",text:`Error calling Worker API: ${r instanceof Error?r.message:String(r)}`}],isError:!0}}}async function Hx(){try{return(await $s("/api/health")).ok}catch(t){return S.debug("SYSTEM","Worker health check failed",{},t instanceof Error?t:new Error(String(t))),!1}}async function Wx(){if(await Hx())return!0;S.warn("SYSTEM","Worker not available, attempting auto-start for MCP client"),Fx();try{let t=Jc(),e=await Hg(t,au);return e==="dead"&&S.error("SYSTEM","Worker auto-start failed \u2014 MCP tools that require the worker (search, timeline, get_observations) will fail until the worker is running. Check earlier log lines for the specific failure reason (Bun not found, missing worker bundle, port conflict, etc.)."),e!=="dead"}catch(t){return S.error("SYSTEM","Worker auto-start threw \u2014 MCP tools that require the worker (search, timeline, get_observations) will fail until the worker is running.",void 0,t instanceof Error?t:new Error(String(t))),!1}}var h_=[{name:"__IMPORTANT",description:`3-LAYER WORKFLOW (ALWAYS FOLLOW):
|
`)}var iu=require("node:fs/promises"),zs=require("node:fs"),Qe=require("node:path"),d_=require("node:os"),p_=require("node:url"),Xx={},Ux="12.7.5";console.log=(...t)=>{S.error("CONSOLE","Intercepted console output (MCP protocol protection)",void 0,{args:t})};var f_=!1,m_=(()=>{if(typeof __dirname<"u")return __dirname;try{return(0,Qe.dirname)((0,p_.fileURLToPath)(Xx.url))}catch{return f_=!0,process.cwd()}})(),au=(0,Qe.resolve)(m_,"worker-service.cjs");function Fx(){f_&&((0,zs.existsSync)(au)||S.error("SYSTEM","mcp-server: dirname resolution failed (both __dirname and import.meta.url are unavailable). Fell back to process.cwd() and the resolved WORKER_SCRIPT_PATH does not exist. This is the actual problem \u2014 the worker bundle is fine, but mcp-server cannot locate it. Worker auto-start will fail until the dirname-resolution path is fixed.",{workerScriptPath:au,mcpServerDir:m_}))}var u_={search:"/api/search",timeline:"/api/timeline"};async function su(t,e){S.debug("SYSTEM","\u2192 Worker API",void 0,{endpoint:t,params:e});let r=new URLSearchParams;for(let[o,s]of Object.entries(e))s!=null&&r.append(o,String(s));let n=`${t}?${r}`;try{let o=await $s(n);if(!o.ok){let i=await o.text();throw new Error(`Worker API error (${o.status}): ${i}`)}let s=await o.json();return S.debug("SYSTEM","\u2190 Worker API success",void 0,{endpoint:t}),s}catch(o){return S.error("SYSTEM","\u2190 Worker API error",{endpoint:t},o instanceof Error?o:new Error(String(o))),{content:[{type:"text",text:`Error calling Worker API: ${o instanceof Error?o.message:String(o)}`}],isError:!0}}}async function qx(t,e){let r=await $s(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){let o=await r.text();throw new Error(`Worker API error (${r.status}): ${o}`)}let n=await r.json();return S.debug("HTTP","Worker API success (POST)",void 0,{endpoint:t}),{content:[{type:"text",text:JSON.stringify(n,null,2)}]}}async function Mr(t,e){S.debug("HTTP","Worker API request (POST)",void 0,{endpoint:t});try{return await qx(t,e)}catch(r){return S.error("HTTP","Worker API error (POST)",{endpoint:t},r instanceof Error?r:new Error(String(r))),{content:[{type:"text",text:`Error calling Worker API: ${r instanceof Error?r.message:String(r)}`}],isError:!0}}}async function Hx(){try{return(await $s("/api/health")).ok}catch(t){return S.debug("SYSTEM","Worker health check failed",{},t instanceof Error?t:new Error(String(t))),!1}}async function Wx(){if(await Hx())return!0;S.warn("SYSTEM","Worker not available, attempting auto-start for MCP client"),Fx();try{let t=Jc(),e=await Hg(t,au);return e==="dead"&&S.error("SYSTEM","Worker auto-start failed \u2014 MCP tools that require the worker (search, timeline, get_observations) will fail until the worker is running. Check earlier log lines for the specific failure reason (Bun not found, missing worker bundle, port conflict, etc.)."),e!=="dead"}catch(t){return S.error("SYSTEM","Worker auto-start threw \u2014 MCP tools that require the worker (search, timeline, get_observations) will fail until the worker is running.",void 0,t instanceof Error?t:new Error(String(t))),!1}}var h_=[{name:"__IMPORTANT",description:`3-LAYER WORKFLOW (ALWAYS FOLLOW):
|
||||||
1. search(query) \u2192 Get index with IDs (~50-100 tokens/result)
|
1. search(query) \u2192 Get index with IDs (~50-100 tokens/result)
|
||||||
2. timeline(anchor=ID) \u2192 Get context around interesting results
|
2. timeline(anchor=ID) \u2192 Get context around interesting results
|
||||||
3. get_observations([IDs]) \u2192 Fetch full details ONLY for filtered IDs
|
3. get_observations([IDs]) \u2192 Fetch full details ONLY for filtered IDs
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -28,7 +28,7 @@ description: Automated semantic versioning and release workflow for Claude Code
|
|||||||
|
|
||||||
1. **Update**: Increment the version string in every path above. Do NOT touch `CHANGELOG.md` — it's regenerated.
|
1. **Update**: Increment the version string in every path above. Do NOT touch `CHANGELOG.md` — it's regenerated.
|
||||||
2. **Verify**: `git grep -n "\"version\": \"<NEW>\""` — confirm all seven files match. `git grep -n "\"version\": \"<OLD>\""` — should return zero hits.
|
2. **Verify**: `git grep -n "\"version\": \"<NEW>\""` — confirm all seven files match. `git grep -n "\"version\": \"<OLD>\""` — should return zero hits.
|
||||||
3. **Build**: `npm run build` to regenerate artifacts.
|
3. **Build and sync**: `npm run build-and-sync` to regenerate artifacts, sync the local marketplace copy, restart the worker, and clear the queue. Do not use plain `npm run build` for release validation because it can leave the local marketplace/worker out of sync.
|
||||||
4. **Commit**: `git add -A && git commit -m "chore: bump version to X.Y.Z"`.
|
4. **Commit**: `git add -A && git commit -m "chore: bump version to X.Y.Z"`.
|
||||||
5. **Tag**: `git tag -a vX.Y.Z -m "Version X.Y.Z"`.
|
5. **Tag**: `git tag -a vX.Y.Z -m "Version X.Y.Z"`.
|
||||||
6. **Push**: `git push origin main && git push origin vX.Y.Z`.
|
6. **Push**: `git push origin main && git push origin vX.Y.Z`.
|
||||||
@@ -36,7 +36,7 @@ description: Automated semantic versioning and release workflow for Claude Code
|
|||||||
```bash
|
```bash
|
||||||
npm publish
|
npm publish
|
||||||
```
|
```
|
||||||
The `prepublishOnly` script re-runs `npm run build` automatically. Confirm publish succeeded:
|
The `prepublishOnly` script re-runs the package build automatically. After publish, run `npm run build-and-sync` again if the publish build touched local artifacts. Confirm publish succeeded:
|
||||||
```bash
|
```bash
|
||||||
npm view claude-mem@X.Y.Z version # should print X.Y.Z
|
npm view claude-mem@X.Y.Z version # should print X.Y.Z
|
||||||
```
|
```
|
||||||
@@ -59,7 +59,7 @@ description: Automated semantic versioning and release workflow for Claude Code
|
|||||||
|
|
||||||
- [ ] All seven config files have matching versions
|
- [ ] All seven config files have matching versions
|
||||||
- [ ] `git grep` for old version returns zero hits
|
- [ ] `git grep` for old version returns zero hits
|
||||||
- [ ] `npm run build` succeeded
|
- [ ] `npm run build-and-sync` succeeded
|
||||||
- [ ] Git tag created and pushed
|
- [ ] Git tag created and pushed
|
||||||
- [ ] **`npm publish` succeeded and `npm view claude-mem@X.Y.Z version` confirms it** (so `npx claude-mem@X.Y.Z` resolves)
|
- [ ] **`npm publish` succeeded and `npm view claude-mem@X.Y.Z version` confirms it** (so `npx claude-mem@X.Y.Z` resolves)
|
||||||
- [ ] GitHub release created with notes
|
- [ ] GitHub release created with notes
|
||||||
|
|||||||
@@ -110,6 +110,27 @@ function runCodexBestEffort(args: string[], successMessage: string, failureMessa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isMarketplaceDifferentSourceError(error: unknown): boolean {
|
||||||
|
const message = error instanceof Error ? error.message : String(error);
|
||||||
|
return message.includes(`marketplace '${MARKETPLACE_NAME}' is already added from a different source`)
|
||||||
|
|| message.includes(`marketplace \`${MARKETPLACE_NAME}\` is already added from a different source`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerCodexMarketplace(marketplaceRoot: string): void {
|
||||||
|
try {
|
||||||
|
runCodex(['plugin', 'marketplace', 'add', marketplaceRoot]);
|
||||||
|
return;
|
||||||
|
} catch (error) {
|
||||||
|
if (!isMarketplaceDifferentSourceError(error)) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.warn(` Codex marketplace ${MARKETPLACE_NAME} is already registered from another source; replacing it with ${marketplaceRoot}.`);
|
||||||
|
runCodex(['plugin', 'marketplace', 'remove', MARKETPLACE_NAME]);
|
||||||
|
runCodex(['plugin', 'marketplace', 'add', marketplaceRoot]);
|
||||||
|
}
|
||||||
|
|
||||||
function parseSemver(value: string): [number, number, number] | null {
|
function parseSemver(value: string): [number, number, number] | null {
|
||||||
const match = value.match(/(\d+)\.(\d+)\.(\d+)/);
|
const match = value.match(/(\d+)\.(\d+)\.(\d+)/);
|
||||||
if (!match) return null;
|
if (!match) return null;
|
||||||
@@ -262,7 +283,7 @@ export async function installCodexCli(marketplaceRootOverride?: string): Promise
|
|||||||
const marketplaceRoot = resolvePluginMarketplaceRoot(marketplaceRootOverride);
|
const marketplaceRoot = resolvePluginMarketplaceRoot(marketplaceRootOverride);
|
||||||
|
|
||||||
console.log(` Registering Codex plugin marketplace: ${marketplaceRoot}`);
|
console.log(` Registering Codex plugin marketplace: ${marketplaceRoot}`);
|
||||||
runCodex(['plugin', 'marketplace', 'add', marketplaceRoot]);
|
registerCodexMarketplace(marketplaceRoot);
|
||||||
runCodexBestEffort(
|
runCodexBestEffort(
|
||||||
['plugin', 'marketplace', 'upgrade', MARKETPLACE_NAME],
|
['plugin', 'marketplace', 'upgrade', MARKETPLACE_NAME],
|
||||||
'Refreshed Codex marketplace and installed plugin cache.',
|
'Refreshed Codex marketplace and installed plugin cache.',
|
||||||
|
|||||||
@@ -141,6 +141,16 @@ describe('Install Non-TTY Support', () => {
|
|||||||
expect(installRegion).toContain('installed plugin cache');
|
expect(installRegion).toContain('installed plugin cache');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('replaces stale Codex marketplace registrations from a different source', () => {
|
||||||
|
const registerRegion = codexInstallerSource.slice(
|
||||||
|
codexInstallerSource.indexOf('function registerCodexMarketplace'),
|
||||||
|
codexInstallerSource.indexOf('function parseSemver'),
|
||||||
|
);
|
||||||
|
expect(registerRegion).toContain('isMarketplaceDifferentSourceError(error)');
|
||||||
|
expect(registerRegion).toContain("['plugin', 'marketplace', 'remove', MARKETPLACE_NAME]");
|
||||||
|
expect(registerRegion).toContain("['plugin', 'marketplace', 'add', marketplaceRoot]");
|
||||||
|
});
|
||||||
|
|
||||||
it('enables Codex plugin hooks during install', () => {
|
it('enables Codex plugin hooks during install', () => {
|
||||||
const installRegion = codexInstallerSource.slice(
|
const installRegion = codexInstallerSource.slice(
|
||||||
codexInstallerSource.indexOf('export async function installCodexCli'),
|
codexInstallerSource.indexOf('export async function installCodexCli'),
|
||||||
@@ -167,7 +177,7 @@ describe('Install Non-TTY Support', () => {
|
|||||||
expect(codexInstallerSource).toContain("const MIN_CODEX_MARKETPLACE_VERSION = '0.128.0'");
|
expect(codexInstallerSource).toContain("const MIN_CODEX_MARKETPLACE_VERSION = '0.128.0'");
|
||||||
expect(codexInstallerSource).toContain("spawnSync('codex', ['--version']");
|
expect(codexInstallerSource).toContain("spawnSync('codex', ['--version']");
|
||||||
expect(installRegion.indexOf('assertCodexMarketplaceSupported()'))
|
expect(installRegion.indexOf('assertCodexMarketplaceSupported()'))
|
||||||
.toBeLessThan(installRegion.indexOf("runCodex(['plugin', 'marketplace', 'add', marketplaceRoot])"));
|
.toBeLessThan(installRegion.indexOf('registerCodexMarketplace(marketplaceRoot)'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('removes legacy Codex AGENTS context only after marketplace registration succeeds', () => {
|
it('removes legacy Codex AGENTS context only after marketplace registration succeeds', () => {
|
||||||
@@ -175,7 +185,7 @@ describe('Install Non-TTY Support', () => {
|
|||||||
codexInstallerSource.indexOf('export async function installCodexCli'),
|
codexInstallerSource.indexOf('export async function installCodexCli'),
|
||||||
codexInstallerSource.indexOf('export function uninstallCodexCli'),
|
codexInstallerSource.indexOf('export function uninstallCodexCli'),
|
||||||
);
|
);
|
||||||
expect(installRegion.indexOf("runCodex(['plugin', 'marketplace', 'add', marketplaceRoot])"))
|
expect(installRegion.indexOf('registerCodexMarketplace(marketplaceRoot)'))
|
||||||
.toBeLessThan(installRegion.indexOf('cleanupLegacyCodexAgentsMdContext()'));
|
.toBeLessThan(installRegion.indexOf('cleanupLegacyCodexAgentsMdContext()'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user