@shawnstack/quickforge 1.5.0 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/dist/assets/AgentProfilesPage-DKyIh3dE.js +1 -0
- package/dist/assets/ChatPanelHost-BUZ6scv9.js +242 -0
- package/dist/assets/{PluginsPage-kiBq0gOT.js → PluginsPage-CN-SFQ_s.js} +1 -1
- package/dist/assets/ScheduledTasksPage-C0htXZk2.js +2 -0
- package/dist/assets/SharedConversationPage-CxbAx1fN.js +1 -0
- package/dist/assets/TerminalDock-_voUf7d-.js +2 -0
- package/dist/assets/WorkspaceInspector-Ci4FuaZH.js +3 -0
- package/dist/assets/{WorkspaceReaderDialog-BJo_KEWi.js → WorkspaceReaderDialog-D75__GFg.js} +1 -1
- package/dist/assets/diff-line-counts-DHyWKEXk.js +10 -0
- package/dist/assets/icons-DzxBk7tb.js +1 -0
- package/dist/assets/index-BI7xZuj-.css +3 -0
- package/dist/assets/index-BzOV50wA.js +1442 -0
- package/dist/assets/{monaco-CGq6uVF1.js → monaco-dMY7_GLO.js} +1 -1
- package/dist/assets/{react-vendor-DunfCFfp.js → react-vendor-DsAeMFcm.js} +1 -1
- package/dist/index.html +4 -4
- package/package.json +1 -1
- package/server/acp/server.mjs +1 -0
- package/server/agent-manager.mjs +8 -8
- package/server/agent-profile-files.mjs +2 -1
- package/server/channels/process-channel.mjs +1 -0
- package/server/channels/providers/wechat.mjs +1 -0
- package/server/custom-commands.mjs +4 -3
- package/server/plugins/registry.mjs +1 -1
- package/server/project-config.mjs +2 -2
- package/server/routes/agent.mjs +0 -1
- package/server/routes/project.mjs +3 -2
- package/server/routes/scheduled-tasks.mjs +13 -121
- package/server/routes/static.mjs +1 -1
- package/server/routes/storage.mjs +13 -7
- package/server/routes/workspace.mjs +8 -24
- package/server/session-utils.mjs +2 -1
- package/server/skills.mjs +3 -2
- package/server/storage.mjs +0 -1
- package/server/tools/index.mjs +5 -2
- package/server/utils/logger.mjs +0 -1
- package/server/utils/package-update.mjs +2 -2
- package/server/utils/scheduled-tasks.mjs +127 -0
- package/server/utils/workspace.mjs +1 -1
- package/dist/assets/AgentProfilesPage-DUmXUxjA.js +0 -1
- package/dist/assets/ChatPanelHost-Syx0SSLe.js +0 -242
- package/dist/assets/ScheduledTasksPage-Dw4-tgp9.js +0 -2
- package/dist/assets/SharedConversationPage-CaE9bNb9.js +0 -1
- package/dist/assets/TerminalDock-BYJcp8Ts.js +0 -2
- package/dist/assets/WorkspaceInspector-Bzmv8Cvi.js +0 -3
- package/dist/assets/diff-line-counts-BZoYp5ai.js +0 -10
- package/dist/assets/icons-47L5YLKz.js +0 -1
- package/dist/assets/index-CqfScETb.js +0 -1200
- package/dist/assets/index-DzkBgHZf.css +0 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{
|
|
1
|
+
import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{wt as t}from"./icons-DzxBk7tb.js";function n(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function r(e){if(Array.isArray(e))return e}function i(e,t,n){return(t=p(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=e==null?null:typeof Symbol<`u`&&e[Symbol.iterator]||e[`@@iterator`];if(n!=null){var r,i,a,o,s=[],c=!0,l=!1;try{if(a=(n=n.call(e)).next,t!==0)for(;!(c=(r=a.call(n)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(e){l=!0,i=e}finally{try{if(!c&&n.return!=null&&(o=n.return(),Object(o)!==o))return}finally{if(l)throw i}}return s}}function o(){throw TypeError(`Invalid attempt to destructure non-iterable instance.
|
|
2
2
|
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?s(Object(n),!0).forEach(function(t){i(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function l(e,t){if(e==null)return{};var n,r,i=u(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function u(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function d(e,t){return r(e)||a(e,t)||m(e,t)||o()}function f(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function p(e){var t=f(e,`string`);return typeof t==`symbol`?t:t+``}function m(e,t){if(e){if(typeof e==`string`)return n(e,t);var r={}.toString.call(e).slice(8,-1);return r===`Object`&&e.constructor&&(r=e.constructor.name),r===`Map`||r===`Set`?Array.from(e):r===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?n(e,t):void 0}}function h(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function g(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function _(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?g(Object(n),!0).forEach(function(t){h(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):g(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function v(){var e=[...arguments];return function(t){return e.reduceRight(function(e,t){return t(e)},t)}}function y(e){return function t(){var n=this,r=[...arguments];return r.length>=e.length?e.apply(this,r):function(){var e=[...arguments];return t.apply(n,[].concat(r,e))}}}function b(e){return{}.toString.call(e).includes(`Object`)}function x(e){return!Object.keys(e).length}function S(e){return typeof e==`function`}function C(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function w(e,t){return b(t)||k(`changeType`),Object.keys(t).some(function(t){return!C(e,t)})&&k(`changeField`),t}function T(e){S(e)||k(`selectorType`)}function E(e){S(e)||b(e)||k(`handlerType`),b(e)&&Object.values(e).some(function(e){return!S(e)})&&k(`handlersType`)}function D(e){e||k(`initialIsRequired`),b(e)||k(`initialType`),x(e)&&k(`initialContent`)}function O(e,t){throw Error(e[t]||e.default)}var k=y(O)({initialIsRequired:`initial state is required`,initialType:`initial state should be an object`,initialContent:`initial state shouldn't be an empty object`,handlerType:`handler should be an object or a function`,handlersType:`all handlers should be a functions`,selectorType:`selector should be a function`,changeType:`provided value of changes should be an object`,changeField:`it seams you want to change a field in the state which is not specified in the "initial" state`,default:"an unknown error accured in `state-local` package"}),A={changes:w,selector:T,handler:E,initial:D};function j(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};A.initial(e),A.handler(t);var n={current:e},r=y(P)(n,t),i=y(N)(n),a=y(A.changes)(e),o=y(M)(n);function s(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:function(e){return e};return A.selector(e),e(n.current)}function c(e){v(r,i,a,o)(e)}return[s,c]}function M(e,t){return S(t)?t(e.current):t}function N(e,t){return e.current=_(_({},e.current),t),t}function P(e,t,n){return S(t)?t(e.current):Object.keys(n).forEach(function(n){return t[n]?.call(t,e.current[n])}),n}var F={create:j},I={paths:{vs:`https://cdn.jsdelivr.net/npm/monaco-editor@0.55.1/min/vs`}};function ee(e){return function t(){var n=this,r=[...arguments];return r.length>=e.length?e.apply(this,r):function(){var e=[...arguments];return t.apply(n,[].concat(r,e))}}}function te(e){return{}.toString.call(e).includes(`Object`)}function ne(e){return e||R(`configIsRequired`),te(e)||R(`configType`),e.urls?(re(),{paths:{vs:e.urls.monacoBase}}):e}function re(){console.warn(L.deprecation)}function ie(e,t){throw Error(e[t]||e.default)}var L={configIsRequired:`the configuration object is required`,configType:`the configuration object should be an object`,default:"an unknown error accured in `@monaco-editor/loader` package",deprecation:`Deprecation warning!
|
|
3
3
|
You are using deprecated way of configuration.
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime-DWdDZTNf.js";import{St as t}from"./icons-47L5YLKz.js";var n=e((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0<n;){var r=n-1>>>1,a=e[r];if(0<i(a,t))e[r]=t,e[n]=a,n=r;else break a}}function n(e){return e.length===0?null:e[0]}function r(e){if(e.length===0)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;a:for(var r=0,a=e.length,o=a>>>1;r<o;){var s=2*(r+1)-1,c=e[s],l=s+1,u=e[l];if(0>i(c,n))l<a&&0>i(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(l<a&&0>i(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,S||(S=!0,D());else{var t=n(l);t!==null&&A(x,t.startTime-e)}}var S=!1,C=-1,ee=5,w=-1;function T(){return g?!0:!(e.unstable_now()-w<ee)}function E(){if(g=!1,S){var t=e.unstable_now();w=t;var i=!0;try{a:{m=!1,h&&(h=!1,v(C),C=-1),p=!0;var a=f;try{b:{for(b(t),d=n(c);d!==null&&!(d.expirationTime>t&&T());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&A(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?D():S=!1}}}var D;if(typeof y==`function`)D=function(){y(E)};else if(typeof MessageChannel<`u`){var O=new MessageChannel,k=O.port2;O.port1.onmessage=E,D=function(){k.postMessage(null)}}else D=function(){_(E,0)};function A(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125<e?console.error(`forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported`):ee=0<e?Math.floor(1e3/e):5},e.unstable_getCurrentPriorityLevel=function(){return f},e.unstable_next=function(e){switch(f){case 1:case 2:case 3:var t=3;break;default:t=f}var n=f;f=t;try{return e()}finally{f=n}},e.unstable_requestPaint=function(){g=!0},e.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=f;f=e;try{return t()}finally{f=n}},e.unstable_scheduleCallback=function(r,i,a){var o=e.unstable_now();switch(typeof a==`object`&&a?(a=a.delay,a=typeof a==`number`&&0<a?o+a:o):a=o,r){case 1:var s=-1;break;case 2:s=250;break;case 5:s=1073741823;break;case 4:s=1e4;break;default:s=5e3}return s=a+s,r={id:u++,callback:i,priorityLevel:r,startTime:a,expirationTime:s,sortIndex:-1},a>o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,A(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,D()))),r},e.unstable_shouldYield=T,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),r=e(((e,t)=>{t.exports=n()})),i=e((e=>{var n=t();function r(e){var t=`https://react.dev/errors/`+e;if(1<arguments.length){t+=`?args[]=`+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+=`&args[]=`+encodeURIComponent(arguments[n])}return`Minified React error #`+e+`; visit `+t+` for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`}function i(){}var a={d:{f:i,r:function(){throw Error(r(522))},D:i,C:i,L:i,m:i,X:i,S:i,M:i},p:0,findDOMNode:null},o=Symbol.for(`react.portal`);function s(e,t,n){var r=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:o,key:r==null?null:``+r,children:e,containerInfo:t,implementation:n}}var c=n.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;function l(e,t){if(e===`font`)return``;if(typeof t==`string`)return t===`use-credentials`?t:``}e.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=a,e.createPortal=function(e,t){var n=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!t||t.nodeType!==1&&t.nodeType!==9&&t.nodeType!==11)throw Error(r(299));return s(e,t,null,n)},e.flushSync=function(e){var t=c.T,n=a.p;try{if(c.T=null,a.p=2,e)return e()}finally{c.T=t,a.p=n,a.d.f()}},e.preconnect=function(e,t){typeof e==`string`&&(t?(t=t.crossOrigin,t=typeof t==`string`?t===`use-credentials`?t:``:void 0):t=null,a.d.C(e,t))},e.prefetchDNS=function(e){typeof e==`string`&&a.d.D(e)},e.preinit=function(e,t){if(typeof e==`string`&&t&&typeof t.as==`string`){var n=t.as,r=l(n,t.crossOrigin),i=typeof t.integrity==`string`?t.integrity:void 0,o=typeof t.fetchPriority==`string`?t.fetchPriority:void 0;n===`style`?a.d.S(e,typeof t.precedence==`string`?t.precedence:void 0,{crossOrigin:r,integrity:i,fetchPriority:o}):n===`script`&&a.d.X(e,{crossOrigin:r,integrity:i,fetchPriority:o,nonce:typeof t.nonce==`string`?t.nonce:void 0})}},e.preinitModule=function(e,t){if(typeof e==`string`)if(typeof t==`object`&&t){if(t.as==null||t.as===`script`){var n=l(t.as,t.crossOrigin);a.d.M(e,{crossOrigin:n,integrity:typeof t.integrity==`string`?t.integrity:void 0,nonce:typeof t.nonce==`string`?t.nonce:void 0})}}else t??a.d.M(e)},e.preload=function(e,t){if(typeof e==`string`&&typeof t==`object`&&t&&typeof t.as==`string`){var n=t.as,r=l(n,t.crossOrigin);a.d.L(e,n,{crossOrigin:r,integrity:typeof t.integrity==`string`?t.integrity:void 0,nonce:typeof t.nonce==`string`?t.nonce:void 0,type:typeof t.type==`string`?t.type:void 0,fetchPriority:typeof t.fetchPriority==`string`?t.fetchPriority:void 0,referrerPolicy:typeof t.referrerPolicy==`string`?t.referrerPolicy:void 0,imageSrcSet:typeof t.imageSrcSet==`string`?t.imageSrcSet:void 0,imageSizes:typeof t.imageSizes==`string`?t.imageSizes:void 0,media:typeof t.media==`string`?t.media:void 0})}},e.preloadModule=function(e,t){if(typeof e==`string`)if(t){var n=l(t.as,t.crossOrigin);a.d.m(e,{as:typeof t.as==`string`&&t.as!==`script`?t.as:void 0,crossOrigin:n,integrity:typeof t.integrity==`string`?t.integrity:void 0})}else a.d.m(e)},e.requestFormReset=function(e){a.d.r(e)},e.unstable_batchedUpdates=function(e,t){return e(t)},e.useFormState=function(e,t,n){return c.H.useFormState(e,t,n)},e.useFormStatus=function(){return c.H.useHostTransitionStatus()},e.version=`19.2.5`})),a=e(((e,t)=>{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=i()})),o=e((e=>{var n=r(),i=t(),o=a();function s(e){var t=`https://react.dev/errors/`+e;if(1<arguments.length){t+=`?args[]=`+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+=`&args[]=`+encodeURIComponent(arguments[n])}return`Minified React error #`+e+`; visit `+t+` for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`}function c(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11)}function l(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do t=e,t.flags&4098&&(n=t.return),e=t.return;while(e)}return t.tag===3?n:null}function u(e){if(e.tag===13){var t=e.memoizedState;if(t===null&&(e=e.alternate,e!==null&&(t=e.memoizedState)),t!==null)return t.dehydrated}return null}function d(e){if(e.tag===31){var t=e.memoizedState;if(t===null&&(e=e.alternate,e!==null&&(t=e.memoizedState)),t!==null)return t.dehydrated}return null}function f(e){if(l(e)!==e)throw Error(s(188))}function p(e){var t=e.alternate;if(!t){if(t=l(e),t===null)throw Error(s(188));return t===e?e:null}for(var n=e,r=t;;){var i=n.return;if(i===null)break;var a=i.alternate;if(a===null){if(r=i.return,r!==null){n=r;continue}break}if(i.child===a.child){for(a=i.child;a;){if(a===n)return f(i),e;if(a===r)return f(i),t;a=a.sibling}throw Error(s(188))}if(n.return!==r.return)n=i,r=a;else{for(var o=!1,c=i.child;c;){if(c===n){o=!0,n=i,r=a;break}if(c===r){o=!0,r=i,n=a;break}c=c.sibling}if(!o){for(c=a.child;c;){if(c===n){o=!0,n=a,r=i;break}if(c===r){o=!0,r=a,n=i;break}c=c.sibling}if(!o)throw Error(s(189))}}if(n.alternate!==r)throw Error(s(190))}if(n.tag!==3)throw Error(s(188));return n.stateNode.current===n?e:t}function m(e){var t=e.tag;if(t===5||t===26||t===27||t===6)return e;for(e=e.child;e!==null;){if(t=m(e),t!==null)return t;e=e.sibling}return null}var h=Object.assign,g=Symbol.for(`react.element`),_=Symbol.for(`react.transitional.element`),v=Symbol.for(`react.portal`),y=Symbol.for(`react.fragment`),b=Symbol.for(`react.strict_mode`),x=Symbol.for(`react.profiler`),S=Symbol.for(`react.consumer`),C=Symbol.for(`react.context`),ee=Symbol.for(`react.forward_ref`),w=Symbol.for(`react.suspense`),T=Symbol.for(`react.suspense_list`),E=Symbol.for(`react.memo`),D=Symbol.for(`react.lazy`),O=Symbol.for(`react.activity`),k=Symbol.for(`react.memo_cache_sentinel`),A=Symbol.iterator;function te(e){return typeof e!=`object`||!e?null:(e=A&&e[A]||e[`@@iterator`],typeof e==`function`?e:null)}var j=Symbol.for(`react.client.reference`);function M(e){if(e==null)return null;if(typeof e==`function`)return e.$$typeof===j?null:e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case y:return`Fragment`;case x:return`Profiler`;case b:return`StrictMode`;case w:return`Suspense`;case T:return`SuspenseList`;case O:return`Activity`}if(typeof e==`object`)switch(e.$$typeof){case v:return`Portal`;case C:return e.displayName||`Context`;case S:return(e._context.displayName||`Context`)+`.Consumer`;case ee:var t=e.render;return e=e.displayName,e||=(e=t.displayName||t.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case E:return t=e.displayName||null,t===null?M(e.type)||`Memo`:t;case D:t=e._payload,e=e._init;try{return M(e(t))}catch{}}return null}var N=Array.isArray,P=i.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,F=o.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,ne={pending:!1,data:null,method:null,action:null},I=[],L=-1;function re(e){return{current:e}}function R(e){0>L||(e.current=I[L],I[L]=null,L--)}function z(e,t){L++,I[L]=e.current,e.current=t}var B=re(null),ie=re(null),ae=re(null),oe=re(null);function se(e,t){switch(z(ae,t),z(ie,e),z(B,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}R(B),z(B,e)}function ce(){R(B),R(ie),R(ae)}function V(e){e.memoizedState!==null&&z(oe,e);var t=B.current,n=Hd(t,e.type);t!==n&&(z(ie,e),z(B,n))}function le(e){ie.current===e&&(R(B),R(ie)),oe.current===e&&(R(oe),Qf._currentValue=ne)}var H,ue;function de(e){if(H===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);H=t&&t[1]||``,ue=-1<e.stack.indexOf(`
|
|
1
|
+
import{t as e}from"./rolldown-runtime-DWdDZTNf.js";import{wt as t}from"./icons-DzxBk7tb.js";var n=e((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0<n;){var r=n-1>>>1,a=e[r];if(0<i(a,t))e[r]=t,e[n]=a,n=r;else break a}}function n(e){return e.length===0?null:e[0]}function r(e){if(e.length===0)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;a:for(var r=0,a=e.length,o=a>>>1;r<o;){var s=2*(r+1)-1,c=e[s],l=s+1,u=e[l];if(0>i(c,n))l<a&&0>i(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(l<a&&0>i(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,S||(S=!0,D());else{var t=n(l);t!==null&&A(x,t.startTime-e)}}var S=!1,C=-1,ee=5,w=-1;function T(){return g?!0:!(e.unstable_now()-w<ee)}function E(){if(g=!1,S){var t=e.unstable_now();w=t;var i=!0;try{a:{m=!1,h&&(h=!1,v(C),C=-1),p=!0;var a=f;try{b:{for(b(t),d=n(c);d!==null&&!(d.expirationTime>t&&T());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&A(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?D():S=!1}}}var D;if(typeof y==`function`)D=function(){y(E)};else if(typeof MessageChannel<`u`){var O=new MessageChannel,k=O.port2;O.port1.onmessage=E,D=function(){k.postMessage(null)}}else D=function(){_(E,0)};function A(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125<e?console.error(`forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported`):ee=0<e?Math.floor(1e3/e):5},e.unstable_getCurrentPriorityLevel=function(){return f},e.unstable_next=function(e){switch(f){case 1:case 2:case 3:var t=3;break;default:t=f}var n=f;f=t;try{return e()}finally{f=n}},e.unstable_requestPaint=function(){g=!0},e.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=f;f=e;try{return t()}finally{f=n}},e.unstable_scheduleCallback=function(r,i,a){var o=e.unstable_now();switch(typeof a==`object`&&a?(a=a.delay,a=typeof a==`number`&&0<a?o+a:o):a=o,r){case 1:var s=-1;break;case 2:s=250;break;case 5:s=1073741823;break;case 4:s=1e4;break;default:s=5e3}return s=a+s,r={id:u++,callback:i,priorityLevel:r,startTime:a,expirationTime:s,sortIndex:-1},a>o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,A(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,D()))),r},e.unstable_shouldYield=T,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),r=e(((e,t)=>{t.exports=n()})),i=e((e=>{var n=t();function r(e){var t=`https://react.dev/errors/`+e;if(1<arguments.length){t+=`?args[]=`+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+=`&args[]=`+encodeURIComponent(arguments[n])}return`Minified React error #`+e+`; visit `+t+` for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`}function i(){}var a={d:{f:i,r:function(){throw Error(r(522))},D:i,C:i,L:i,m:i,X:i,S:i,M:i},p:0,findDOMNode:null},o=Symbol.for(`react.portal`);function s(e,t,n){var r=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:o,key:r==null?null:``+r,children:e,containerInfo:t,implementation:n}}var c=n.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;function l(e,t){if(e===`font`)return``;if(typeof t==`string`)return t===`use-credentials`?t:``}e.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=a,e.createPortal=function(e,t){var n=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!t||t.nodeType!==1&&t.nodeType!==9&&t.nodeType!==11)throw Error(r(299));return s(e,t,null,n)},e.flushSync=function(e){var t=c.T,n=a.p;try{if(c.T=null,a.p=2,e)return e()}finally{c.T=t,a.p=n,a.d.f()}},e.preconnect=function(e,t){typeof e==`string`&&(t?(t=t.crossOrigin,t=typeof t==`string`?t===`use-credentials`?t:``:void 0):t=null,a.d.C(e,t))},e.prefetchDNS=function(e){typeof e==`string`&&a.d.D(e)},e.preinit=function(e,t){if(typeof e==`string`&&t&&typeof t.as==`string`){var n=t.as,r=l(n,t.crossOrigin),i=typeof t.integrity==`string`?t.integrity:void 0,o=typeof t.fetchPriority==`string`?t.fetchPriority:void 0;n===`style`?a.d.S(e,typeof t.precedence==`string`?t.precedence:void 0,{crossOrigin:r,integrity:i,fetchPriority:o}):n===`script`&&a.d.X(e,{crossOrigin:r,integrity:i,fetchPriority:o,nonce:typeof t.nonce==`string`?t.nonce:void 0})}},e.preinitModule=function(e,t){if(typeof e==`string`)if(typeof t==`object`&&t){if(t.as==null||t.as===`script`){var n=l(t.as,t.crossOrigin);a.d.M(e,{crossOrigin:n,integrity:typeof t.integrity==`string`?t.integrity:void 0,nonce:typeof t.nonce==`string`?t.nonce:void 0})}}else t??a.d.M(e)},e.preload=function(e,t){if(typeof e==`string`&&typeof t==`object`&&t&&typeof t.as==`string`){var n=t.as,r=l(n,t.crossOrigin);a.d.L(e,n,{crossOrigin:r,integrity:typeof t.integrity==`string`?t.integrity:void 0,nonce:typeof t.nonce==`string`?t.nonce:void 0,type:typeof t.type==`string`?t.type:void 0,fetchPriority:typeof t.fetchPriority==`string`?t.fetchPriority:void 0,referrerPolicy:typeof t.referrerPolicy==`string`?t.referrerPolicy:void 0,imageSrcSet:typeof t.imageSrcSet==`string`?t.imageSrcSet:void 0,imageSizes:typeof t.imageSizes==`string`?t.imageSizes:void 0,media:typeof t.media==`string`?t.media:void 0})}},e.preloadModule=function(e,t){if(typeof e==`string`)if(t){var n=l(t.as,t.crossOrigin);a.d.m(e,{as:typeof t.as==`string`&&t.as!==`script`?t.as:void 0,crossOrigin:n,integrity:typeof t.integrity==`string`?t.integrity:void 0})}else a.d.m(e)},e.requestFormReset=function(e){a.d.r(e)},e.unstable_batchedUpdates=function(e,t){return e(t)},e.useFormState=function(e,t,n){return c.H.useFormState(e,t,n)},e.useFormStatus=function(){return c.H.useHostTransitionStatus()},e.version=`19.2.5`})),a=e(((e,t)=>{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=i()})),o=e((e=>{var n=r(),i=t(),o=a();function s(e){var t=`https://react.dev/errors/`+e;if(1<arguments.length){t+=`?args[]=`+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+=`&args[]=`+encodeURIComponent(arguments[n])}return`Minified React error #`+e+`; visit `+t+` for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`}function c(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11)}function l(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do t=e,t.flags&4098&&(n=t.return),e=t.return;while(e)}return t.tag===3?n:null}function u(e){if(e.tag===13){var t=e.memoizedState;if(t===null&&(e=e.alternate,e!==null&&(t=e.memoizedState)),t!==null)return t.dehydrated}return null}function d(e){if(e.tag===31){var t=e.memoizedState;if(t===null&&(e=e.alternate,e!==null&&(t=e.memoizedState)),t!==null)return t.dehydrated}return null}function f(e){if(l(e)!==e)throw Error(s(188))}function p(e){var t=e.alternate;if(!t){if(t=l(e),t===null)throw Error(s(188));return t===e?e:null}for(var n=e,r=t;;){var i=n.return;if(i===null)break;var a=i.alternate;if(a===null){if(r=i.return,r!==null){n=r;continue}break}if(i.child===a.child){for(a=i.child;a;){if(a===n)return f(i),e;if(a===r)return f(i),t;a=a.sibling}throw Error(s(188))}if(n.return!==r.return)n=i,r=a;else{for(var o=!1,c=i.child;c;){if(c===n){o=!0,n=i,r=a;break}if(c===r){o=!0,r=i,n=a;break}c=c.sibling}if(!o){for(c=a.child;c;){if(c===n){o=!0,n=a,r=i;break}if(c===r){o=!0,r=a,n=i;break}c=c.sibling}if(!o)throw Error(s(189))}}if(n.alternate!==r)throw Error(s(190))}if(n.tag!==3)throw Error(s(188));return n.stateNode.current===n?e:t}function m(e){var t=e.tag;if(t===5||t===26||t===27||t===6)return e;for(e=e.child;e!==null;){if(t=m(e),t!==null)return t;e=e.sibling}return null}var h=Object.assign,g=Symbol.for(`react.element`),_=Symbol.for(`react.transitional.element`),v=Symbol.for(`react.portal`),y=Symbol.for(`react.fragment`),b=Symbol.for(`react.strict_mode`),x=Symbol.for(`react.profiler`),S=Symbol.for(`react.consumer`),C=Symbol.for(`react.context`),ee=Symbol.for(`react.forward_ref`),w=Symbol.for(`react.suspense`),T=Symbol.for(`react.suspense_list`),E=Symbol.for(`react.memo`),D=Symbol.for(`react.lazy`),O=Symbol.for(`react.activity`),k=Symbol.for(`react.memo_cache_sentinel`),A=Symbol.iterator;function te(e){return typeof e!=`object`||!e?null:(e=A&&e[A]||e[`@@iterator`],typeof e==`function`?e:null)}var j=Symbol.for(`react.client.reference`);function M(e){if(e==null)return null;if(typeof e==`function`)return e.$$typeof===j?null:e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case y:return`Fragment`;case x:return`Profiler`;case b:return`StrictMode`;case w:return`Suspense`;case T:return`SuspenseList`;case O:return`Activity`}if(typeof e==`object`)switch(e.$$typeof){case v:return`Portal`;case C:return e.displayName||`Context`;case S:return(e._context.displayName||`Context`)+`.Consumer`;case ee:var t=e.render;return e=e.displayName,e||=(e=t.displayName||t.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case E:return t=e.displayName||null,t===null?M(e.type)||`Memo`:t;case D:t=e._payload,e=e._init;try{return M(e(t))}catch{}}return null}var N=Array.isArray,P=i.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,F=o.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,ne={pending:!1,data:null,method:null,action:null},I=[],L=-1;function re(e){return{current:e}}function R(e){0>L||(e.current=I[L],I[L]=null,L--)}function z(e,t){L++,I[L]=e.current,e.current=t}var B=re(null),ie=re(null),ae=re(null),oe=re(null);function se(e,t){switch(z(ae,t),z(ie,e),z(B,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}R(B),z(B,e)}function ce(){R(B),R(ie),R(ae)}function V(e){e.memoizedState!==null&&z(oe,e);var t=B.current,n=Hd(t,e.type);t!==n&&(z(ie,e),z(B,n))}function le(e){ie.current===e&&(R(B),R(ie)),oe.current===e&&(R(oe),Qf._currentValue=ne)}var H,ue;function de(e){if(H===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);H=t&&t[1]||``,ue=-1<e.stack.indexOf(`
|
|
2
2
|
at`)?` (<anonymous>)`:-1<e.stack.indexOf(`@`)?`@unknown:0:0`:``}return`
|
|
3
3
|
`+H+e+ue}var fe=!1;function pe(e,t){if(!e||fe)return``;fe=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var r={DetermineComponentFrameRoot:function(){try{if(t){var n=function(){throw Error()};if(Object.defineProperty(n.prototype,`props`,{set:function(){throw Error()}}),typeof Reflect==`object`&&Reflect.construct){try{Reflect.construct(n,[])}catch(e){var r=e}Reflect.construct(e,[],n)}else{try{n.call()}catch(e){r=e}e.call(n.prototype)}}else{try{throw Error()}catch(e){r=e}(n=e())&&typeof n.catch==`function`&&n.catch(function(){})}}catch(e){if(e&&r&&typeof e.stack==`string`)return[e.stack,r.stack]}return[null,null]}};r.DetermineComponentFrameRoot.displayName=`DetermineComponentFrameRoot`;var i=Object.getOwnPropertyDescriptor(r.DetermineComponentFrameRoot,`name`);i&&i.configurable&&Object.defineProperty(r.DetermineComponentFrameRoot,`name`,{value:`DetermineComponentFrameRoot`});var a=r.DetermineComponentFrameRoot(),o=a[0],s=a[1];if(o&&s){var c=o.split(`
|
|
4
4
|
`),l=s.split(`
|
package/dist/index.html
CHANGED
|
@@ -11,16 +11,16 @@
|
|
|
11
11
|
<meta name="apple-mobile-web-app-title" content="QuickForge" />
|
|
12
12
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
|
13
13
|
<title>速构 QuickForge</title>
|
|
14
|
-
<script type="module" crossorigin src="/assets/index-
|
|
14
|
+
<script type="module" crossorigin src="/assets/index-BzOV50wA.js"></script>
|
|
15
15
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-DWdDZTNf.js">
|
|
16
16
|
<link rel="modulepreload" crossorigin href="/assets/pi-ai-Cx633yhb.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="/assets/lit-vendor-Dr3cpBGF.js">
|
|
18
18
|
<link rel="modulepreload" crossorigin href="/assets/pi-web-ui-CBet4bMl.js">
|
|
19
19
|
<link rel="modulepreload" crossorigin href="/assets/css-utils-rkE68RDy.js">
|
|
20
|
-
<link rel="modulepreload" crossorigin href="/assets/icons-
|
|
21
|
-
<link rel="modulepreload" crossorigin href="/assets/react-vendor-
|
|
20
|
+
<link rel="modulepreload" crossorigin href="/assets/icons-DzxBk7tb.js">
|
|
21
|
+
<link rel="modulepreload" crossorigin href="/assets/react-vendor-DsAeMFcm.js">
|
|
22
22
|
<link rel="modulepreload" crossorigin href="/assets/logger-B65Akg8A.js">
|
|
23
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
23
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BI7xZuj-.css">
|
|
24
24
|
</head>
|
|
25
25
|
<body>
|
|
26
26
|
<div id="root"></div>
|
package/package.json
CHANGED
package/server/acp/server.mjs
CHANGED
|
@@ -889,6 +889,7 @@ export async function createQuickForgeAcpAgent() {
|
|
|
889
889
|
}
|
|
890
890
|
}
|
|
891
891
|
|
|
892
|
+
/* eslint-disable no-console -- ACP stdio mode redirects console.log away from stdout protocol traffic. */
|
|
892
893
|
export async function runQuickForgeAcpStdio() {
|
|
893
894
|
const originalConsoleLog = console.log
|
|
894
895
|
console.log = (...args) => console.error(...args)
|
package/server/agent-manager.mjs
CHANGED
|
@@ -34,8 +34,8 @@ import {
|
|
|
34
34
|
parseInternalCommandInvocation,
|
|
35
35
|
resolveCustomCommandInvocation,
|
|
36
36
|
} from './custom-commands.mjs'
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
37
|
+
import { serverConvertToLlm, messageText, lastAssistantText } from './message-converters.mjs'
|
|
38
|
+
import { mergeQuickForgeTiming, wrapToolDefinition, wrapMcpToolDefinition, wrapPluginToolDefinition, sessionSkillsContext } from './tool-wiring.mjs'
|
|
39
39
|
import {
|
|
40
40
|
APPROVAL_TIMEOUT_MS,
|
|
41
41
|
safeReadTools,
|
|
@@ -833,8 +833,8 @@ async function runSubagent(parentSession, params, parentSignal, onUpdate) {
|
|
|
833
833
|
error.statusCode = 400
|
|
834
834
|
throw error
|
|
835
835
|
}
|
|
836
|
-
if (!parentSession.
|
|
837
|
-
throw new Error('Subagents require an active
|
|
836
|
+
if (!parentSession.projectContext?.workspaceRoot) {
|
|
837
|
+
throw new Error('Subagents require an active workspace.')
|
|
838
838
|
}
|
|
839
839
|
if (!parentSession.model) {
|
|
840
840
|
throw new Error('No active model is configured for the parent session.')
|
|
@@ -866,7 +866,7 @@ async function runSubagent(parentSession, params, parentSignal, onUpdate) {
|
|
|
866
866
|
includeMcpTools: false,
|
|
867
867
|
},
|
|
868
868
|
)
|
|
869
|
-
toolsForClient = tools.map(({ execute, prepareArguments, ...tool }) => tool)
|
|
869
|
+
toolsForClient = tools.map(({ execute: _execute, prepareArguments: _prepareArguments, ...tool }) => tool)
|
|
870
870
|
|
|
871
871
|
const emitSubagentTrace = () => {
|
|
872
872
|
if (traceTimer) {
|
|
@@ -1821,7 +1821,7 @@ export async function abortRun(sessionId) {
|
|
|
1821
1821
|
}
|
|
1822
1822
|
|
|
1823
1823
|
// Clean up any pending tool approvals for this session
|
|
1824
|
-
for (const [
|
|
1824
|
+
for (const [_toolCallId, approval] of pendingApprovals) {
|
|
1825
1825
|
if (approval.sessionId === sessionId) {
|
|
1826
1826
|
approval.reject(new Error('Run aborted'))
|
|
1827
1827
|
}
|
|
@@ -2014,10 +2014,10 @@ export async function destroyAgent(sessionId) {
|
|
|
2014
2014
|
}
|
|
2015
2015
|
|
|
2016
2016
|
// Clean up any pending approvals for this session before removing it.
|
|
2017
|
-
for (const [
|
|
2017
|
+
for (const [_toolCallId, approval] of pendingApprovals) {
|
|
2018
2018
|
if (approval.sessionId === sessionId) approval.reject(new Error('Session destroyed'))
|
|
2019
2019
|
}
|
|
2020
|
-
for (const [
|
|
2020
|
+
for (const [_approvalId, approval] of pendingAutoCompactApprovals) {
|
|
2021
2021
|
if (approval.sessionId === sessionId) approval.reject(new Error('Session destroyed'))
|
|
2022
2022
|
}
|
|
2023
2023
|
|
|
@@ -2,6 +2,7 @@ import { existsSync, promises as fs } from 'node:fs'
|
|
|
2
2
|
import os from 'node:os'
|
|
3
3
|
import path from 'node:path'
|
|
4
4
|
import { dataDir } from './storage.mjs'
|
|
5
|
+
import { logger } from './utils/logger.mjs'
|
|
5
6
|
import { firstOptionalBoolean, firstString, parseFrontmatter, splitDelimitedList } from './frontmatter.mjs'
|
|
6
7
|
|
|
7
8
|
const DEFAULT_MAX_RUNTIME_MS = 30 * 60 * 1000
|
|
@@ -123,7 +124,7 @@ async function listAgentFilesFromDirectory(dir, options = {}) {
|
|
|
123
124
|
})
|
|
124
125
|
if (profile) profiles.push(profile)
|
|
125
126
|
} catch (error) {
|
|
126
|
-
|
|
127
|
+
logger.warn(`Failed to load agent profile ${file}:`, error.message || error)
|
|
127
128
|
}
|
|
128
129
|
}
|
|
129
130
|
return profiles
|
|
@@ -2,6 +2,7 @@ import { promises as fs } from 'node:fs'
|
|
|
2
2
|
import path from 'node:path'
|
|
3
3
|
import { getEnabledPluginCommandSources } from './plugins/registry.mjs'
|
|
4
4
|
import { userCommandsDir } from './storage.mjs'
|
|
5
|
+
import { logger } from './utils/logger.mjs'
|
|
5
6
|
|
|
6
7
|
const commandsRelativeDirs = ['.claude/commands', '.opencode/commands', '.ai/commands']
|
|
7
8
|
const commandsRelativeDir = '.ai/commands'
|
|
@@ -239,7 +240,7 @@ async function listCommandsFromDirectory(dir, options = {}) {
|
|
|
239
240
|
})
|
|
240
241
|
if (command) commands.push(command)
|
|
241
242
|
} catch (error) {
|
|
242
|
-
|
|
243
|
+
logger.warn(`Failed to load custom command ${file}:`, error.message || error)
|
|
243
244
|
}
|
|
244
245
|
}
|
|
245
246
|
|
|
@@ -253,7 +254,7 @@ async function listCommandsFromFile(file, options = {}) {
|
|
|
253
254
|
return command ? [command] : []
|
|
254
255
|
} catch (error) {
|
|
255
256
|
if (error?.code === 'ENOENT' || error?.code === 'ENOTDIR' || error?.code === 'EACCES' || error?.code === 'EPERM') return []
|
|
256
|
-
|
|
257
|
+
logger.warn(`Failed to load custom command ${file}:`, error.message || error)
|
|
257
258
|
return []
|
|
258
259
|
}
|
|
259
260
|
}
|
|
@@ -483,7 +484,7 @@ function formatBuiltinCommandRows() {
|
|
|
483
484
|
const aliases = cmd.aliases?.length
|
|
484
485
|
? ` (alias: ${cmd.aliases.map((alias) => `/${alias}`).join(', ')})`
|
|
485
486
|
: ''
|
|
486
|
-
const perm = cmd.permissionNote ? `
|
|
487
|
+
const perm = cmd.permissionNote ? ` [${cmd.permissionNote}]` : ''
|
|
487
488
|
return `- \`/${cmd.name}${hint}\`${aliases} — ${cmd.description}${perm}`
|
|
488
489
|
})
|
|
489
490
|
}
|
|
@@ -4,7 +4,7 @@ import { randomUUID } from 'node:crypto'
|
|
|
4
4
|
import { spawnSync } from 'node:child_process'
|
|
5
5
|
import { existsSync, promises as fs } from 'node:fs'
|
|
6
6
|
import { ensureProjectCache, readProjectConfigData, atomicProjectConfigUpdate, dataDir, readStore, atomicUpdate } from './storage.mjs'
|
|
7
|
-
import { setWorkspaceRoot,
|
|
7
|
+
import { setWorkspaceRoot, assertDirectory } from './utils/workspace.mjs'
|
|
8
8
|
import { loadSelectedGlobalSkills, loadSelectedProjectSkills, mergeSkills } from './skills.mjs'
|
|
9
9
|
|
|
10
10
|
let defaultWorkspaceRoot = ''
|
|
@@ -101,7 +101,7 @@ function terminalShellProfileCandidatesForPlatform(platform = os.platform()) {
|
|
|
101
101
|
const profiles = TERMINAL_SHELL_PROFILE_CANDIDATES
|
|
102
102
|
.filter((profile) => profile.platforms.includes(platform))
|
|
103
103
|
.filter((profile) => commandExists(profile.command))
|
|
104
|
-
.map(({ platforms, ...profile }) => ({ ...profile, builtin: true, detected: true }))
|
|
104
|
+
.map(({ platforms: _platforms, ...profile }) => ({ ...profile, builtin: true, detected: true }))
|
|
105
105
|
|
|
106
106
|
return profiles
|
|
107
107
|
}
|
package/server/routes/agent.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { sendJson, readJsonBody, decodeSegment } from '../utils/response.mjs'
|
|
2
|
+
import { logger } from '../utils/logger.mjs'
|
|
2
3
|
import { getActiveProject, setActiveProjectPath, readProjectConfig, getDefaultWorkspaceRoot } from '../project-config.mjs'
|
|
3
4
|
import { listProjectCommands, createCommandFile } from '../custom-commands.mjs'
|
|
4
5
|
import { atomicProjectConfigUpdate } from '../storage.mjs'
|
|
@@ -38,9 +39,9 @@ export async function handleProjectApi(req, res, url) {
|
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
if (req.method === 'POST' && url.pathname === '/api/project/select-directory') {
|
|
41
|
-
|
|
42
|
+
logger.info('[project] Opening directory picker dialog...')
|
|
42
43
|
const selectedPath = await selectDirectoryDialog()
|
|
43
|
-
|
|
44
|
+
logger.info('[project] Directory picker result', { selectedPath: selectedPath || null })
|
|
44
45
|
if (!selectedPath) {
|
|
45
46
|
sendJson(res, 200, { cancelled: true, project: getActiveProject(config), projects: config.projects })
|
|
46
47
|
return
|
|
@@ -5,14 +5,24 @@ import { createAgent, getSessionEventBus, agentEvents, persistSessionState } fro
|
|
|
5
5
|
import { agentProfileSnapshot, getAgentProfile } from '../agent-profiles.mjs'
|
|
6
6
|
import { projectContextFromId, readProjectConfig } from '../project-config.mjs'
|
|
7
7
|
import { logger } from '../utils/logger.mjs'
|
|
8
|
+
import {
|
|
9
|
+
dayMs,
|
|
10
|
+
formatLocalDateTime,
|
|
11
|
+
hourMs,
|
|
12
|
+
minuteMs,
|
|
13
|
+
nextCronRun,
|
|
14
|
+
nextDailyRun,
|
|
15
|
+
nextMonthlyRun,
|
|
16
|
+
nextWeeklyRun,
|
|
17
|
+
normalizeExecutionMode,
|
|
18
|
+
parseExecuteTime,
|
|
19
|
+
timeFromDate,
|
|
20
|
+
} from '../utils/scheduled-tasks.mjs'
|
|
8
21
|
|
|
9
22
|
const STORE = 'scheduled-tasks'
|
|
10
23
|
const RUN_CHECK_INTERVAL_MS = 30 * 1000
|
|
11
24
|
const MAX_RUN_HISTORY_PER_TASK = 200
|
|
12
25
|
const cronRegex = /^(\*|\d{1,2}|\d{1,2}-\d{1,2}|\d{1,2}\/\d{1,2}|\*\/\d{1,2})(\s+(\*|\d{1,2}|\d{1,2}-\d{1,2}|\d{1,2}\/\d{1,2}|\*\/\d{1,2})){4}$/
|
|
13
|
-
const minuteMs = 60 * 1000
|
|
14
|
-
const hourMs = 60 * minuteMs
|
|
15
|
-
const dayMs = 24 * hourMs
|
|
16
26
|
const editableScheduleTypes = new Set(['once', 'daily', 'weekly', 'monthly'])
|
|
17
27
|
const weekDayNames = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
|
|
18
28
|
|
|
@@ -24,13 +34,6 @@ function executionModeFor(task) {
|
|
|
24
34
|
return task?.executionMode === 'parallel' ? 'parallel' : 'serial'
|
|
25
35
|
}
|
|
26
36
|
|
|
27
|
-
function normalizeExecutionMode(value) {
|
|
28
|
-
if (value === undefined || value === null || value === '') return 'serial'
|
|
29
|
-
const mode = String(value)
|
|
30
|
-
if (mode === 'serial' || mode === 'parallel') return mode
|
|
31
|
-
throw requestError('executionMode must be serial or parallel')
|
|
32
|
-
}
|
|
33
|
-
|
|
34
37
|
function currentRunIdsFor(task) {
|
|
35
38
|
const ids = []
|
|
36
39
|
if (Array.isArray(task?.currentRunIds)) ids.push(...task.currentRunIds.filter(Boolean))
|
|
@@ -72,20 +75,6 @@ function createId() {
|
|
|
72
75
|
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`
|
|
73
76
|
}
|
|
74
77
|
|
|
75
|
-
function pad(value) {
|
|
76
|
-
return String(value).padStart(2, '0')
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function formatLocalDateTime(date) {
|
|
80
|
-
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function timeFromDate(value) {
|
|
84
|
-
const date = value ? new Date(value) : null
|
|
85
|
-
if (!date || Number.isNaN(date.getTime())) return undefined
|
|
86
|
-
return `${pad(date.getHours())}:${pad(date.getMinutes())}`
|
|
87
|
-
}
|
|
88
|
-
|
|
89
78
|
function requestError(message, statusCode = 400) {
|
|
90
79
|
const error = new Error(message)
|
|
91
80
|
error.statusCode = statusCode
|
|
@@ -98,67 +87,12 @@ function nonEmptyString(value, fieldName) {
|
|
|
98
87
|
return text
|
|
99
88
|
}
|
|
100
89
|
|
|
101
|
-
function parseExecuteTime(value) {
|
|
102
|
-
const text = String(value ?? '').trim()
|
|
103
|
-
const match = text.match(/^(\d{1,2}):(\d{2})$/)
|
|
104
|
-
if (!match) throw requestError('executeTime must use HH:mm format')
|
|
105
|
-
const hours = Number(match[1])
|
|
106
|
-
const minutes = Number(match[2])
|
|
107
|
-
if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) {
|
|
108
|
-
throw requestError('executeTime is out of range')
|
|
109
|
-
}
|
|
110
|
-
return `${pad(hours)}:${pad(minutes)}`
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function dateWithTime(base, executeTime) {
|
|
114
|
-
const [hours, minutes] = parseExecuteTime(executeTime).split(':').map(Number)
|
|
115
|
-
const date = new Date(base)
|
|
116
|
-
date.setHours(hours, minutes, 0, 0)
|
|
117
|
-
return date
|
|
118
|
-
}
|
|
119
|
-
|
|
120
90
|
function parseDateTime(value, fieldName) {
|
|
121
91
|
const date = new Date(value)
|
|
122
92
|
if (Number.isNaN(date.getTime())) throw requestError(`${fieldName} is invalid`)
|
|
123
93
|
return date
|
|
124
94
|
}
|
|
125
95
|
|
|
126
|
-
function nextDailyRun(executeTime, base = new Date()) {
|
|
127
|
-
const next = dateWithTime(base, executeTime)
|
|
128
|
-
if (next.getTime() <= base.getTime()) next.setDate(next.getDate() + 1)
|
|
129
|
-
return next
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function nextWeeklyRun(weekDay, executeTime, base = new Date()) {
|
|
133
|
-
const targetDay = Number(weekDay)
|
|
134
|
-
if (!Number.isInteger(targetDay) || targetDay < 0 || targetDay > 6) {
|
|
135
|
-
throw requestError('weekDay must be between 0 and 6')
|
|
136
|
-
}
|
|
137
|
-
const next = dateWithTime(base, executeTime)
|
|
138
|
-
let daysToAdd = (targetDay - next.getDay() + 7) % 7
|
|
139
|
-
if (daysToAdd === 0 && next.getTime() <= base.getTime()) daysToAdd = 7
|
|
140
|
-
next.setDate(next.getDate() + daysToAdd)
|
|
141
|
-
return next
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function monthlyCandidate(year, month, monthDay, executeTime) {
|
|
145
|
-
const targetDay = Number(monthDay)
|
|
146
|
-
if (!Number.isInteger(targetDay) || targetDay < 1 || targetDay > 31) {
|
|
147
|
-
throw requestError('monthDay must be between 1 and 31')
|
|
148
|
-
}
|
|
149
|
-
const [hours, minutes] = parseExecuteTime(executeTime).split(':').map(Number)
|
|
150
|
-
const lastDay = new Date(year, month + 1, 0).getDate()
|
|
151
|
-
return new Date(year, month, Math.min(targetDay, lastDay), hours, minutes, 0, 0)
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
function nextMonthlyRun(monthDay, executeTime, base = new Date()) {
|
|
155
|
-
let next = monthlyCandidate(base.getFullYear(), base.getMonth(), monthDay, executeTime)
|
|
156
|
-
if (next.getTime() <= base.getTime()) {
|
|
157
|
-
next = monthlyCandidate(base.getFullYear(), base.getMonth() + 1, monthDay, executeTime)
|
|
158
|
-
}
|
|
159
|
-
return next
|
|
160
|
-
}
|
|
161
|
-
|
|
162
96
|
function scheduleRuleFor(task) {
|
|
163
97
|
if (task.scheduleType === 'once') return `单次 ${formatLocalDateTime(new Date(task.executeAt ?? task.nextRunAt))}`
|
|
164
98
|
if (task.scheduleType === 'daily') return `每天 ${task.executeTime}`
|
|
@@ -167,48 +101,6 @@ function scheduleRuleFor(task) {
|
|
|
167
101
|
return task.scheduleRule || task.cronExpression || '定时执行'
|
|
168
102
|
}
|
|
169
103
|
|
|
170
|
-
function parseCronField(field, min, max) {
|
|
171
|
-
if (field === '*') return { any: true, values: [] }
|
|
172
|
-
const values = new Set()
|
|
173
|
-
for (const part of field.split(',')) {
|
|
174
|
-
if (/^\*\/\d+$/.test(part)) {
|
|
175
|
-
const step = Number(part.slice(2))
|
|
176
|
-
for (let value = min; value <= max; value += step) values.add(value)
|
|
177
|
-
} else if (/^\d+-\d+$/.test(part)) {
|
|
178
|
-
const [start, end] = part.split('-').map(Number)
|
|
179
|
-
for (let value = Math.max(start, min); value <= Math.min(end, max); value += 1) values.add(value)
|
|
180
|
-
} else if (/^\d+$/.test(part)) {
|
|
181
|
-
const value = Number(part)
|
|
182
|
-
if (value >= min && value <= max) values.add(value)
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
return { any: false, values: [...values] }
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
function cronMatches(date, cronExpression) {
|
|
189
|
-
const fields = String(cronExpression || '').trim().split(/\s+/)
|
|
190
|
-
if (fields.length !== 5) return false
|
|
191
|
-
const checks = [
|
|
192
|
-
[date.getMinutes(), parseCronField(fields[0], 0, 59)],
|
|
193
|
-
[date.getHours(), parseCronField(fields[1], 0, 23)],
|
|
194
|
-
[date.getDate(), parseCronField(fields[2], 1, 31)],
|
|
195
|
-
[date.getMonth() + 1, parseCronField(fields[3], 1, 12)],
|
|
196
|
-
[date.getDay(), parseCronField(fields[4], 0, 6)],
|
|
197
|
-
]
|
|
198
|
-
return checks.every(([value, rule]) => rule.any || rule.values.includes(value))
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
function nextCronRun(cronExpression, base = new Date()) {
|
|
202
|
-
const cursor = new Date(base.getTime() + minuteMs)
|
|
203
|
-
cursor.setSeconds(0, 0)
|
|
204
|
-
const maxChecks = 366 * 24 * 60
|
|
205
|
-
for (let index = 0; index < maxChecks; index += 1) {
|
|
206
|
-
if (cronMatches(cursor, cronExpression)) return cursor
|
|
207
|
-
cursor.setMinutes(cursor.getMinutes() + 1)
|
|
208
|
-
}
|
|
209
|
-
return null
|
|
210
|
-
}
|
|
211
|
-
|
|
212
104
|
function normalizeAiJson(text) {
|
|
213
105
|
const raw = String(text || '').trim()
|
|
214
106
|
const fenced = raw.match(/```(?:json)?\s*([\s\S]*?)```/i)
|
package/server/routes/static.mjs
CHANGED
|
@@ -48,7 +48,7 @@ function shouldFallbackToIndex(url, pathname) {
|
|
|
48
48
|
export async function serveStatic(req, res, url) {
|
|
49
49
|
const distDir = path.join(projectRoot, 'dist')
|
|
50
50
|
const requested = decodeURIComponent(requestPathname(url))
|
|
51
|
-
const normalized = path.normalize(requested).replace(/^([.][.][
|
|
51
|
+
const normalized = path.normalize(requested).replace(/^([.][.][/])+/, '').replace(/^[/\\]+/, '')
|
|
52
52
|
let filePath = path.resolve(distDir, normalized)
|
|
53
53
|
|
|
54
54
|
const relative = path.relative(distDir, filePath)
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import path from 'node:path'
|
|
2
1
|
import { sendJson, readJsonBody, decodeSegment } from '../utils/response.mjs'
|
|
3
2
|
import { readStore, writeStore, atomicUpdate, getComparable, getStoreRevision, readSessionStoreScoped, readSessionValue, writeSessionValue, deleteSessionValue, ensureStorage, dataDir, configDir, storageDir, cacheDir, logsDir } from '../storage.mjs'
|
|
4
3
|
import { directorySize } from '../utils/workspace.mjs'
|
|
@@ -7,8 +6,8 @@ const metadataIndexCache = new Map()
|
|
|
7
6
|
const MAX_METADATA_INDEX_CACHE_ENTRIES = 50
|
|
8
7
|
const METADATA_INDEX_CACHE_TTL_MS = 1000
|
|
9
8
|
|
|
10
|
-
function metadataIndexCacheKey({ scope, projectId, indexName, direction }) {
|
|
11
|
-
return JSON.stringify({ scope: scope || '', projectId: projectId || '', indexName, direction })
|
|
9
|
+
function metadataIndexCacheKey({ scope, projectId, indexName, direction, archived }) {
|
|
10
|
+
return JSON.stringify({ scope: scope || '', projectId: projectId || '', indexName, direction, archived: archived || '' })
|
|
12
11
|
}
|
|
13
12
|
|
|
14
13
|
function sortIndexedValues(values, store, indexName, direction) {
|
|
@@ -34,7 +33,7 @@ function sortIndexedValues(values, store, indexName, direction) {
|
|
|
34
33
|
return values
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
async function readIndexedValues(store, indexName, direction, scope, projectId) {
|
|
36
|
+
async function readIndexedValues(store, indexName, direction, scope, projectId, archived) {
|
|
38
37
|
if (store !== 'sessions-metadata') {
|
|
39
38
|
let data
|
|
40
39
|
if (scope && store === 'sessions') {
|
|
@@ -46,7 +45,7 @@ async function readIndexedValues(store, indexName, direction, scope, projectId)
|
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
const revision = getStoreRevision(store)
|
|
49
|
-
const key = metadataIndexCacheKey({ scope, projectId, indexName, direction })
|
|
48
|
+
const key = metadataIndexCacheKey({ scope, projectId, indexName, direction, archived })
|
|
50
49
|
const cached = metadataIndexCache.get(key)
|
|
51
50
|
const now = Date.now()
|
|
52
51
|
if (cached && cached.revision === revision && now - cached.cachedAt < METADATA_INDEX_CACHE_TTL_MS) return cached.values
|
|
@@ -55,7 +54,13 @@ async function readIndexedValues(store, indexName, direction, scope, projectId)
|
|
|
55
54
|
? await readSessionStoreScoped(store, scope, scope === 'project' ? projectId : undefined)
|
|
56
55
|
: await readStore(store)
|
|
57
56
|
const values = sortIndexedValues(
|
|
58
|
-
Object.values(data)
|
|
57
|
+
Object.values(data)
|
|
58
|
+
.filter((value) => value?.messageCount !== 0)
|
|
59
|
+
.filter((value) => {
|
|
60
|
+
if (archived === 'only') return Boolean(value?.archivedAt)
|
|
61
|
+
if (archived === 'include') return true
|
|
62
|
+
return !value?.archivedAt
|
|
63
|
+
}),
|
|
59
64
|
store,
|
|
60
65
|
indexName,
|
|
61
66
|
direction,
|
|
@@ -107,10 +112,11 @@ export async function handleStorageApi(req, res, url) {
|
|
|
107
112
|
const projectId = url.searchParams.get('projectId')
|
|
108
113
|
const limitParam = url.searchParams.get('limit')
|
|
109
114
|
const offsetParam = url.searchParams.get('offset')
|
|
115
|
+
const archived = url.searchParams.get('archived')
|
|
110
116
|
|
|
111
117
|
await ensureStorage()
|
|
112
118
|
|
|
113
|
-
const values = await readIndexedValues(store, indexName, direction, scope, projectId)
|
|
119
|
+
const values = await readIndexedValues(store, indexName, direction, scope, projectId, archived)
|
|
114
120
|
|
|
115
121
|
const total = values.length
|
|
116
122
|
const limit = limitParam ? parseInt(limitParam, 10) : undefined
|
|
@@ -5,17 +5,15 @@ import { sendJson, readJsonBody } from '../utils/response.mjs'
|
|
|
5
5
|
import { projectContextFromId } from '../project-config.mjs'
|
|
6
6
|
import {
|
|
7
7
|
assertSafeWorkspacePath,
|
|
8
|
-
isSensitiveWorkspacePath,
|
|
9
8
|
resolveWorkspacePath,
|
|
10
|
-
shouldSearchFile,
|
|
11
9
|
toWorkspaceRelative,
|
|
12
10
|
} from '../utils/workspace.mjs'
|
|
13
11
|
|
|
14
|
-
const MAX_PREVIEW_BYTES = 1024 * 1024
|
|
15
|
-
const MAX_STATIC_PREVIEW_BYTES =
|
|
12
|
+
const MAX_PREVIEW_BYTES = 50 * 1024 * 1024
|
|
13
|
+
const MAX_STATIC_PREVIEW_BYTES = 50 * 1024 * 1024
|
|
16
14
|
const PREVIEW_ALLOWED_EXTENSIONS = new Set(['.html', '.htm', '.css', '.js', '.mjs', '.json', '.svg', '.png', '.jpg', '.jpeg', '.webp', '.gif', '.ico', '.txt', '.md'])
|
|
17
|
-
const MAX_TREE_NODES =
|
|
18
|
-
const SKIP_DIRS = new Set(['.git', 'node_modules'
|
|
15
|
+
const MAX_TREE_NODES = 50000
|
|
16
|
+
const SKIP_DIRS = new Set(['.git', 'node_modules'])
|
|
19
17
|
|
|
20
18
|
const extensionLanguageMap = new Map([
|
|
21
19
|
['ts', 'typescript'], ['tsx', 'typescript'], ['js', 'javascript'], ['jsx', 'javascript'],
|
|
@@ -58,14 +56,6 @@ function previewContentType(filePath) {
|
|
|
58
56
|
return map[ext] || 'application/octet-stream'
|
|
59
57
|
}
|
|
60
58
|
|
|
61
|
-
function isBinaryBuffer(buffer) {
|
|
62
|
-
const length = Math.min(buffer.length, 8000)
|
|
63
|
-
for (let index = 0; index < length; index += 1) {
|
|
64
|
-
if (buffer[index] === 0) return true
|
|
65
|
-
}
|
|
66
|
-
return false
|
|
67
|
-
}
|
|
68
|
-
|
|
69
59
|
async function projectContextFromUrl(url) {
|
|
70
60
|
const projectId = url.searchParams.get('projectId')
|
|
71
61
|
if (!projectId) {
|
|
@@ -248,7 +238,7 @@ async function readGitFile(workspaceRoot, ref, relativePath) {
|
|
|
248
238
|
|
|
249
239
|
async function readWorkspaceTextFile(context, relativePath) {
|
|
250
240
|
const file = resolveWorkspacePath(relativePath, context)
|
|
251
|
-
await assertSafeWorkspacePath(file, context)
|
|
241
|
+
await assertSafeWorkspacePath(file, context, { allowSensitive: true })
|
|
252
242
|
const stat = await fs.stat(file)
|
|
253
243
|
if (!stat.isFile()) {
|
|
254
244
|
const error = new Error('Path is not a file')
|
|
@@ -261,11 +251,6 @@ async function readWorkspaceTextFile(context, relativePath) {
|
|
|
261
251
|
throw error
|
|
262
252
|
}
|
|
263
253
|
const buffer = await fs.readFile(file)
|
|
264
|
-
if (isBinaryBuffer(buffer)) {
|
|
265
|
-
const error = new Error('Binary file cannot be previewed')
|
|
266
|
-
error.statusCode = 415
|
|
267
|
-
throw error
|
|
268
|
-
}
|
|
269
254
|
return { content: buffer.toString('utf8'), size: stat.size, path: toWorkspaceRelative(file, context) }
|
|
270
255
|
}
|
|
271
256
|
|
|
@@ -282,9 +267,9 @@ async function buildTreeForDirectory(dir, context, counter) {
|
|
|
282
267
|
const fullPath = path.join(dir, entry.name)
|
|
283
268
|
const relativePath = toWorkspaceRelative(fullPath, context)
|
|
284
269
|
if (entry.isDirectory()) {
|
|
285
|
-
if (SKIP_DIRS.has(entry.name)
|
|
270
|
+
if (SKIP_DIRS.has(entry.name)) continue
|
|
286
271
|
try {
|
|
287
|
-
await assertSafeWorkspacePath(fullPath, context)
|
|
272
|
+
await assertSafeWorkspacePath(fullPath, context, { allowSensitive: true })
|
|
288
273
|
counter.count += 1
|
|
289
274
|
nodes.push({
|
|
290
275
|
name: entry.name,
|
|
@@ -296,9 +281,8 @@ async function buildTreeForDirectory(dir, context, counter) {
|
|
|
296
281
|
// Skip directories that cannot be safely resolved.
|
|
297
282
|
}
|
|
298
283
|
} else if (entry.isFile()) {
|
|
299
|
-
if (!shouldSearchFile(entry.name) || isSensitiveWorkspacePath(fullPath, context)) continue
|
|
300
284
|
try {
|
|
301
|
-
await assertSafeWorkspacePath(fullPath, context)
|
|
285
|
+
await assertSafeWorkspacePath(fullPath, context, { allowSensitive: true })
|
|
302
286
|
counter.count += 1
|
|
303
287
|
nodes.push({ name: entry.name, path: relativePath, type: 'file' })
|
|
304
288
|
} catch {
|
package/server/session-utils.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { streamSimple } from '@earendil-works/pi-ai'
|
|
|
2
2
|
import { buildInstructionsPayload, projectContextFromId } from './project-config.mjs'
|
|
3
3
|
import { composeSystemPrompt } from './system-prompt.mjs'
|
|
4
4
|
import { listSubagentProfiles } from './agent-profiles.mjs'
|
|
5
|
+
import { logger } from './utils/logger.mjs'
|
|
5
6
|
|
|
6
7
|
// ---------------------------------------------------------------------------
|
|
7
8
|
// System prompt
|
|
@@ -109,7 +110,7 @@ export async function generateAiTitle(messages, model, thinkingLevel, getApiKey)
|
|
|
109
110
|
const title = normalizeAiTitle(titleText)
|
|
110
111
|
return title || null
|
|
111
112
|
} catch (error) {
|
|
112
|
-
|
|
113
|
+
logger.warn('Failed to generate AI title:', error.message || error)
|
|
113
114
|
return null
|
|
114
115
|
}
|
|
115
116
|
}
|