@shawnstack/quickforge 1.5.1 → 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.
Files changed (44) hide show
  1. package/README.md +10 -10
  2. package/dist/assets/AgentProfilesPage-DKyIh3dE.js +1 -0
  3. package/dist/assets/ChatPanelHost-BUZ6scv9.js +242 -0
  4. package/dist/assets/{PluginsPage-kRzB5k8J.js → PluginsPage-CN-SFQ_s.js} +1 -1
  5. package/dist/assets/ScheduledTasksPage-C0htXZk2.js +2 -0
  6. package/dist/assets/{SharedConversationPage-EQdZgWCM.js → SharedConversationPage-CxbAx1fN.js} +1 -1
  7. package/dist/assets/TerminalDock-_voUf7d-.js +2 -0
  8. package/dist/assets/WorkspaceInspector-Ci4FuaZH.js +3 -0
  9. package/dist/assets/{WorkspaceReaderDialog-BwzZ8Tgv.js → WorkspaceReaderDialog-D75__GFg.js} +1 -1
  10. package/dist/assets/{diff-line-counts-CeZC7b0z.js → diff-line-counts-DHyWKEXk.js} +1 -1
  11. package/dist/assets/icons-DzxBk7tb.js +1 -0
  12. package/dist/assets/index-BI7xZuj-.css +3 -0
  13. package/dist/assets/index-BzOV50wA.js +1442 -0
  14. package/dist/assets/{monaco-CNEfYIy1.js → monaco-dMY7_GLO.js} +1 -1
  15. package/dist/assets/{react-vendor-CZCcjpSR.js → react-vendor-DsAeMFcm.js} +1 -1
  16. package/dist/index.html +4 -4
  17. package/package.json +1 -1
  18. package/server/acp/server.mjs +1 -0
  19. package/server/agent-manager.mjs +6 -6
  20. package/server/agent-profile-files.mjs +2 -1
  21. package/server/channels/process-channel.mjs +1 -0
  22. package/server/channels/providers/wechat.mjs +1 -0
  23. package/server/custom-commands.mjs +4 -3
  24. package/server/plugins/registry.mjs +1 -1
  25. package/server/project-config.mjs +2 -2
  26. package/server/routes/agent.mjs +0 -1
  27. package/server/routes/project.mjs +3 -2
  28. package/server/routes/scheduled-tasks.mjs +13 -121
  29. package/server/routes/static.mjs +1 -1
  30. package/server/routes/storage.mjs +13 -7
  31. package/server/session-utils.mjs +2 -1
  32. package/server/skills.mjs +3 -2
  33. package/server/storage.mjs +0 -1
  34. package/server/utils/logger.mjs +0 -1
  35. package/server/utils/package-update.mjs +2 -2
  36. package/server/utils/scheduled-tasks.mjs +127 -0
  37. package/dist/assets/AgentProfilesPage-BIwd5Nzg.js +0 -1
  38. package/dist/assets/ChatPanelHost-De-DMjx5.js +0 -242
  39. package/dist/assets/ScheduledTasksPage-ZnjohaPS.js +0 -2
  40. package/dist/assets/TerminalDock-P2pJH_tx.js +0 -2
  41. package/dist/assets/WorkspaceInspector-CkLAqYQ6.js +0 -3
  42. package/dist/assets/icons-DJqt-rnw.js +0 -1
  43. package/dist/assets/index-CcGy4TXo.js +0 -1354
  44. package/dist/assets/index-DuTUuAMk.css +0 -3
@@ -1,4 +1,4 @@
1
- import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{Ct as t}from"./icons-DJqt-rnw.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.
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{Ct as t}from"./icons-DJqt-rnw.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-CcGy4TXo.js"></script>
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-DJqt-rnw.js">
21
- <link rel="modulepreload" crossorigin href="/assets/react-vendor-CZCcjpSR.js">
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-DuTUuAMk.css">
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shawnstack/quickforge",
3
- "version": "1.5.1",
3
+ "version": "1.5.2",
4
4
  "description": "AI chat application with Agent access modes for local workspace tools. React + Vite + Tailwind CSS frontend, local Node.js storage server.",
5
5
  "keywords": [
6
6
  "ai",
@@ -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)
@@ -34,8 +34,8 @@ import {
34
34
  parseInternalCommandInvocation,
35
35
  resolveCustomCommandInvocation,
36
36
  } from './custom-commands.mjs'
37
- import { omitDetailsForLlm, serverConvertToLlm, messageText, lastAssistantText } from './message-converters.mjs'
38
- import { isPlainObject, mergeQuickForgeTiming, wrapToolDefinition, wrapMcpToolDefinition, wrapPluginToolDefinition, sessionSkillsContext } from './tool-wiring.mjs'
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,
@@ -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 [toolCallId, approval] of pendingApprovals) {
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 [toolCallId, approval] of pendingApprovals) {
2017
+ for (const [_toolCallId, approval] of pendingApprovals) {
2018
2018
  if (approval.sessionId === sessionId) approval.reject(new Error('Session destroyed'))
2019
2019
  }
2020
- for (const [approvalId, approval] of pendingAutoCompactApprovals) {
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
- console.warn(`Failed to load agent profile ${file}:`, error.message || error)
127
+ logger.warn(`Failed to load agent profile ${file}:`, error.message || error)
127
128
  }
128
129
  }
129
130
  return profiles
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-control-regex -- ANSI escape matching intentionally includes ESC. */
1
2
  import { spawn } from 'node:child_process'
2
3
  import { EventEmitter } from 'node:events'
3
4
  import { setTimeout as delay } from 'node:timers/promises'
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-control-regex -- URL extraction intentionally treats ESC as a delimiter. */
1
2
  import { spawn } from 'node:child_process'
2
3
  import { promises as fs } from 'node:fs'
3
4
  import path from 'node:path'
@@ -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
- console.warn(`Failed to load custom command ${file}:`, error.message || error)
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
- console.warn(`Failed to load custom command ${file}:`, error.message || error)
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 ? ` \[${cmd.permissionNote}\]` : ''
487
+ const perm = cmd.permissionNote ? ` [${cmd.permissionNote}]` : ''
487
488
  return `- \`/${cmd.name}${hint}\`${aliases} — ${cmd.description}${perm}`
488
489
  })
489
490
  }
@@ -43,7 +43,7 @@ async function readJsonFile(filePath) {
43
43
  }
44
44
 
45
45
  async function listPluginDirs(root) {
46
- let entries = []
46
+ let entries
47
47
  try {
48
48
  entries = await fs.readdir(root, { withFileTypes: true })
49
49
  } catch (error) {
@@ -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, getWorkspaceRoot, assertDirectory } from './utils/workspace.mjs'
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
  }
@@ -15,7 +15,6 @@ import {
15
15
  restoreAgent,
16
16
  touchSession,
17
17
  listSessions,
18
- refreshAllSessionTools,
19
18
  updateSessionAccessMode,
20
19
  updateSessionYoloMode,
21
20
  updateSessionModel,
@@ -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
- console.log('[project] Opening directory picker dialog...')
42
+ logger.info('[project] Opening directory picker dialog...')
42
43
  const selectedPath = await selectDirectoryDialog()
43
- console.log('[project] Directory picker result:', selectedPath ? `"${selectedPath}"` : '(cancelled/empty)')
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)
@@ -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(/^([.][.][\/])+/, '').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).filter((value) => value?.messageCount !== 0),
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
@@ -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
- console.warn('Failed to generate AI title:', error.message || error)
113
+ logger.warn('Failed to generate AI title:', error.message || error)
113
114
  return null
114
115
  }
115
116
  }
package/server/skills.mjs CHANGED
@@ -3,6 +3,7 @@ import os from 'node:os'
3
3
  import path from 'node:path'
4
4
  import { dataDir } from './storage.mjs'
5
5
  import { getEnabledPluginSkillSources } from './plugins/registry.mjs'
6
+ import { logger } from './utils/logger.mjs'
6
7
 
7
8
  const userSkillsDir = path.join(dataDir, 'skills')
8
9
  const sharedUserSkillsDir = path.join(os.homedir(), '.agents', 'skills')
@@ -347,7 +348,7 @@ async function loadSkillsFromSources(sources) {
347
348
  if (skillsByName.has(skill.name)) skillsByName.delete(skill.name)
348
349
  skillsByName.set(skill.name, skill)
349
350
  } catch (error) {
350
- console.warn(`Failed to load skill from ${skillDir}:`, error.message || error)
351
+ logger.warn(`Failed to load skill from ${skillDir}:`, error.message || error)
351
352
  }
352
353
  }
353
354
  }
@@ -371,7 +372,7 @@ async function loadSkillsFromExplicitSources(sources) {
371
372
  if (skillsByName.has(skill.name)) skillsByName.delete(skill.name)
372
373
  skillsByName.set(skill.name, skill)
373
374
  } catch (error) {
374
- console.warn(`Failed to load skill from ${skillDir}:`, error.message || error)
375
+ logger.warn(`Failed to load skill from ${skillDir}:`, error.message || error)
375
376
  }
376
377
  }
377
378
  }
@@ -75,7 +75,6 @@ export function getStoreRevision(storeName) {
75
75
  }
76
76
 
77
77
  const configStores = new Set(['settings', 'provider-keys', 'custom-providers', 'plugins'])
78
- const sessionStores = new Set(['sessions', 'sessions-metadata'])
79
78
 
80
79
  const configStoreSections = {
81
80
  settings: ['app', 'settings'],
@@ -4,7 +4,6 @@ import { logsDir } from '../storage.mjs'
4
4
 
5
5
  // --- Level control ---
6
6
  const LEVELS = { ERROR: 0, WARN: 1, INFO: 2, DEBUG: 3 }
7
- const levelNames = Object.keys(LEVELS)
8
7
 
9
8
  const envLevel = (process.env.QUICKFORGE_LOG_LEVEL || '').toUpperCase()
10
9
  const minLevel = LEVELS[envLevel] ?? LEVELS.INFO
@@ -27,7 +27,7 @@ export async function getPackageInfo(projectRoot) {
27
27
  bugsUrl: typeof pkg.bugs === 'string' ? pkg.bugs : pkg.bugs?.url || '',
28
28
  }
29
29
  } catch (error) {
30
- throw new Error(`Unable to read package metadata: ${error.message}`)
30
+ throw new Error(`Unable to read package metadata: ${error.message}`, { cause: error })
31
31
  }
32
32
  }
33
33
 
@@ -109,7 +109,7 @@ export async function fetchLatestVersion(packageName) {
109
109
  if (!latest || typeof latest !== 'string') throw new Error('latest version not found in registry response')
110
110
  return latest
111
111
  } catch (error) {
112
- if (error.name === 'AbortError') throw new Error('request timeout')
112
+ if (error.name === 'AbortError') throw new Error('request timeout', { cause: error })
113
113
  throw error
114
114
  } finally {
115
115
  clearTimeout(timeout)