Compare commits
9 Commits
v0.13.1-de
...
v0.13.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0af79002ed | ||
|
|
f3981a1cce | ||
|
|
031e8d5717 | ||
|
|
995fb3b6a3 | ||
|
|
aeb0ff11b3 | ||
|
|
b61cfbd9f9 | ||
|
|
481dd1a88a | ||
|
|
3f6cdd36f3 | ||
|
|
fe932c8307 |
81
package-lock.json
generated
81
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "codenomad-workspace",
|
"name": "codenomad-workspace",
|
||||||
"version": "0.13.1",
|
"version": "0.13.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "codenomad-workspace",
|
"name": "codenomad-workspace",
|
||||||
"version": "0.13.1",
|
"version": "0.13.3",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"7zip-bin": "^5.2.0",
|
"7zip-bin": "^5.2.0",
|
||||||
@@ -64,7 +64,6 @@
|
|||||||
"version": "7.28.5",
|
"version": "7.28.5",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.27.1",
|
"@babel/code-frame": "^7.27.1",
|
||||||
"@babel/generator": "^7.28.5",
|
"@babel/generator": "^7.28.5",
|
||||||
@@ -3381,7 +3380,6 @@
|
|||||||
"version": "7.20.5",
|
"version": "7.20.5",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.20.7",
|
"@babel/parser": "^7.20.7",
|
||||||
"@babel/types": "^7.20.7",
|
"@babel/types": "^7.20.7",
|
||||||
@@ -3483,7 +3481,6 @@
|
|||||||
"version": "22.19.0",
|
"version": "22.19.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~6.21.0"
|
"undici-types": "~6.21.0"
|
||||||
}
|
}
|
||||||
@@ -3558,7 +3555,6 @@
|
|||||||
"integrity": "sha512-MCbrb508JZHqe7bUibmZj/lyojdhLRnfkmyXnkrCM2zVrjTgL89U8UEfInpKTvPeTnxsw2hmyZxnhsdNR6yhwg==",
|
"integrity": "sha512-MCbrb508JZHqe7bUibmZj/lyojdhLRnfkmyXnkrCM2zVrjTgL89U8UEfInpKTvPeTnxsw2hmyZxnhsdNR6yhwg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cac": "^6.7.14",
|
"cac": "^6.7.14",
|
||||||
"colorette": "^2.0.20",
|
"colorette": "^2.0.20",
|
||||||
@@ -3641,7 +3637,6 @@
|
|||||||
"version": "6.12.6",
|
"version": "6.12.6",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fast-deep-equal": "^3.1.1",
|
"fast-deep-equal": "^3.1.1",
|
||||||
"fast-json-stable-stringify": "^2.0.0",
|
"fast-json-stable-stringify": "^2.0.0",
|
||||||
@@ -3844,6 +3839,7 @@
|
|||||||
"version": "5.3.2",
|
"version": "5.3.2",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"archiver-utils": "^2.1.0",
|
"archiver-utils": "^2.1.0",
|
||||||
"async": "^3.2.4",
|
"async": "^3.2.4",
|
||||||
@@ -3861,6 +3857,7 @@
|
|||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"glob": "^7.1.4",
|
"glob": "^7.1.4",
|
||||||
"graceful-fs": "^4.2.0",
|
"graceful-fs": "^4.2.0",
|
||||||
@@ -3881,6 +3878,7 @@
|
|||||||
"version": "2.3.8",
|
"version": "2.3.8",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-util-is": "~1.0.0",
|
"core-util-is": "~1.0.0",
|
||||||
"inherits": "~2.0.3",
|
"inherits": "~2.0.3",
|
||||||
@@ -3894,12 +3892,14 @@
|
|||||||
"node_modules/archiver-utils/node_modules/safe-buffer": {
|
"node_modules/archiver-utils/node_modules/safe-buffer": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/archiver-utils/node_modules/string_decoder": {
|
"node_modules/archiver-utils/node_modules/string_decoder": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safe-buffer": "~5.1.0"
|
"safe-buffer": "~5.1.0"
|
||||||
}
|
}
|
||||||
@@ -4213,6 +4213,7 @@
|
|||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"buffer": "^5.5.0",
|
"buffer": "^5.5.0",
|
||||||
"inherits": "^2.0.4",
|
"inherits": "^2.0.4",
|
||||||
@@ -4276,7 +4277,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"baseline-browser-mapping": "^2.9.0",
|
"baseline-browser-mapping": "^2.9.0",
|
||||||
"caniuse-lite": "^1.0.30001759",
|
"caniuse-lite": "^1.0.30001759",
|
||||||
@@ -4767,6 +4767,7 @@
|
|||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"buffer-crc32": "^0.2.13",
|
"buffer-crc32": "^0.2.13",
|
||||||
"crc32-stream": "^4.0.2",
|
"crc32-stream": "^4.0.2",
|
||||||
@@ -4896,6 +4897,7 @@
|
|||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"crc32": "bin/crc32.njs"
|
"crc32": "bin/crc32.njs"
|
||||||
},
|
},
|
||||||
@@ -4907,6 +4909,7 @@
|
|||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"crc-32": "^1.2.0",
|
"crc-32": "^1.2.0",
|
||||||
"readable-stream": "^3.4.0"
|
"readable-stream": "^3.4.0"
|
||||||
@@ -5272,7 +5275,6 @@
|
|||||||
"version": "24.13.3",
|
"version": "24.13.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"app-builder-lib": "24.13.3",
|
"app-builder-lib": "24.13.3",
|
||||||
"builder-util": "24.13.1",
|
"builder-util": "24.13.1",
|
||||||
@@ -5439,6 +5441,7 @@
|
|||||||
"version": "24.13.3",
|
"version": "24.13.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"app-builder-lib": "24.13.3",
|
"app-builder-lib": "24.13.3",
|
||||||
"archiver": "^5.3.1",
|
"archiver": "^5.3.1",
|
||||||
@@ -5450,6 +5453,7 @@
|
|||||||
"version": "10.1.0",
|
"version": "10.1.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"graceful-fs": "^4.2.0",
|
"graceful-fs": "^4.2.0",
|
||||||
"jsonfile": "^6.0.1",
|
"jsonfile": "^6.0.1",
|
||||||
@@ -5463,6 +5467,7 @@
|
|||||||
"version": "6.2.0",
|
"version": "6.2.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"universalify": "^2.0.0"
|
"universalify": "^2.0.0"
|
||||||
},
|
},
|
||||||
@@ -5474,6 +5479,7 @@
|
|||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 10.0.0"
|
"node": ">= 10.0.0"
|
||||||
}
|
}
|
||||||
@@ -6191,7 +6197,8 @@
|
|||||||
"node_modules/fs-constants": {
|
"node_modules/fs-constants": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/fs-extra": {
|
"node_modules/fs-extra": {
|
||||||
"version": "8.1.0",
|
"version": "8.1.0",
|
||||||
@@ -7408,7 +7415,8 @@
|
|||||||
"node_modules/isarray": {
|
"node_modules/isarray": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/isbinaryfile": {
|
"node_modules/isbinaryfile": {
|
||||||
"version": "5.0.6",
|
"version": "5.0.6",
|
||||||
@@ -7458,7 +7466,6 @@
|
|||||||
"version": "1.21.7",
|
"version": "1.21.7",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"jiti": "bin/jiti.js"
|
"jiti": "bin/jiti.js"
|
||||||
}
|
}
|
||||||
@@ -7590,6 +7597,7 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"readable-stream": "^2.0.5"
|
"readable-stream": "^2.0.5"
|
||||||
},
|
},
|
||||||
@@ -7601,6 +7609,7 @@
|
|||||||
"version": "2.3.8",
|
"version": "2.3.8",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-util-is": "~1.0.0",
|
"core-util-is": "~1.0.0",
|
||||||
"inherits": "~2.0.3",
|
"inherits": "~2.0.3",
|
||||||
@@ -7614,12 +7623,14 @@
|
|||||||
"node_modules/lazystream/node_modules/safe-buffer": {
|
"node_modules/lazystream/node_modules/safe-buffer": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/lazystream/node_modules/string_decoder": {
|
"node_modules/lazystream/node_modules/string_decoder": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safe-buffer": "~5.1.0"
|
"safe-buffer": "~5.1.0"
|
||||||
}
|
}
|
||||||
@@ -7684,22 +7695,26 @@
|
|||||||
"node_modules/lodash.defaults": {
|
"node_modules/lodash.defaults": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/lodash.difference": {
|
"node_modules/lodash.difference": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/lodash.flatten": {
|
"node_modules/lodash.flatten": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/lodash.isplainobject": {
|
"node_modules/lodash.isplainobject": {
|
||||||
"version": "4.0.6",
|
"version": "4.0.6",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/lodash.sortby": {
|
"node_modules/lodash.sortby": {
|
||||||
"version": "4.7.0",
|
"version": "4.7.0",
|
||||||
@@ -7711,7 +7726,8 @@
|
|||||||
"node_modules/lodash.union": {
|
"node_modules/lodash.union": {
|
||||||
"version": "4.6.0",
|
"version": "4.6.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/lowercase-keys": {
|
"node_modules/lowercase-keys": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
@@ -8515,7 +8531,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nanoid": "^3.3.11",
|
"nanoid": "^3.3.11",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
@@ -8663,7 +8678,8 @@
|
|||||||
"node_modules/process-nextick-args": {
|
"node_modules/process-nextick-args": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/process-warning": {
|
"node_modules/process-warning": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
@@ -8912,6 +8928,7 @@
|
|||||||
"version": "3.6.2",
|
"version": "3.6.2",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"inherits": "^2.0.3",
|
"inherits": "^2.0.3",
|
||||||
"string_decoder": "^1.1.1",
|
"string_decoder": "^1.1.1",
|
||||||
@@ -8925,6 +8942,7 @@
|
|||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"minimatch": "^5.1.0"
|
"minimatch": "^5.1.0"
|
||||||
}
|
}
|
||||||
@@ -9227,7 +9245,6 @@
|
|||||||
"version": "4.52.5",
|
"version": "4.52.5",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/estree": "1.0.8"
|
"@types/estree": "1.0.8"
|
||||||
},
|
},
|
||||||
@@ -9451,7 +9468,6 @@
|
|||||||
"node_modules/seroval": {
|
"node_modules/seroval": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
@@ -9775,7 +9791,6 @@
|
|||||||
"node_modules/solid-js": {
|
"node_modules/solid-js": {
|
||||||
"version": "1.9.10",
|
"version": "1.9.10",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csstype": "^3.1.0",
|
"csstype": "^3.1.0",
|
||||||
"seroval": "~1.3.0",
|
"seroval": "~1.3.0",
|
||||||
@@ -9916,6 +9931,7 @@
|
|||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safe-buffer": "~5.2.0"
|
"safe-buffer": "~5.2.0"
|
||||||
}
|
}
|
||||||
@@ -10249,6 +10265,7 @@
|
|||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bl": "^4.0.3",
|
"bl": "^4.0.3",
|
||||||
"end-of-stream": "^1.4.1",
|
"end-of-stream": "^1.4.1",
|
||||||
@@ -10441,7 +10458,6 @@
|
|||||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
@@ -10691,7 +10707,6 @@
|
|||||||
"version": "5.9.3",
|
"version": "5.9.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
@@ -11039,7 +11054,6 @@
|
|||||||
"version": "5.4.21",
|
"version": "5.4.21",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.21.3",
|
"esbuild": "^0.21.3",
|
||||||
"postcss": "^8.4.43",
|
"postcss": "^8.4.43",
|
||||||
@@ -11524,7 +11538,6 @@
|
|||||||
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"fast-uri": "^3.0.1",
|
"fast-uri": "^3.0.1",
|
||||||
@@ -11719,7 +11732,6 @@
|
|||||||
"integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
|
"integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"rollup": "dist/bin/rollup"
|
"rollup": "dist/bin/rollup"
|
||||||
},
|
},
|
||||||
@@ -12008,6 +12020,7 @@
|
|||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"archiver-utils": "^3.0.4",
|
"archiver-utils": "^3.0.4",
|
||||||
"compress-commons": "^4.1.2",
|
"compress-commons": "^4.1.2",
|
||||||
@@ -12021,6 +12034,7 @@
|
|||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"glob": "^7.2.3",
|
"glob": "^7.2.3",
|
||||||
"graceful-fs": "^4.2.0",
|
"graceful-fs": "^4.2.0",
|
||||||
@@ -12040,7 +12054,6 @@
|
|||||||
"node_modules/zod": {
|
"node_modules/zod": {
|
||||||
"version": "3.25.76",
|
"version": "3.25.76",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/colinhacks"
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
}
|
}
|
||||||
@@ -12055,7 +12068,7 @@
|
|||||||
},
|
},
|
||||||
"packages/electron-app": {
|
"packages/electron-app": {
|
||||||
"name": "@neuralnomads/codenomad-electron-app",
|
"name": "@neuralnomads/codenomad-electron-app",
|
||||||
"version": "0.13.1",
|
"version": "0.13.3",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codenomad/ui": "file:../ui",
|
"@codenomad/ui": "file:../ui",
|
||||||
@@ -12092,7 +12105,7 @@
|
|||||||
},
|
},
|
||||||
"packages/server": {
|
"packages/server": {
|
||||||
"name": "@neuralnomads/codenomad",
|
"name": "@neuralnomads/codenomad",
|
||||||
"version": "0.13.1",
|
"version": "0.13.3",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/cors": "^8.5.0",
|
"@fastify/cors": "^8.5.0",
|
||||||
@@ -12134,7 +12147,7 @@
|
|||||||
},
|
},
|
||||||
"packages/tauri-app": {
|
"packages/tauri-app": {
|
||||||
"name": "@codenomad/tauri-app",
|
"name": "@codenomad/tauri-app",
|
||||||
"version": "0.13.1",
|
"version": "0.13.3",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tauri-apps/cli": "^2.9.4"
|
"@tauri-apps/cli": "^2.9.4"
|
||||||
@@ -12142,7 +12155,7 @@
|
|||||||
},
|
},
|
||||||
"packages/ui": {
|
"packages/ui": {
|
||||||
"name": "@codenomad/ui",
|
"name": "@codenomad/ui",
|
||||||
"version": "0.13.1",
|
"version": "0.13.3",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@git-diff-view/solid": "^0.0.8",
|
"@git-diff-view/solid": "^0.0.8",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "codenomad-workspace",
|
"name": "codenomad-workspace",
|
||||||
"version": "0.13.1",
|
"version": "0.13.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "CodeNomad monorepo workspace",
|
"description": "CodeNomad monorepo workspace",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
"build:mac-x64": "npm run build:mac-x64 --workspace @neuralnomads/codenomad-electron-app",
|
"build:mac-x64": "npm run build:mac-x64 --workspace @neuralnomads/codenomad-electron-app",
|
||||||
"build:binaries": "npm run build:binaries --workspace @neuralnomads/codenomad-electron-app",
|
"build:binaries": "npm run build:binaries --workspace @neuralnomads/codenomad-electron-app",
|
||||||
"typecheck": "npm run typecheck --workspace @codenomad/ui && npm run typecheck --workspace @neuralnomads/codenomad-electron-app",
|
"typecheck": "npm run typecheck --workspace @codenomad/ui && npm run typecheck --workspace @neuralnomads/codenomad-electron-app",
|
||||||
"bumpVersion": "npm version --workspaces --include-workspace-root --no-git-tag-version && npm run sync:version --workspace @codenomad/tauri-app"
|
"bumpVersion": "node ./scripts/bump-version.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"7zip-bin": "^5.2.0",
|
"7zip-bin": "^5.2.0",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"minServerVersion": "0.13.1",
|
"minServerVersion": "0.13.3",
|
||||||
"latestServerUrl": "https://github.com/NeuralNomadsAI/CodeNomad/releases/latest"
|
"latestServerUrl": "https://github.com/NeuralNomadsAI/CodeNomad/releases/latest"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@neuralnomads/codenomad-electron-app",
|
"name": "@neuralnomads/codenomad-electron-app",
|
||||||
"version": "0.13.1",
|
"version": "0.13.3",
|
||||||
"description": "CodeNomad - AI coding assistant",
|
"description": "CodeNomad - AI coding assistant",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": {
|
"author": {
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@opencode-ai/plugin": "1.3.2"
|
"@opencode-ai/plugin": "1.3.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
4
packages/server/package-lock.json
generated
4
packages/server/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@neuralnomads/codenomad",
|
"name": "@neuralnomads/codenomad",
|
||||||
"version": "0.13.1",
|
"version": "0.13.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@neuralnomads/codenomad",
|
"name": "@neuralnomads/codenomad",
|
||||||
"version": "0.13.1",
|
"version": "0.13.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/cors": "^8.5.0",
|
"@fastify/cors": "^8.5.0",
|
||||||
"@fastify/reply-from": "^9.8.0",
|
"@fastify/reply-from": "^9.8.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@neuralnomads/codenomad",
|
"name": "@neuralnomads/codenomad",
|
||||||
"version": "0.13.1",
|
"version": "0.13.3",
|
||||||
"description": "CodeNomad Server",
|
"description": "CodeNomad Server",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": {
|
"author": {
|
||||||
|
|||||||
2
packages/tauri-app/Cargo.lock
generated
2
packages/tauri-app/Cargo.lock
generated
@@ -458,7 +458,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "codenomad-tauri"
|
name = "codenomad-tauri"
|
||||||
version = "0.12.3"
|
version = "0.13.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"dirs 5.0.1",
|
"dirs 5.0.1",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@codenomad/tauri-app",
|
"name": "@codenomad/tauri-app",
|
||||||
"version": "0.13.1",
|
"version": "0.13.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "codenomad-tauri"
|
name = "codenomad-tauri"
|
||||||
version = "0.12.3"
|
version = "0.13.3"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "CodeNomad",
|
"productName": "CodeNomad",
|
||||||
"version": "0.12.3",
|
"version": "0.13.3",
|
||||||
"identifier": "ai.neuralnomads.codenomad.client",
|
"identifier": "ai.neuralnomads.codenomad.client",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "npm run dev:bootstrap",
|
"beforeDevCommand": "npm run dev:bootstrap",
|
||||||
"beforeBuildCommand": "npm run bundle:server",
|
"beforeBuildCommand": "npm run bundle:server",
|
||||||
"frontendDist": "resources/ui-loading"
|
"frontendDist": "resources/ui-loading"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"app": {
|
"app": {
|
||||||
"withGlobalTauri": true,
|
"withGlobalTauri": true,
|
||||||
"windows": [
|
"windows": [
|
||||||
@@ -33,9 +30,13 @@
|
|||||||
],
|
],
|
||||||
"security": {
|
"security": {
|
||||||
"assetProtocol": {
|
"assetProtocol": {
|
||||||
"scope": ["**"]
|
"scope": [
|
||||||
|
"**"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"capabilities": ["main-window-native-dialogs"]
|
"capabilities": [
|
||||||
|
"main-window-native-dialogs"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bundle": {
|
"bundle": {
|
||||||
@@ -44,7 +45,17 @@
|
|||||||
"resources/server",
|
"resources/server",
|
||||||
"resources/ui-loading"
|
"resources/ui-loading"
|
||||||
],
|
],
|
||||||
"icon": ["icon.icns", "icon.ico", "icon.png"],
|
"icon": [
|
||||||
"targets": ["app", "appimage", "deb", "rpm", "nsis"]
|
"icon.icns",
|
||||||
|
"icon.ico",
|
||||||
|
"icon.png"
|
||||||
|
],
|
||||||
|
"targets": [
|
||||||
|
"app",
|
||||||
|
"appimage",
|
||||||
|
"deb",
|
||||||
|
"rpm",
|
||||||
|
"nsis"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@codenomad/ui",
|
"name": "@codenomad/ui",
|
||||||
"version": "0.13.1",
|
"version": "0.13.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -443,7 +443,7 @@ const FolderSelectionView: Component<FolderSelectionViewProps> = (props) => {
|
|||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
class="selector-button selector-button-secondary w-auto px-3 py-1.5 inline-flex items-center justify-center gap-1.5"
|
class="selector-button selector-button-secondary w-auto px-3 py-1.5 inline-flex items-center justify-center gap-1.5"
|
||||||
aria-label={t("folderSelection.links.githubStars")}
|
aria-label={t("folderSelection.links.githubStars")}
|
||||||
title={t("folderSelection.links.githubStars")}
|
title={githubStars() !== null ? `${t("folderSelection.links.githubStars")}: ${githubStars()!.toLocaleString()}` : t("folderSelection.links.githubStars")}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
void openExternalUrl(GITHUB_URL, "folder-selection")
|
void openExternalUrl(GITHUB_URL, "folder-selection")
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ import SessionSidebar from "./shell/SessionSidebar"
|
|||||||
import { useSessionSidebarRequests } from "./shell/useSessionSidebarRequests"
|
import { useSessionSidebarRequests } from "./shell/useSessionSidebarRequests"
|
||||||
import RightPanel from "./shell/right-panel/RightPanel"
|
import RightPanel from "./shell/right-panel/RightPanel"
|
||||||
import { useDrawerChrome } from "./shell/useDrawerChrome"
|
import { useDrawerChrome } from "./shell/useDrawerChrome"
|
||||||
import { getSessionStatus } from "../../stores/session-status"
|
import { getRetrySeconds, getSessionRetry, getSessionStatus } from "../../stores/session-status"
|
||||||
import { Maximize2, ShieldAlert } from "lucide-solid"
|
import { Maximize2, ShieldAlert } from "lucide-solid"
|
||||||
|
|
||||||
import type { LayoutMode } from "./shell/types"
|
import type { LayoutMode } from "./shell/types"
|
||||||
@@ -104,6 +104,7 @@ const InstanceShell2: Component<InstanceShellProps> = (props) => {
|
|||||||
const [selectedBackgroundProcess, setSelectedBackgroundProcess] = createSignal<BackgroundProcess | null>(null)
|
const [selectedBackgroundProcess, setSelectedBackgroundProcess] = createSignal<BackgroundProcess | null>(null)
|
||||||
const [showBackgroundOutput, setShowBackgroundOutput] = createSignal(false)
|
const [showBackgroundOutput, setShowBackgroundOutput] = createSignal(false)
|
||||||
const [permissionModalOpen, setPermissionModalOpen] = createSignal(false)
|
const [permissionModalOpen, setPermissionModalOpen] = createSignal(false)
|
||||||
|
const [now, setNow] = createSignal(Date.now())
|
||||||
|
|
||||||
// Worktree selector manages its own dialogs.
|
// Worktree selector manages its own dialogs.
|
||||||
const [showSessionSearch, setShowSessionSearch] = createSignal(false)
|
const [showSessionSearch, setShowSessionSearch] = createSignal(false)
|
||||||
@@ -237,6 +238,12 @@ const InstanceShell2: Component<InstanceShellProps> = (props) => {
|
|||||||
window.localStorage.setItem(RIGHT_DRAWER_STORAGE_KEY, rightDrawerWidth().toString())
|
window.localStorage.setItem(RIGHT_DRAWER_STORAGE_KEY, rightDrawerWidth().toString())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
if (typeof window === "undefined") return
|
||||||
|
const timer = window.setInterval(() => setNow(Date.now()), 1000)
|
||||||
|
onCleanup(() => window.clearInterval(timer))
|
||||||
|
})
|
||||||
|
|
||||||
const connectionStatus = () => sseManager.getStatus(props.instance.id)
|
const connectionStatus = () => sseManager.getStatus(props.instance.id)
|
||||||
const connectionStatusClass = () => {
|
const connectionStatusClass = () => {
|
||||||
const status = connectionStatus()
|
const status = connectionStatus()
|
||||||
@@ -306,17 +313,28 @@ const InstanceShell2: Component<InstanceShellProps> = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const status = getSessionStatus(props.instance.id, activeSessionId)
|
const status = getSessionStatus(props.instance.id, activeSessionId)
|
||||||
const text =
|
const retry = getSessionRetry(props.instance.id, activeSessionId)
|
||||||
status === "working"
|
const text = retry
|
||||||
|
? (() => {
|
||||||
|
const seconds = getRetrySeconds(retry.next, now())
|
||||||
|
return seconds > 0 ? t("sessionList.status.retryingIn", { seconds: String(seconds) }) : t("sessionList.status.retrying")
|
||||||
|
})()
|
||||||
|
: status === "working"
|
||||||
? t("sessionList.status.working")
|
? t("sessionList.status.working")
|
||||||
: status === "compacting"
|
: status === "compacting"
|
||||||
? t("sessionList.status.compacting")
|
? t("sessionList.status.compacting")
|
||||||
: t("sessionList.status.idle")
|
: t("sessionList.status.idle")
|
||||||
|
|
||||||
return {
|
return {
|
||||||
className: `session-${status}`,
|
className: `session-${retry ? "retrying" : status}`,
|
||||||
text,
|
text,
|
||||||
showAlertIcon: false,
|
showAlertIcon: false,
|
||||||
|
title: retry
|
||||||
|
? t("sessionList.status.retryTooltip", {
|
||||||
|
message: retry.message,
|
||||||
|
attempt: String(retry.attempt),
|
||||||
|
})
|
||||||
|
: undefined,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -324,7 +342,7 @@ const InstanceShell2: Component<InstanceShellProps> = (props) => {
|
|||||||
const pill = activeSessionStatusPill()
|
const pill = activeSessionStatusPill()
|
||||||
if (!pill) return null
|
if (!pill) return null
|
||||||
return (
|
return (
|
||||||
<span class={`status-indicator session-status session-status-list ${pill.className}`}>
|
<span class={`status-indicator session-status session-status-list ${pill.className}`} title={pill.title}>
|
||||||
{pill.showAlertIcon ? <ShieldAlert class="w-3.5 h-3.5" aria-hidden="true" /> : <span class="status-dot" />}
|
{pill.showAlertIcon ? <ShieldAlert class="w-3.5 h-3.5" aria-hidden="true" /> : <span class="status-dot" />}
|
||||||
{pill.text}
|
{pill.text}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -123,7 +123,11 @@ export function Markdown(props: MarkdownProps) {
|
|||||||
version: () => resolved().version,
|
version: () => resolved().version,
|
||||||
})
|
})
|
||||||
|
|
||||||
const commitCacheEntry = (snapshot: ReturnType<typeof resolved>, renderedHtml: string) => {
|
const commitCacheEntry = (
|
||||||
|
snapshot: ReturnType<typeof resolved>,
|
||||||
|
renderedHtml: string,
|
||||||
|
options?: { cache?: boolean },
|
||||||
|
) => {
|
||||||
const cacheEntry: RenderCache = {
|
const cacheEntry: RenderCache = {
|
||||||
text: snapshot.text,
|
text: snapshot.text,
|
||||||
html: renderedHtml,
|
html: renderedHtml,
|
||||||
@@ -131,7 +135,9 @@ export function Markdown(props: MarkdownProps) {
|
|||||||
mode: `${snapshot.version}:${snapshot.escapeRawHtml ? "escaped" : "raw"}`,
|
mode: `${snapshot.version}:${snapshot.escapeRawHtml ? "escaped" : "raw"}`,
|
||||||
}
|
}
|
||||||
setHtml(renderedHtml)
|
setHtml(renderedHtml)
|
||||||
cacheHandle.set(cacheEntry)
|
if (options?.cache ?? true) {
|
||||||
|
cacheHandle.set(cacheEntry)
|
||||||
|
}
|
||||||
notifyRendered()
|
notifyRendered()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,9 +148,10 @@ export function Markdown(props: MarkdownProps) {
|
|||||||
suppressHighlight: !snapshot.highlightEnabled,
|
suppressHighlight: !snapshot.highlightEnabled,
|
||||||
escapeRawHtml: snapshot.escapeRawHtml,
|
escapeRawHtml: snapshot.escapeRawHtml,
|
||||||
})
|
})
|
||||||
|
const shouldCache = !snapshot.highlightEnabled || !markdown.hasPendingCodeHighlight(snapshot.text)
|
||||||
|
|
||||||
if (latestRequestKey === snapshot.requestKey) {
|
if (latestRequestKey === snapshot.requestKey) {
|
||||||
commitCacheEntry(snapshot, rendered)
|
commitCacheEntry(snapshot, rendered, { cache: shouldCache })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,12 @@ import { usePromptAttachments } from "./prompt-input/usePromptAttachments"
|
|||||||
import { usePromptPicker } from "./prompt-input/usePromptPicker"
|
import { usePromptPicker } from "./prompt-input/usePromptPicker"
|
||||||
import { usePromptKeyDown } from "./prompt-input/usePromptKeyDown"
|
import { usePromptKeyDown } from "./prompt-input/usePromptKeyDown"
|
||||||
import { usePromptVoiceInput } from "./prompt-input/usePromptVoiceInput"
|
import { usePromptVoiceInput } from "./prompt-input/usePromptVoiceInput"
|
||||||
import { canUseConversationMode, isConversationModeEnabled, toggleConversationMode } from "../stores/conversation-speech"
|
import {
|
||||||
|
canUseConversationMode,
|
||||||
|
clearConversationPlaybackForInstance,
|
||||||
|
isConversationModeEnabled,
|
||||||
|
toggleConversationMode,
|
||||||
|
} from "../stores/conversation-speech"
|
||||||
const log = getLogger("actions")
|
const log = getLogger("actions")
|
||||||
const LazyUnifiedPicker = lazy(() => import("./unified-picker"))
|
const LazyUnifiedPicker = lazy(() => import("./unified-picker"))
|
||||||
|
|
||||||
@@ -492,6 +497,8 @@ export default function PromptInput(props: PromptInputProps) {
|
|||||||
const beginVoicePress = (event?: PointerEvent | KeyboardEvent) => {
|
const beginVoicePress = (event?: PointerEvent | KeyboardEvent) => {
|
||||||
if (voiceButtonPressed || props.disabled || voiceInput.isTranscribing() || !voiceInput.canUseVoiceInput()) return
|
if (voiceButtonPressed || props.disabled || voiceInput.isTranscribing() || !voiceInput.canUseVoiceInput()) return
|
||||||
voiceButtonPressed = true
|
voiceButtonPressed = true
|
||||||
|
// Treat a mic press as barge-in: stop any active assistant speech before listening.
|
||||||
|
clearConversationPlaybackForInstance(props.instanceId)
|
||||||
|
|
||||||
if (event instanceof PointerEvent) {
|
if (event instanceof PointerEvent) {
|
||||||
const target = event.currentTarget
|
const target = event.currentTarget
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Component, For, Show, createSignal, createMemo, createEffect, JSX, onCleanup } from "solid-js"
|
import { Component, For, Show, createSignal, createMemo, createEffect, JSX, onCleanup } from "solid-js"
|
||||||
import type { SessionStatus } from "../types/session"
|
import type { SessionStatus } from "../types/session"
|
||||||
import type { SessionThread } from "../stores/session-state"
|
import type { SessionThread } from "../stores/session-state"
|
||||||
import { getSessionStatus } from "../stores/session-status"
|
import { getRetrySeconds, getSessionRetry, getSessionStatus } from "../stores/session-status"
|
||||||
import { Bot, User, Copy, Trash2, Pencil, ShieldAlert, ChevronDown, Search, Square, CheckSquare, MinusSquare, Split, RotateCw } from "lucide-solid"
|
import { Bot, User, Copy, Trash2, Pencil, ShieldAlert, ChevronDown, Search, Square, CheckSquare, MinusSquare, Split, RotateCw } from "lucide-solid"
|
||||||
import KeyboardHint from "./keyboard-hint"
|
import KeyboardHint from "./keyboard-hint"
|
||||||
import SessionRenameDialog from "./session-rename-dialog"
|
import SessionRenameDialog from "./session-rename-dialog"
|
||||||
@@ -55,6 +55,13 @@ const SessionList: Component<SessionListProps> = (props) => {
|
|||||||
|
|
||||||
const [selectedSessionIds, setSelectedSessionIds] = createSignal<Set<string>>(new Set())
|
const [selectedSessionIds, setSelectedSessionIds] = createSignal<Set<string>>(new Set())
|
||||||
const [reloadingSessionIds, setReloadingSessionIds] = createSignal<Set<string>>(new Set())
|
const [reloadingSessionIds, setReloadingSessionIds] = createSignal<Set<string>>(new Set())
|
||||||
|
const [now, setNow] = createSignal(Date.now())
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
if (typeof window === "undefined") return
|
||||||
|
const timer = window.setInterval(() => setNow(Date.now()), 1000)
|
||||||
|
onCleanup(() => window.clearInterval(timer))
|
||||||
|
})
|
||||||
|
|
||||||
const normalizeSessionLabel = (sessionId: string) => {
|
const normalizeSessionLabel = (sessionId: string) => {
|
||||||
const session = sessionStateSessions().get(props.instanceId)?.get(sessionId)
|
const session = sessionStateSessions().get(props.instanceId)?.get(sessionId)
|
||||||
@@ -400,7 +407,13 @@ const SessionList: Component<SessionListProps> = (props) => {
|
|||||||
const isActive = () => props.activeSessionId === rowProps.sessionId
|
const isActive = () => props.activeSessionId === rowProps.sessionId
|
||||||
const title = () => session()?.title || t("sessionList.session.untitled")
|
const title = () => session()?.title || t("sessionList.session.untitled")
|
||||||
const status = () => getSessionStatus(props.instanceId, rowProps.sessionId)
|
const status = () => getSessionStatus(props.instanceId, rowProps.sessionId)
|
||||||
|
const retry = () => getSessionRetry(props.instanceId, rowProps.sessionId)
|
||||||
const statusLabel = () => {
|
const statusLabel = () => {
|
||||||
|
const retryState = retry()
|
||||||
|
if (retryState) {
|
||||||
|
const seconds = getRetrySeconds(retryState.next, now())
|
||||||
|
return seconds > 0 ? t("sessionList.status.retryingIn", { seconds: String(seconds) }) : t("sessionList.status.retrying")
|
||||||
|
}
|
||||||
switch (formatSessionStatus(status())) {
|
switch (formatSessionStatus(status())) {
|
||||||
case "working":
|
case "working":
|
||||||
return t("sessionList.status.working")
|
return t("sessionList.status.working")
|
||||||
@@ -413,13 +426,21 @@ const SessionList: Component<SessionListProps> = (props) => {
|
|||||||
const needsPermission = () => Boolean(session()?.pendingPermission)
|
const needsPermission = () => Boolean(session()?.pendingPermission)
|
||||||
const needsQuestion = () => Boolean((session() as any)?.pendingQuestion)
|
const needsQuestion = () => Boolean((session() as any)?.pendingQuestion)
|
||||||
const needsInput = () => needsPermission() || needsQuestion()
|
const needsInput = () => needsPermission() || needsQuestion()
|
||||||
const statusClassName = () => (needsInput() ? "session-permission" : `session-${status()}`)
|
const statusClassName = () => (needsInput() ? "session-permission" : `session-${retry() ? "retrying" : status()}`)
|
||||||
const statusText = () =>
|
const statusText = () =>
|
||||||
needsPermission()
|
needsPermission()
|
||||||
? t("sessionList.status.needsPermission")
|
? t("sessionList.status.needsPermission")
|
||||||
: needsQuestion()
|
: needsQuestion()
|
||||||
? t("sessionList.status.needsInput")
|
? t("sessionList.status.needsInput")
|
||||||
: statusLabel()
|
: statusLabel()
|
||||||
|
const statusTooltip = () => {
|
||||||
|
const retryState = retry()
|
||||||
|
if (!retryState) return undefined
|
||||||
|
return t("sessionList.status.retryTooltip", {
|
||||||
|
message: retryState.message,
|
||||||
|
attempt: String(retryState.attempt),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const isSelected = () => selectedSessionIds().has(rowProps.sessionId)
|
const isSelected = () => selectedSessionIds().has(rowProps.sessionId)
|
||||||
|
|
||||||
@@ -499,7 +520,7 @@ const SessionList: Component<SessionListProps> = (props) => {
|
|||||||
<ChevronDown class={`w-3.5 h-3.5 transition-transform ${rowProps.expanded ? "" : "-rotate-90"}`} />
|
<ChevronDown class={`w-3.5 h-3.5 transition-transform ${rowProps.expanded ? "" : "-rotate-90"}`} />
|
||||||
</span>
|
</span>
|
||||||
</Show>
|
</Show>
|
||||||
<span class={`status-indicator session-status session-status-list ${statusClassName()}`}>
|
<span class={`status-indicator session-status session-status-list ${statusClassName()}`} title={statusTooltip()}>
|
||||||
{needsInput() ? <ShieldAlert class="w-3.5 h-3.5" aria-hidden="true" /> : <span class="status-dot" />}
|
{needsInput() ? <ShieldAlert class="w-3.5 h-3.5" aria-hidden="true" /> : <span class="status-dot" />}
|
||||||
{statusText()}
|
{statusText()}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -19,9 +19,6 @@ export function formatCompactCount(value: number): string {
|
|||||||
return `${(value / 1_000_000).toFixed(1)}M`
|
return `${(value / 1_000_000).toFixed(1)}M`
|
||||||
}
|
}
|
||||||
if (value >= 10_000) {
|
if (value >= 10_000) {
|
||||||
return `${Math.round(value / 1_000)}K`
|
|
||||||
}
|
|
||||||
if (value >= 1_000) {
|
|
||||||
const label = `${(value / 1_000).toFixed(1)}K`
|
const label = `${(value / 1_000).toFixed(1)}K`
|
||||||
return label.replace(/\.0K$/, "K")
|
return label.replace(/\.0K$/, "K")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ export const sessionMessages = {
|
|||||||
"sessionList.status.working": "Working",
|
"sessionList.status.working": "Working",
|
||||||
"sessionList.status.compacting": "Compacting",
|
"sessionList.status.compacting": "Compacting",
|
||||||
"sessionList.status.idle": "Idle",
|
"sessionList.status.idle": "Idle",
|
||||||
|
"sessionList.status.retrying": "Retrying",
|
||||||
|
"sessionList.status.retryingIn": "Retrying in {seconds}s",
|
||||||
|
"sessionList.status.retryTooltip": "{message} (Attempt {attempt})",
|
||||||
|
"sessionList.status.retryToast": "{countdown}: {message} (Attempt {attempt})",
|
||||||
"sessionList.status.needsPermission": "Needs Permission",
|
"sessionList.status.needsPermission": "Needs Permission",
|
||||||
"sessionList.status.needsInput": "Needs Input",
|
"sessionList.status.needsInput": "Needs Input",
|
||||||
"sessionList.expand.collapseAriaLabel": "Collapse session",
|
"sessionList.expand.collapseAriaLabel": "Collapse session",
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ export const sessionMessages = {
|
|||||||
"sessionList.status.working": "Trabajando",
|
"sessionList.status.working": "Trabajando",
|
||||||
"sessionList.status.compacting": "Compactando",
|
"sessionList.status.compacting": "Compactando",
|
||||||
"sessionList.status.idle": "Inactiva",
|
"sessionList.status.idle": "Inactiva",
|
||||||
|
"sessionList.status.retrying": "Reintentando",
|
||||||
|
"sessionList.status.retryingIn": "Reintentando en {seconds}s",
|
||||||
|
"sessionList.status.retryTooltip": "{message} (Intento {attempt})",
|
||||||
|
"sessionList.status.retryToast": "{countdown}: {message} (Intento {attempt})",
|
||||||
"sessionList.status.needsPermission": "Requiere permiso",
|
"sessionList.status.needsPermission": "Requiere permiso",
|
||||||
"sessionList.status.needsInput": "Requiere entrada",
|
"sessionList.status.needsInput": "Requiere entrada",
|
||||||
"sessionList.expand.collapseAriaLabel": "Colapsar sesión",
|
"sessionList.expand.collapseAriaLabel": "Colapsar sesión",
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ export const sessionMessages = {
|
|||||||
"sessionList.status.working": "En cours",
|
"sessionList.status.working": "En cours",
|
||||||
"sessionList.status.compacting": "Compactage",
|
"sessionList.status.compacting": "Compactage",
|
||||||
"sessionList.status.idle": "Inactif",
|
"sessionList.status.idle": "Inactif",
|
||||||
|
"sessionList.status.retrying": "Nouvelle tentative",
|
||||||
|
"sessionList.status.retryingIn": "Nouvelle tentative dans {seconds}s",
|
||||||
|
"sessionList.status.retryTooltip": "{message} (Tentative {attempt})",
|
||||||
|
"sessionList.status.retryToast": "{countdown} : {message} (Tentative {attempt})",
|
||||||
"sessionList.status.needsPermission": "Autorisation requise",
|
"sessionList.status.needsPermission": "Autorisation requise",
|
||||||
"sessionList.status.needsInput": "Entrée requise",
|
"sessionList.status.needsInput": "Entrée requise",
|
||||||
"sessionList.expand.collapseAriaLabel": "Réduire la session",
|
"sessionList.expand.collapseAriaLabel": "Réduire la session",
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ export const sessionMessages = {
|
|||||||
"sessionList.status.working": "עובד",
|
"sessionList.status.working": "עובד",
|
||||||
"sessionList.status.compacting": "מסכם",
|
"sessionList.status.compacting": "מסכם",
|
||||||
"sessionList.status.idle": "מוכן",
|
"sessionList.status.idle": "מוכן",
|
||||||
|
"sessionList.status.retrying": "מנסה שוב",
|
||||||
|
"sessionList.status.retryingIn": "מנסה שוב בעוד {seconds}ש׳",
|
||||||
|
"sessionList.status.retryTooltip": "{message} (ניסיון {attempt})",
|
||||||
|
"sessionList.status.retryToast": "{countdown}: {message} (ניסיון {attempt})",
|
||||||
"sessionList.status.needsPermission": "נדרש אישור",
|
"sessionList.status.needsPermission": "נדרש אישור",
|
||||||
"sessionList.status.needsInput": "נדרש קלט",
|
"sessionList.status.needsInput": "נדרש קלט",
|
||||||
"sessionList.expand.collapseAriaLabel": "כווץ סשן",
|
"sessionList.expand.collapseAriaLabel": "כווץ סשן",
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ export const sessionMessages = {
|
|||||||
"sessionList.status.working": "作業中",
|
"sessionList.status.working": "作業中",
|
||||||
"sessionList.status.compacting": "圧縮中",
|
"sessionList.status.compacting": "圧縮中",
|
||||||
"sessionList.status.idle": "待機中",
|
"sessionList.status.idle": "待機中",
|
||||||
|
"sessionList.status.retrying": "再試行中",
|
||||||
|
"sessionList.status.retryingIn": "{seconds}秒後に再試行",
|
||||||
|
"sessionList.status.retryTooltip": "{message}({attempt}回目)",
|
||||||
|
"sessionList.status.retryToast": "{countdown}: {message}({attempt}回目)",
|
||||||
"sessionList.status.needsPermission": "許可待ち",
|
"sessionList.status.needsPermission": "許可待ち",
|
||||||
"sessionList.status.needsInput": "入力待ち",
|
"sessionList.status.needsInput": "入力待ち",
|
||||||
"sessionList.expand.collapseAriaLabel": "セッションを折りたたむ",
|
"sessionList.expand.collapseAriaLabel": "セッションを折りたたむ",
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ export const sessionMessages = {
|
|||||||
"sessionList.status.working": "Работает",
|
"sessionList.status.working": "Работает",
|
||||||
"sessionList.status.compacting": "Компактация",
|
"sessionList.status.compacting": "Компактация",
|
||||||
"sessionList.status.idle": "Простой",
|
"sessionList.status.idle": "Простой",
|
||||||
|
"sessionList.status.retrying": "Повтор",
|
||||||
|
"sessionList.status.retryingIn": "Повтор через {seconds}с",
|
||||||
|
"sessionList.status.retryTooltip": "{message} (Попытка {attempt})",
|
||||||
|
"sessionList.status.retryToast": "{countdown}: {message} (Попытка {attempt})",
|
||||||
"sessionList.status.needsPermission": "Требуется разрешение",
|
"sessionList.status.needsPermission": "Требуется разрешение",
|
||||||
"sessionList.status.needsInput": "Требуется ввод",
|
"sessionList.status.needsInput": "Требуется ввод",
|
||||||
"sessionList.expand.collapseAriaLabel": "Свернуть сессию",
|
"sessionList.expand.collapseAriaLabel": "Свернуть сессию",
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ export const sessionMessages = {
|
|||||||
"sessionList.status.working": "工作中",
|
"sessionList.status.working": "工作中",
|
||||||
"sessionList.status.compacting": "压缩中",
|
"sessionList.status.compacting": "压缩中",
|
||||||
"sessionList.status.idle": "空闲",
|
"sessionList.status.idle": "空闲",
|
||||||
|
"sessionList.status.retrying": "重试中",
|
||||||
|
"sessionList.status.retryingIn": "{seconds} 秒后重试",
|
||||||
|
"sessionList.status.retryTooltip": "{message}(第 {attempt} 次尝试)",
|
||||||
|
"sessionList.status.retryToast": "{countdown}: {message}(第 {attempt} 次尝试)",
|
||||||
"sessionList.status.needsPermission": "需要权限",
|
"sessionList.status.needsPermission": "需要权限",
|
||||||
"sessionList.status.needsInput": "需要输入",
|
"sessionList.status.needsInput": "需要输入",
|
||||||
"sessionList.expand.collapseAriaLabel": "折叠会话",
|
"sessionList.expand.collapseAriaLabel": "折叠会话",
|
||||||
|
|||||||
@@ -120,14 +120,7 @@ function resolveLanguage(token: string): { canonical: string | null; raw: string
|
|||||||
return { canonical: null, raw: normalized }
|
return { canonical: null, raw: normalized }
|
||||||
}
|
}
|
||||||
|
|
||||||
async function ensureLanguages(content: string) {
|
function collectCodeFenceLanguages(content: string): string[] {
|
||||||
if (highlightSuppressed) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract code-fence language tokens via `marked` so we correctly handle code blocks
|
|
||||||
// that contain backticks (e.g. JS template literals). Regex-based fence scans tend
|
|
||||||
// to miss these and prevent languages from loading.
|
|
||||||
const foundLanguages = new Set<string>()
|
const foundLanguages = new Set<string>()
|
||||||
try {
|
try {
|
||||||
const tokens = marked.lexer(content) as any
|
const tokens = marked.lexer(content) as any
|
||||||
@@ -139,10 +132,44 @@ async function ensureLanguages(content: string) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
} catch {
|
} catch {
|
||||||
// If tokenization fails for any reason, skip language preloading.
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
return [...foundLanguages]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hasPendingCodeHighlight(content: string): boolean {
|
||||||
|
const languages = collectCodeFenceLanguages(content)
|
||||||
|
for (const token of languages) {
|
||||||
|
const rawToken = normalizeLanguageToken(token)
|
||||||
|
if (!rawToken || rawToken === "text") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const { canonical, raw } = resolveLanguage(token)
|
||||||
|
const langKey = canonical || raw
|
||||||
|
if (langKey === "text" || raw === "text") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!highlighter || !loadedLanguages.has(langKey)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
async function ensureLanguages(content: string) {
|
||||||
|
if (highlightSuppressed) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extract code-fence language tokens via `marked` so we correctly handle code blocks
|
||||||
|
// that contain backticks (e.g. JS template literals). Regex-based fence scans tend
|
||||||
|
// to miss these and prevent languages from loading.
|
||||||
|
const foundLanguages = collectCodeFenceLanguages(content)
|
||||||
|
|
||||||
// Queue language loading tasks
|
// Queue language loading tasks
|
||||||
for (const token of foundLanguages) {
|
for (const token of foundLanguages) {
|
||||||
const rawToken = normalizeLanguageToken(token)
|
const rawToken = normalizeLanguageToken(token)
|
||||||
|
|||||||
@@ -102,9 +102,11 @@ export function showToastNotification(payload: ToastPayload): ToastHandle {
|
|||||||
</button>
|
</button>
|
||||||
<div class="flex items-start gap-3 pr-6">
|
<div class="flex items-start gap-3 pr-6">
|
||||||
<span class={`mt-1 inline-block h-2.5 w-2.5 rounded-full ${accent.badge}`} />
|
<span class={`mt-1 inline-block h-2.5 w-2.5 rounded-full ${accent.badge}`} />
|
||||||
<div class="flex-1 text-sm leading-snug">
|
<div class="min-w-0 flex-1 text-sm leading-snug">
|
||||||
{payload.title && <p class={`font-semibold ${accent.headline}`}>{payload.title}</p>}
|
{payload.title && <p class={`break-words ${accent.headline} font-semibold`}>{payload.title}</p>}
|
||||||
<p class={`${accent.body} ${payload.title ? "mt-1" : ""}`}>{payload.message}</p>
|
<p class={`${accent.body} ${payload.title ? "mt-1" : ""} whitespace-pre-wrap break-words [overflow-wrap:anywhere]`}>
|
||||||
|
{payload.message}
|
||||||
|
</p>
|
||||||
{payload.action && (
|
{payload.action && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { mapSdkSessionStatus, type Session, type SessionStatus } from "../types/session"
|
import { mapSdkSessionRetry, mapSdkSessionStatus, type Session, type SessionStatus } from "../types/session"
|
||||||
import type { Message } from "../types/message"
|
import type { Message } from "../types/message"
|
||||||
import type { FileDiff } from "@opencode-ai/sdk/v2/client"
|
import type { FileDiff } from "@opencode-ai/sdk/v2/client"
|
||||||
|
|
||||||
@@ -149,12 +149,15 @@ async function fetchSessions(instanceId: string): Promise<void> {
|
|||||||
const existingStatus = existingSession?.status
|
const existingStatus = existingSession?.status
|
||||||
|
|
||||||
let status: SessionStatus
|
let status: SessionStatus
|
||||||
|
let retry = existingSession?.retry ?? null
|
||||||
if (existingStatus === "compacting") {
|
if (existingStatus === "compacting") {
|
||||||
status = "compacting"
|
status = "compacting"
|
||||||
|
retry = null
|
||||||
} else {
|
} else {
|
||||||
const rawStatus = (apiSession as any)?.status ?? statusById[apiSession.id]
|
const rawStatus = (apiSession as any)?.status ?? statusById[apiSession.id]
|
||||||
const hasType = rawStatus && typeof rawStatus === "object" && typeof rawStatus.type === "string"
|
const hasType = rawStatus && typeof rawStatus === "object" && typeof rawStatus.type === "string"
|
||||||
status = hasType ? mapSdkSessionStatus(rawStatus) : existingStatus ?? "idle"
|
status = hasType ? mapSdkSessionStatus(rawStatus) : existingStatus ?? "idle"
|
||||||
|
retry = hasType ? mapSdkSessionRetry(rawStatus) : retry
|
||||||
}
|
}
|
||||||
|
|
||||||
sessionMap.set(apiSession.id, {
|
sessionMap.set(apiSession.id, {
|
||||||
@@ -165,6 +168,7 @@ async function fetchSessions(instanceId: string): Promise<void> {
|
|||||||
agent: existingSession?.agent ?? "",
|
agent: existingSession?.agent ?? "",
|
||||||
model: existingSession?.model ?? { providerId: "", modelId: "" },
|
model: existingSession?.model ?? { providerId: "", modelId: "" },
|
||||||
status,
|
status,
|
||||||
|
retry,
|
||||||
version: apiSession.version,
|
version: apiSession.version,
|
||||||
time: {
|
time: {
|
||||||
...apiSession.time,
|
...apiSession.time,
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import type { PermissionReplyEventPropertiesLike, PermissionRequestLike } from "
|
|||||||
import { getQuestionId, getQuestionSessionId, getRequestIdFromQuestionReply } from "../types/question"
|
import { getQuestionId, getQuestionSessionId, getRequestIdFromQuestionReply } from "../types/question"
|
||||||
import type { QuestionRequest } from "../types/question"
|
import type { QuestionRequest } from "../types/question"
|
||||||
import type { EventQuestionReplied, EventQuestionRejected } from "@opencode-ai/sdk/v2"
|
import type { EventQuestionReplied, EventQuestionRejected } from "@opencode-ai/sdk/v2"
|
||||||
import { showToastNotification, ToastVariant } from "../lib/notifications"
|
import { showToastNotification, type ToastHandle, ToastVariant } from "../lib/notifications"
|
||||||
import { sendOsNotification } from "../lib/os-notifications"
|
import { sendOsNotification } from "../lib/os-notifications"
|
||||||
import { preferences } from "./preferences"
|
import { preferences } from "./preferences"
|
||||||
import {
|
import {
|
||||||
@@ -39,7 +39,14 @@ import {
|
|||||||
removeQuestionFromQueue,
|
removeQuestionFromQueue,
|
||||||
} from "./instances"
|
} from "./instances"
|
||||||
import { showAlertDialog } from "./alerts"
|
import { showAlertDialog } from "./alerts"
|
||||||
import { createClientSession, mapSdkSessionStatus, type Session, type SessionStatus } from "../types/session"
|
import {
|
||||||
|
createClientSession,
|
||||||
|
mapSdkSessionRetry,
|
||||||
|
mapSdkSessionStatus,
|
||||||
|
type Session,
|
||||||
|
type SessionRetryState,
|
||||||
|
type SessionStatus,
|
||||||
|
} from "../types/session"
|
||||||
import { ensureSessionParentExpanded, sessions, setSessions, syncInstanceSessionIndicator, withSession } from "./session-state"
|
import { ensureSessionParentExpanded, sessions, setSessions, syncInstanceSessionIndicator, withSession } from "./session-state"
|
||||||
import { normalizeMessagePart } from "./message-v2/normalizers"
|
import { normalizeMessagePart } from "./message-v2/normalizers"
|
||||||
import { updateSessionInfo } from "./message-v2/session-info"
|
import { updateSessionInfo } from "./message-v2/session-info"
|
||||||
@@ -67,6 +74,15 @@ import { handleConversationAssistantPartUpdated } from "./conversation-speech"
|
|||||||
|
|
||||||
const log = getLogger("sse")
|
const log = getLogger("sse")
|
||||||
const pendingSessionFetches = new Map<string, Promise<void>>()
|
const pendingSessionFetches = new Map<string, Promise<void>>()
|
||||||
|
let activeRetryToast: ToastHandle | null = null
|
||||||
|
|
||||||
|
function isSameRetryState(left: SessionRetryState | null | undefined, right: SessionRetryState | null | undefined): boolean {
|
||||||
|
const a = left ?? null
|
||||||
|
const b = right ?? null
|
||||||
|
if (a === b) return true
|
||||||
|
if (!a || !b) return false
|
||||||
|
return a.attempt === b.attempt && a.message === b.message && a.next === b.next
|
||||||
|
}
|
||||||
|
|
||||||
function shouldSendOsNotification(kind: "needsInput" | "idle"): boolean {
|
function shouldSendOsNotification(kind: "needsInput" | "idle"): boolean {
|
||||||
if (typeof document === "undefined") return false
|
if (typeof document === "undefined") return false
|
||||||
@@ -131,18 +147,20 @@ interface TuiToastEvent {
|
|||||||
|
|
||||||
const ALLOWED_TOAST_VARIANTS = new Set<ToastVariant>(["info", "success", "warning", "error"])
|
const ALLOWED_TOAST_VARIANTS = new Set<ToastVariant>(["info", "success", "warning", "error"])
|
||||||
|
|
||||||
function applySessionStatus(instanceId: string, sessionId: string, status: SessionStatus) {
|
function applySessionStatus(instanceId: string, sessionId: string, status: SessionStatus, retry?: SessionRetryState | null) {
|
||||||
let parentToExpand: string | null = null
|
let parentToExpand: string | null = null
|
||||||
|
|
||||||
withSession(instanceId, sessionId, (session) => {
|
withSession(instanceId, sessionId, (session) => {
|
||||||
const current = session.status ?? "idle"
|
const current = session.status ?? "idle"
|
||||||
if (current === status) return false
|
const nextRetry = retry ?? null
|
||||||
|
if (current === status && isSameRetryState(session.retry, nextRetry)) return false
|
||||||
|
|
||||||
if (current === "compacting" && status !== "compacting") {
|
if (current === "compacting" && status !== "compacting") {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
session.status = status
|
session.status = status
|
||||||
|
session.retry = status === "working" ? nextRetry : null
|
||||||
|
|
||||||
// Auto-expand the parent thread when a child session starts working.
|
// Auto-expand the parent thread when a child session starts working.
|
||||||
// Users can still collapse it; we only expand on the transition.
|
// Users can still collapse it; we only expand on the transition.
|
||||||
@@ -172,6 +190,7 @@ async function fetchSessionInfo(instanceId: string, sessionId: string, directory
|
|||||||
)
|
)
|
||||||
|
|
||||||
let fetchedStatus: SessionStatus = "idle"
|
let fetchedStatus: SessionStatus = "idle"
|
||||||
|
let fetchedRetry: SessionRetryState | null = null
|
||||||
try {
|
try {
|
||||||
let statuses: Record<string, any> = {}
|
let statuses: Record<string, any> = {}
|
||||||
try {
|
try {
|
||||||
@@ -187,11 +206,13 @@ async function fetchSessionInfo(instanceId: string, sessionId: string, directory
|
|||||||
const rawStatus = (info as any)?.status ?? statuses?.[sessionId]
|
const rawStatus = (info as any)?.status ?? statuses?.[sessionId]
|
||||||
const hasType = rawStatus && typeof rawStatus === "object" && typeof rawStatus.type === "string"
|
const hasType = rawStatus && typeof rawStatus === "object" && typeof rawStatus.type === "string"
|
||||||
fetchedStatus = hasType ? mapSdkSessionStatus(rawStatus) : "idle"
|
fetchedStatus = hasType ? mapSdkSessionStatus(rawStatus) : "idle"
|
||||||
|
fetchedRetry = hasType ? mapSdkSessionRetry(rawStatus) : null
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error("Failed to fetch session status", error)
|
log.error("Failed to fetch session status", error)
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetched = createClientSession(info, instanceId, "", { providerId: "", modelId: "" }, fetchedStatus)
|
const fetched = createClientSession(info, instanceId, "", { providerId: "", modelId: "" }, fetchedStatus)
|
||||||
|
fetched.retry = fetchedRetry
|
||||||
|
|
||||||
let updatedInstanceSessions: Map<string, Session> | undefined
|
let updatedInstanceSessions: Map<string, Session> | undefined
|
||||||
let shouldExpandParent: string | null = null
|
let shouldExpandParent: string | null = null
|
||||||
@@ -205,6 +226,7 @@ async function fetchSessionInfo(instanceId: string, sessionId: string, directory
|
|||||||
agent: existing?.agent ?? fetched.agent,
|
agent: existing?.agent ?? fetched.agent,
|
||||||
model: existing?.model ?? fetched.model,
|
model: existing?.model ?? fetched.model,
|
||||||
status: existing?.status === "compacting" ? "compacting" : fetched.status,
|
status: existing?.status === "compacting" ? "compacting" : fetched.status,
|
||||||
|
retry: existing?.status === "compacting" ? null : fetched.retry,
|
||||||
pendingPermission: existing?.pendingPermission ?? fetched.pendingPermission,
|
pendingPermission: existing?.pendingPermission ?? fetched.pendingPermission,
|
||||||
pendingQuestion: existing?.pendingQuestion ?? false,
|
pendingQuestion: existing?.pendingQuestion ?? false,
|
||||||
}
|
}
|
||||||
@@ -231,14 +253,20 @@ async function fetchSessionInfo(instanceId: string, sessionId: string, directory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureSessionStatus(instanceId: string, sessionId: string, status: SessionStatus, directory?: string) {
|
function ensureSessionStatus(
|
||||||
|
instanceId: string,
|
||||||
|
sessionId: string,
|
||||||
|
status: SessionStatus,
|
||||||
|
directory?: string,
|
||||||
|
retry?: SessionRetryState | null,
|
||||||
|
) {
|
||||||
const instanceSessions = sessions().get(instanceId)
|
const instanceSessions = sessions().get(instanceId)
|
||||||
const existing = instanceSessions?.get(sessionId)
|
const existing = instanceSessions?.get(sessionId)
|
||||||
if (existing) {
|
if (existing) {
|
||||||
if ((existing.status ?? "idle") === status) {
|
if ((existing.status ?? "idle") === status && isSameRetryState(existing.retry, retry)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
applySessionStatus(instanceId, sessionId, status)
|
applySessionStatus(instanceId, sessionId, status, retry)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +278,7 @@ function ensureSessionStatus(instanceId: string, sessionId: string, status: Sess
|
|||||||
const pending = (async () => {
|
const pending = (async () => {
|
||||||
const fetched = await fetchSessionInfo(instanceId, sessionId, directory)
|
const fetched = await fetchSessionInfo(instanceId, sessionId, directory)
|
||||||
if (!fetched) return
|
if (!fetched) return
|
||||||
applySessionStatus(instanceId, sessionId, status)
|
applySessionStatus(instanceId, sessionId, status, retry)
|
||||||
})()
|
})()
|
||||||
|
|
||||||
pendingSessionFetches.set(key, pending)
|
pendingSessionFetches.set(key, pending)
|
||||||
@@ -428,6 +456,7 @@ function handleSessionUpdate(instanceId: string, event: EventSessionUpdated): vo
|
|||||||
modelId: "",
|
modelId: "",
|
||||||
},
|
},
|
||||||
status: "idle",
|
status: "idle",
|
||||||
|
retry: null,
|
||||||
version: info.version || "0",
|
version: info.version || "0",
|
||||||
time: info.time
|
time: info.time
|
||||||
? { ...info.time }
|
? { ...info.time }
|
||||||
@@ -461,6 +490,7 @@ function handleSessionUpdate(instanceId: string, event: EventSessionUpdated): vo
|
|||||||
...existingSession,
|
...existingSession,
|
||||||
title: info.title || existingSession.title,
|
title: info.title || existingSession.title,
|
||||||
status: existingSession.status ?? "idle",
|
status: existingSession.status ?? "idle",
|
||||||
|
retry: existingSession.retry ?? null,
|
||||||
time: mergedTime,
|
time: mergedTime,
|
||||||
revert: info.revert
|
revert: info.revert
|
||||||
? {
|
? {
|
||||||
@@ -532,8 +562,29 @@ function handleSessionStatus(instanceId: string, event: EventSessionStatus): voi
|
|||||||
const sessionId = event.properties?.sessionID
|
const sessionId = event.properties?.sessionID
|
||||||
if (!sessionId) return
|
if (!sessionId) return
|
||||||
|
|
||||||
const status = mapSdkSessionStatus(event.properties.status)
|
const rawStatus = event.properties.status
|
||||||
ensureSessionStatus(instanceId, sessionId, status, (event as any)?.directory)
|
const status = mapSdkSessionStatus(rawStatus)
|
||||||
|
const retry = mapSdkSessionRetry(rawStatus)
|
||||||
|
ensureSessionStatus(instanceId, sessionId, status, (event as any)?.directory, retry)
|
||||||
|
if (retry) {
|
||||||
|
const remainingSeconds = Math.max(0, Math.round((retry.next - Date.now()) / 1000))
|
||||||
|
const countdown =
|
||||||
|
remainingSeconds > 0
|
||||||
|
? tGlobal("sessionList.status.retryingIn", { seconds: String(remainingSeconds) })
|
||||||
|
: tGlobal("sessionList.status.retrying")
|
||||||
|
const label = getSessionTitle(instanceId, sessionId)
|
||||||
|
activeRetryToast?.dismiss()
|
||||||
|
activeRetryToast = showToastNotification({
|
||||||
|
title: label || getInstanceDisplayName(instanceId),
|
||||||
|
message: tGlobal("sessionList.status.retryToast", {
|
||||||
|
countdown,
|
||||||
|
message: retry.message,
|
||||||
|
attempt: String(retry.attempt),
|
||||||
|
}),
|
||||||
|
variant: "error",
|
||||||
|
duration: 7000,
|
||||||
|
})
|
||||||
|
}
|
||||||
log.info(`[SSE] Session status updated: ${sessionId}`, { status })
|
log.info(`[SSE] Session status updated: ${sessionId}`, { status })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,6 +598,7 @@ function handleSessionCompacted(instanceId: string, event: EventSessionCompacted
|
|||||||
if (existing) {
|
if (existing) {
|
||||||
withSession(instanceId, sessionID, (session) => {
|
withSession(instanceId, sessionID, (session) => {
|
||||||
session.status = "working"
|
session.status = "working"
|
||||||
|
session.retry = null
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
ensureSessionStatus(instanceId, sessionID, "working", (event as any)?.directory)
|
ensureSessionStatus(instanceId, sessionID, "working", (event as any)?.directory)
|
||||||
|
|||||||
@@ -353,6 +353,9 @@ function setSessionStatus(instanceId: string, sessionId: string, status: Session
|
|||||||
if (session.status === status) return false
|
if (session.status === status) return false
|
||||||
const previous = session.status
|
const previous = session.status
|
||||||
session.status = status
|
session.status = status
|
||||||
|
if (status !== "working") {
|
||||||
|
session.retry = null
|
||||||
|
}
|
||||||
|
|
||||||
// If a child session starts working, auto-expand its parent thread once.
|
// If a child session starts working, auto-expand its parent thread once.
|
||||||
// Users can still collapse it afterwards; we only expand on the transition.
|
// Users can still collapse it afterwards; we only expand on the transition.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Session, SessionStatus } from "../types/session"
|
import type { Session, SessionRetryState, SessionStatus } from "../types/session"
|
||||||
import { getInstanceSessionIndicatorStatusCached, sessions } from "./session-state"
|
import { getInstanceSessionIndicatorStatusCached, sessions } from "./session-state"
|
||||||
|
|
||||||
function getSession(instanceId: string, sessionId: string): Session | null {
|
function getSession(instanceId: string, sessionId: string): Session | null {
|
||||||
@@ -14,6 +14,15 @@ export function getSessionStatus(instanceId: string, sessionId: string): Session
|
|||||||
return session.status ?? "idle"
|
return session.status ?? "idle"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getSessionRetry(instanceId: string, sessionId: string): SessionRetryState | null {
|
||||||
|
const session = getSession(instanceId, sessionId)
|
||||||
|
return session?.retry ?? null
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRetrySeconds(next: number, now = Date.now()): number {
|
||||||
|
return Math.max(0, Math.round((next - now) / 1000))
|
||||||
|
}
|
||||||
|
|
||||||
export type InstanceSessionIndicatorStatus = "permission" | SessionStatus
|
export type InstanceSessionIndicatorStatus = "permission" | SessionStatus
|
||||||
|
|
||||||
export function getInstanceSessionIndicatorStatus(instanceId: string): InstanceSessionIndicatorStatus {
|
export function getInstanceSessionIndicatorStatus(instanceId: string): InstanceSessionIndicatorStatus {
|
||||||
|
|||||||
@@ -184,6 +184,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.status-indicator.session-status.session-working,
|
.status-indicator.session-status.session-working,
|
||||||
|
.status-indicator.session-status.session-retrying,
|
||||||
.status-indicator.session-status.session-compacting,
|
.status-indicator.session-status.session-compacting,
|
||||||
.status-indicator.session-status.session-idle {
|
.status-indicator.session-status.session-idle {
|
||||||
font-weight: var(--font-weight-medium);
|
font-weight: var(--font-weight-medium);
|
||||||
@@ -194,6 +195,11 @@
|
|||||||
--session-status-dot: var(--session-status-working-fg);
|
--session-status-dot: var(--session-status-working-fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status-indicator.session-status.session-retrying {
|
||||||
|
color: var(--status-error);
|
||||||
|
--session-status-dot: var(--status-error);
|
||||||
|
}
|
||||||
|
|
||||||
.status-indicator.session-status.session-compacting {
|
.status-indicator.session-status.session-compacting {
|
||||||
color: var(--session-status-compacting-fg);
|
color: var(--session-status-compacting-fg);
|
||||||
--session-status-dot: var(--session-status-compacting-fg);
|
--session-status-dot: var(--session-status-compacting-fg);
|
||||||
@@ -222,6 +228,10 @@
|
|||||||
background-color: var(--session-status-working-bg);
|
background-color: var(--session-status-working-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status-indicator.session-status.session-retrying.session-status-list {
|
||||||
|
background-color: var(--status-error-bg);
|
||||||
|
}
|
||||||
|
|
||||||
.status-indicator.session-status.session-compacting.session-status-list {
|
.status-indicator.session-status.session-compacting.session-status-list {
|
||||||
background-color: var(--session-status-compacting-bg);
|
background-color: var(--session-status-compacting-bg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -416,6 +416,7 @@ session-sidebar-controls .selector-trigger-primary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.status-indicator.session-status.session-working,
|
.status-indicator.session-status.session-working,
|
||||||
|
.status-indicator.session-status.session-retrying,
|
||||||
.status-indicator.session-status.session-compacting,
|
.status-indicator.session-status.session-compacting,
|
||||||
.status-indicator.session-status.session-idle {
|
.status-indicator.session-status.session-idle {
|
||||||
font-weight: var(--font-weight-medium);
|
font-weight: var(--font-weight-medium);
|
||||||
@@ -426,6 +427,11 @@ session-sidebar-controls .selector-trigger-primary {
|
|||||||
--session-status-dot: var(--session-status-working-fg);
|
--session-status-dot: var(--session-status-working-fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status-indicator.session-status.session-retrying {
|
||||||
|
color: var(--status-error);
|
||||||
|
--session-status-dot: var(--status-error);
|
||||||
|
}
|
||||||
|
|
||||||
.status-indicator.session-status.session-compacting {
|
.status-indicator.session-status.session-compacting {
|
||||||
color: var(--session-status-compacting-fg);
|
color: var(--session-status-compacting-fg);
|
||||||
--session-status-dot: var(--session-status-compacting-fg);
|
--session-status-dot: var(--session-status-compacting-fg);
|
||||||
@@ -454,6 +460,10 @@ session-sidebar-controls .selector-trigger-primary {
|
|||||||
background-color: var(--session-status-working-bg);
|
background-color: var(--session-status-working-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status-indicator.session-status.session-retrying.session-status-list {
|
||||||
|
background-color: var(--status-error-bg);
|
||||||
|
}
|
||||||
|
|
||||||
.status-indicator.session-status.session-compacting.session-status-list {
|
.status-indicator.session-status.session-compacting.session-status-list {
|
||||||
background-color: var(--session-status-compacting-bg);
|
background-color: var(--session-status-compacting-bg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,12 @@ export type {
|
|||||||
|
|
||||||
export type SessionStatus = "idle" | "working" | "compacting"
|
export type SessionStatus = "idle" | "working" | "compacting"
|
||||||
|
|
||||||
|
export interface SessionRetryState {
|
||||||
|
attempt: number
|
||||||
|
message: string
|
||||||
|
next: number
|
||||||
|
}
|
||||||
|
|
||||||
export function mapSdkSessionStatus(status: SDKSessionStatus | null | undefined): SessionStatus {
|
export function mapSdkSessionStatus(status: SDKSessionStatus | null | undefined): SessionStatus {
|
||||||
if (!status || status.type === "idle") {
|
if (!status || status.type === "idle") {
|
||||||
return "idle"
|
return "idle"
|
||||||
@@ -26,6 +32,18 @@ export function mapSdkSessionStatus(status: SDKSessionStatus | null | undefined)
|
|||||||
return "working"
|
return "working"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function mapSdkSessionRetry(status: SDKSessionStatus | null | undefined): SessionRetryState | null {
|
||||||
|
if (!status || status.type !== "retry") {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
attempt: typeof status.attempt === "number" ? status.attempt : 1,
|
||||||
|
message: typeof status.message === "string" ? status.message : "",
|
||||||
|
next: typeof status.next === "number" ? status.next : Date.now(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Our client-specific Session interface extending SDK Session
|
// Our client-specific Session interface extending SDK Session
|
||||||
export interface Session
|
export interface Session
|
||||||
extends Omit<import("@opencode-ai/sdk").Session, "projectID" | "directory" | "parentID"> {
|
extends Omit<import("@opencode-ai/sdk").Session, "projectID" | "directory" | "parentID"> {
|
||||||
@@ -40,6 +58,7 @@ export interface Session
|
|||||||
pendingPermission?: boolean // Indicates if session is waiting on user permission
|
pendingPermission?: boolean // Indicates if session is waiting on user permission
|
||||||
pendingQuestion?: boolean // Indicates if session is waiting on user input
|
pendingQuestion?: boolean // Indicates if session is waiting on user input
|
||||||
status: SessionStatus // Single source of truth for session status
|
status: SessionStatus // Single source of truth for session status
|
||||||
|
retry?: SessionRetryState | null // Retry metadata for transient backoff states
|
||||||
diff?: FileDiff[] // Session-level file diffs (hydrated via session.diff)
|
diff?: FileDiff[] // Session-level file diffs (hydrated via session.diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
40
scripts/bump-version.js
Normal file
40
scripts/bump-version.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const { spawnSync } = require("child_process")
|
||||||
|
|
||||||
|
const versionArgs = process.argv.slice(2)
|
||||||
|
|
||||||
|
if (versionArgs.length === 0) {
|
||||||
|
console.error("[bumpVersion] missing version argument (example: npm run bumpVersion -- patch)")
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const npmCommand = process.platform === "win32" ? "npm.cmd" : "npm"
|
||||||
|
|
||||||
|
function runStep(args, label) {
|
||||||
|
const result = spawnSync(npmCommand, args, {
|
||||||
|
stdio: "inherit",
|
||||||
|
})
|
||||||
|
|
||||||
|
if (result.error) {
|
||||||
|
console.error(`[bumpVersion] failed during ${label}: ${result.error.message}`)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.status !== 0) {
|
||||||
|
process.exit(result.status ?? 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runStep(
|
||||||
|
[
|
||||||
|
"version",
|
||||||
|
...versionArgs,
|
||||||
|
"--workspaces",
|
||||||
|
"--include-workspace-root",
|
||||||
|
"--no-git-tag-version",
|
||||||
|
],
|
||||||
|
"npm version"
|
||||||
|
)
|
||||||
|
|
||||||
|
runStep(["run", "sync:version", "--workspace", "@codenomad/tauri-app"], "tauri version sync")
|
||||||
Reference in New Issue
Block a user