@shawnstack/quickforge 1.4.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -12
- package/dist/assets/{AgentProfilesPage-C79teCgh.js → AgentProfilesPage-CNK5PxA3.js} +1 -1
- package/dist/assets/ChatPanelHost-FqPQwwMO.js +217 -0
- package/dist/assets/PluginsPage-BCu1Ept0.js +1 -0
- package/dist/assets/{ScheduledTasksPage-C047y3p3.js → ScheduledTasksPage-Bx04rjui.js} +2 -2
- package/dist/assets/SharedConversationPage-55vX9sqe.js +1 -0
- package/dist/assets/TerminalDock-DLN_pLkJ.js +2 -0
- package/dist/assets/WorkspaceInspector-DoemHHnY.js +3 -0
- package/dist/assets/{WorkspaceReaderDialog-bTeERaGd.js → WorkspaceReaderDialog-C6xUHBCw.js} +2 -2
- package/dist/assets/{icons-Dsc5yL3l.js → icons-BWtivFsx.js} +1 -1
- package/dist/assets/index-CxOHP41X.css +3 -0
- package/dist/assets/index-Dcf73EL8.js +895 -0
- package/dist/assets/{monaco-DG4TcBMc.js → monaco-evITXh-m.js} +1 -1
- package/dist/assets/{react-vendor-CiCXOLb5.js → react-vendor-Mthyt1p4.js} +1 -1
- package/dist/index.html +4 -4
- package/package.json +1 -1
- package/server/agent-manager.mjs +85 -13
- package/server/approval-store.mjs +13 -1
- package/server/auto-compaction.mjs +29 -73
- package/server/context-usage.mjs +108 -0
- package/server/custom-commands.mjs +145 -28
- package/server/mcp/registry.mjs +40 -0
- package/server/routes/agent.mjs +1 -1
- package/server/routes/mcp.mjs +7 -1
- package/server/routes/project.mjs +32 -2
- package/server/routes/shared-conversation.mjs +1 -1
- package/server/storage.mjs +1 -0
- package/server/subagents.mjs +8 -6
- package/server/system-prompt.mjs +2 -2
- package/server/tools/definitions.mjs +1 -1
- package/dist/assets/ChatPanelHost-BjdIshtX.js +0 -195
- package/dist/assets/PluginsPage-Dt7Iiddo.js +0 -1
- package/dist/assets/SharedConversationPage-8X8kfztQ.js +0 -1
- package/dist/assets/TerminalDock-CEuJNf0m.js +0 -2
- package/dist/assets/WorkspaceInspector-BIa5gLVs.js +0 -3
- package/dist/assets/index-CPAWYhzz.css +0 -3
- package/dist/assets/index-YTL26wyJ.js +0 -814
|
@@ -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{ut as t}from"./icons-BWtivFsx.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{it as t}from"./icons-Dsc5yL3l.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{ut as t}from"./icons-BWtivFsx.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-Dcf73EL8.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-BWtivFsx.js">
|
|
21
|
+
<link rel="modulepreload" crossorigin href="/assets/react-vendor-Mthyt1p4.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-CxOHP41X.css">
|
|
24
24
|
</head>
|
|
25
25
|
<body>
|
|
26
26
|
<div id="root"></div>
|
package/package.json
CHANGED
package/server/agent-manager.mjs
CHANGED
|
@@ -35,7 +35,6 @@ import { omitDetailsForLlm, serverConvertToLlm, messageText, lastAssistantText }
|
|
|
35
35
|
import { isPlainObject, mergeQuickForgeTiming, wrapToolDefinition, wrapMcpToolDefinition, wrapPluginToolDefinition, sessionSkillsContext } from './tool-wiring.mjs'
|
|
36
36
|
import {
|
|
37
37
|
APPROVAL_TIMEOUT_MS,
|
|
38
|
-
commandRestrictedTools,
|
|
39
38
|
safeReadTools,
|
|
40
39
|
pendingApprovals,
|
|
41
40
|
pendingAutoCompactApprovals,
|
|
@@ -545,9 +544,59 @@ async function clearSession(session) {
|
|
|
545
544
|
return { sessionId: session.sessionId, status: session.status, cleared: true }
|
|
546
545
|
}
|
|
547
546
|
|
|
548
|
-
|
|
547
|
+
const QUICKFORGE_COMMAND_DETAILS_KEY = 'quickforgeCommand'
|
|
548
|
+
|
|
549
|
+
function normalizedPromptCommand(command) {
|
|
550
|
+
return command?.type === 'plan' ? { type: 'plan' } : null
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
function objectDetails(message) {
|
|
554
|
+
const details = message?.details
|
|
555
|
+
return details && typeof details === 'object' && !Array.isArray(details) ? details : {}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
function promptCommandFromMessage(message) {
|
|
559
|
+
return normalizedPromptCommand(objectDetails(message)[QUICKFORGE_COMMAND_DETAILS_KEY])
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
function messageWithPromptCommand(message, command) {
|
|
563
|
+
const normalized = normalizedPromptCommand(command)
|
|
564
|
+
if (!normalized || !message || typeof message !== 'object') return message
|
|
565
|
+
return {
|
|
566
|
+
...message,
|
|
567
|
+
details: {
|
|
568
|
+
...objectDetails(message),
|
|
569
|
+
[QUICKFORGE_COMMAND_DETAILS_KEY]: normalized,
|
|
570
|
+
},
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
function internalInvocationForPromptCommand(userMessage, command) {
|
|
575
|
+
const normalized = normalizedPromptCommand(command)
|
|
576
|
+
if (normalized?.type === 'plan') {
|
|
577
|
+
// Derive the task from the message text. Strip a leading "/plan" so that
|
|
578
|
+
// toggling plan mode while typing "/plan <task>" yields the clean task —
|
|
579
|
+
// matching the slash-command parse path and avoiding a redundant prefix.
|
|
580
|
+
const raw = messageText(userMessage).trim()
|
|
581
|
+
const planPrefix = raw.match(/^\/plan(?:\s+([\s\S]*))?$/i)
|
|
582
|
+
return { type: 'plan', args: planPrefix ? (planPrefix[1] || '').trim() : raw }
|
|
583
|
+
}
|
|
584
|
+
return parseInternalCommandInvocation(userMessage)
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
function planCommandState(userMessage, args) {
|
|
588
|
+
return {
|
|
589
|
+
userMessage: messageWithPromptCommand(userMessage, { type: 'plan' }),
|
|
590
|
+
commandPrompt: formatPlanCommandPrompt(args),
|
|
591
|
+
permissions: { allowEdit: false, allowCommands: false, allowSubagents: true },
|
|
592
|
+
commandName: 'plan',
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
async function resolveCommandState(session, userMessage, promptCommand = null) {
|
|
597
|
+
const command = normalizedPromptCommand(promptCommand) || promptCommandFromMessage(userMessage)
|
|
549
598
|
const internalResponse = await handleInternalCommand(
|
|
550
|
-
|
|
599
|
+
internalInvocationForPromptCommand(userMessage, command),
|
|
551
600
|
session.projectContext?.workspaceRoot,
|
|
552
601
|
session.projectContext?.project?.commandDir,
|
|
553
602
|
)
|
|
@@ -555,12 +604,7 @@ async function resolveCommandState(session, userMessage) {
|
|
|
555
604
|
if (internalResponse?.clear) return { clear: internalResponse }
|
|
556
605
|
if (internalResponse?.compact) return { compact: internalResponse }
|
|
557
606
|
if (internalResponse?.plan) {
|
|
558
|
-
return
|
|
559
|
-
userMessage,
|
|
560
|
-
commandPrompt: formatPlanCommandPrompt(internalResponse.args),
|
|
561
|
-
permissions: { allowEdit: false, allowCommands: false, allowSubagents: true },
|
|
562
|
-
commandName: 'plan',
|
|
563
|
-
}
|
|
607
|
+
return planCommandState(userMessage, internalResponse.args)
|
|
564
608
|
}
|
|
565
609
|
if (internalResponse?.review) {
|
|
566
610
|
return {
|
|
@@ -571,7 +615,22 @@ async function resolveCommandState(session, userMessage) {
|
|
|
571
615
|
}
|
|
572
616
|
}
|
|
573
617
|
|
|
574
|
-
if (!session.projectContext?.workspaceRoot)
|
|
618
|
+
if (!session.projectContext?.workspaceRoot) {
|
|
619
|
+
// Even without a project, user-level custom commands (~/.quickforge/commands/) are available
|
|
620
|
+
const invocation = await resolveCustomCommandInvocation(
|
|
621
|
+
userMessage,
|
|
622
|
+
null,
|
|
623
|
+
session.projectContext?.project?.commandDir,
|
|
624
|
+
)
|
|
625
|
+
if (!invocation) return { userMessage }
|
|
626
|
+
|
|
627
|
+
return {
|
|
628
|
+
userMessage,
|
|
629
|
+
commandPrompt: invocation.systemPrompt,
|
|
630
|
+
permissions: invocation.permissions,
|
|
631
|
+
commandName: invocation.command.name,
|
|
632
|
+
}
|
|
633
|
+
}
|
|
575
634
|
|
|
576
635
|
const invocation = await resolveCustomCommandInvocation(
|
|
577
636
|
userMessage,
|
|
@@ -1452,7 +1511,7 @@ export async function rollbackSessionMessages(sessionId, rollbackMessageIndex) {
|
|
|
1452
1511
|
* Send a user message to the agent and start the agent loop.
|
|
1453
1512
|
* Returns immediately; events are streamed via the event bus.
|
|
1454
1513
|
*/
|
|
1455
|
-
export async function runPrompt(sessionId, message, selectedCapabilities = []) {
|
|
1514
|
+
export async function runPrompt(sessionId, message, selectedCapabilities = [], promptCommand = null) {
|
|
1456
1515
|
let session = agentSessions.get(sessionId)
|
|
1457
1516
|
if (!session) {
|
|
1458
1517
|
session = await restoreAgent(sessionId)
|
|
@@ -1471,7 +1530,7 @@ export async function runPrompt(sessionId, message, selectedCapabilities = []) {
|
|
|
1471
1530
|
const initialUserMessage = typeof message === 'string'
|
|
1472
1531
|
? { role: 'user', content: message, timestamp: new Date().toISOString() }
|
|
1473
1532
|
: message
|
|
1474
|
-
const commandState = await resolveCommandState(session, initialUserMessage)
|
|
1533
|
+
const commandState = await resolveCommandState(session, initialUserMessage, promptCommand)
|
|
1475
1534
|
const userMessage = commandState.userMessage ?? initialUserMessage
|
|
1476
1535
|
|
|
1477
1536
|
if (commandState.textResponse) {
|
|
@@ -1569,14 +1628,27 @@ export async function continueSession(sessionId) {
|
|
|
1569
1628
|
throw Object.assign(new Error('Cannot continue: no user message found.'), { statusCode: 400 })
|
|
1570
1629
|
}
|
|
1571
1630
|
|
|
1572
|
-
const
|
|
1631
|
+
const lastUserMessage = messages[lastUserIndex]
|
|
1632
|
+
const commandState = await resolveCommandState(session, lastUserMessage)
|
|
1633
|
+
const continuedUserMessage = commandState.userMessage ?? lastUserMessage
|
|
1634
|
+
const trimmedMessages = messages.slice(0, lastUserIndex).concat(continuedUserMessage)
|
|
1573
1635
|
updateSessionMessages(session, trimmedMessages)
|
|
1574
1636
|
resetSessionCompaction(session)
|
|
1575
1637
|
|
|
1576
1638
|
resetIdleTimer(session)
|
|
1639
|
+
session.activeCommandName = commandState.commandName ?? null
|
|
1640
|
+
session.activeCommandPermissions = commandState.permissions ?? null
|
|
1641
|
+
session.activeCommandPrompt = commandState.commandPrompt ?? null
|
|
1642
|
+
session.activeCapabilityPrompt = null
|
|
1643
|
+
|
|
1577
1644
|
session.agent.continue().catch((err) => {
|
|
1578
1645
|
logger.error(`Agent continue error for session ${sessionId}:`, err, { sessionId })
|
|
1579
1646
|
emitSessionEvent(session, { type: 'error', error: err.message || 'Unknown error' })
|
|
1647
|
+
}).finally(() => {
|
|
1648
|
+
session.activeCommandName = null
|
|
1649
|
+
session.activeCommandPermissions = null
|
|
1650
|
+
session.activeCommandPrompt = null
|
|
1651
|
+
session.activeCapabilityPrompt = null
|
|
1580
1652
|
})
|
|
1581
1653
|
|
|
1582
1654
|
return { sessionId, status: 'running' }
|
|
@@ -24,6 +24,14 @@ export const commandRestrictedTools = new Set([
|
|
|
24
24
|
'run_subagent',
|
|
25
25
|
])
|
|
26
26
|
|
|
27
|
+
export const planAllowedTools = new Set([
|
|
28
|
+
'read_file',
|
|
29
|
+
'grep_files',
|
|
30
|
+
'activate_skill',
|
|
31
|
+
'read_skill_resource',
|
|
32
|
+
'run_subagent',
|
|
33
|
+
])
|
|
34
|
+
|
|
27
35
|
export const safeReadTools = new Set([
|
|
28
36
|
'read_file',
|
|
29
37
|
'grep_files',
|
|
@@ -45,7 +53,11 @@ export const pendingAutoCompactApprovals = new Map()
|
|
|
45
53
|
|
|
46
54
|
export function commandToolPermissionError(session, toolName) {
|
|
47
55
|
const permissions = session?.activeCommandPermissions
|
|
48
|
-
if (!permissions
|
|
56
|
+
if (!permissions) return null
|
|
57
|
+
if (session?.activeCommandName === 'plan' && !planAllowedTools.has(toolName)) {
|
|
58
|
+
return `Command /plan is read-only and cannot use ${toolName}.`
|
|
59
|
+
}
|
|
60
|
+
if (!commandRestrictedTools.has(toolName)) return null
|
|
49
61
|
if (toolName === 'run_command' && permissions.allowCommands === false) {
|
|
50
62
|
return `Command /${session.activeCommandName} does not allow running shell commands.`
|
|
51
63
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readStore } from './storage.mjs'
|
|
2
2
|
import { compactConversation, saveCompactBackup } from './conversation-compaction.mjs'
|
|
3
|
+
import { estimateContextUsage, shouldCompactContextByPercent } from './context-usage.mjs'
|
|
3
4
|
|
|
4
5
|
export const AUTO_COMPACT_SETTINGS_KEY = 'auto-compact-settings'
|
|
5
6
|
|
|
@@ -44,14 +45,6 @@ function safeJson(value) {
|
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
function estimateTextTokens(value) {
|
|
48
|
-
const text = String(value || '')
|
|
49
|
-
if (!text) return 0
|
|
50
|
-
const cjkChars = text.match(/[\u3400-\u9fff\uf900-\ufaff]/g)?.length ?? 0
|
|
51
|
-
const otherChars = Math.max(0, text.length - cjkChars)
|
|
52
|
-
return Math.ceil(cjkChars + otherChars / 3.5)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
48
|
function contentToText(content) {
|
|
56
49
|
if (typeof content === 'string') return content
|
|
57
50
|
if (!Array.isArray(content)) return ''
|
|
@@ -65,19 +58,6 @@ function contentToText(content) {
|
|
|
65
58
|
}).filter(Boolean).join('\n')
|
|
66
59
|
}
|
|
67
60
|
|
|
68
|
-
function estimateMessageTokens(message) {
|
|
69
|
-
if (!message || typeof message !== 'object') return 0
|
|
70
|
-
const parts = [message.role || '', contentToText(message.content)]
|
|
71
|
-
if (message.toolName) parts.push(message.toolName)
|
|
72
|
-
if (message.toolCallId) parts.push(message.toolCallId)
|
|
73
|
-
if (message.attachments !== undefined) parts.push(safeJson(message.attachments))
|
|
74
|
-
return estimateTextTokens(parts.join('\n'))
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function estimateMessagesTokens(messages) {
|
|
78
|
-
return (Array.isArray(messages) ? messages : []).reduce((total, message) => total + estimateMessageTokens(message), 0)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
61
|
function estimateMessagesChars(messages) {
|
|
82
62
|
return (Array.isArray(messages) ? messages : []).reduce((total, message) => {
|
|
83
63
|
if (!message || typeof message !== 'object') return total
|
|
@@ -85,50 +65,6 @@ function estimateMessagesChars(messages) {
|
|
|
85
65
|
}, 0)
|
|
86
66
|
}
|
|
87
67
|
|
|
88
|
-
function messageTimestampMs(message) {
|
|
89
|
-
const timestamp = message?.timestamp
|
|
90
|
-
if (typeof timestamp === 'number') return timestamp
|
|
91
|
-
if (typeof timestamp === 'string') {
|
|
92
|
-
const parsed = Date.parse(timestamp)
|
|
93
|
-
return Number.isNaN(parsed) ? 0 : parsed
|
|
94
|
-
}
|
|
95
|
-
return 0
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function latestCompactTimestampMs(session) {
|
|
99
|
-
return messageTimestampMs(session?.contextCompaction?.summaryMessage)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function latestKnownInputTokens(messages, sinceTimestamp = 0) {
|
|
103
|
-
let latestTimestamp = -1
|
|
104
|
-
let latestInput = 0
|
|
105
|
-
for (const message of Array.isArray(messages) ? messages : []) {
|
|
106
|
-
if (message?.role !== 'assistant' || !message.usage) continue
|
|
107
|
-
const timestamp = messageTimestampMs(message)
|
|
108
|
-
if (sinceTimestamp > 0 && timestamp <= sinceTimestamp) continue
|
|
109
|
-
if (timestamp < latestTimestamp) continue
|
|
110
|
-
const input = Math.max(0, Number(message.usage.input ?? message.usage.totalTokens) || 0)
|
|
111
|
-
if (input <= 0) continue
|
|
112
|
-
latestTimestamp = timestamp
|
|
113
|
-
latestInput = input
|
|
114
|
-
}
|
|
115
|
-
return latestInput
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export function estimateContextUsage({ systemPrompt, messages, tools, model, knownInputTokens = 0 }) {
|
|
119
|
-
const contextWindow = Number(model?.contextWindow) || 0
|
|
120
|
-
const reservedOutputTokens = Math.max(0, Number(model?.maxTokens) || 4096)
|
|
121
|
-
const estimatedInputTokens =
|
|
122
|
-
estimateTextTokens(systemPrompt) +
|
|
123
|
-
estimateMessagesTokens(messages) +
|
|
124
|
-
estimateTextTokens(safeJson(tools))
|
|
125
|
-
const knownInput = Math.max(0, Number(knownInputTokens) || 0)
|
|
126
|
-
const inputTokens = Math.max(estimatedInputTokens, knownInput)
|
|
127
|
-
const totalTokens = inputTokens + reservedOutputTokens
|
|
128
|
-
const percent = contextWindow > 0 ? Math.round((totalTokens / contextWindow) * 1000) / 10 : 0
|
|
129
|
-
return { inputTokens, estimatedInputTokens, knownInputTokens: knownInput, reservedOutputTokens, totalTokens, contextWindow, percent }
|
|
130
|
-
}
|
|
131
|
-
|
|
132
68
|
function isUserMessage(message) {
|
|
133
69
|
return message?.role === 'user' || message?.role === 'user-with-attachments'
|
|
134
70
|
}
|
|
@@ -220,11 +156,29 @@ export function estimateSessionContextUsage(session, messages = session?.agent?.
|
|
|
220
156
|
const sourceMessages = Array.isArray(messages) ? messages : []
|
|
221
157
|
const contextWindow = Number(session.model?.contextWindow) || 0
|
|
222
158
|
if (sourceMessages.length === 0) {
|
|
223
|
-
return {
|
|
159
|
+
return {
|
|
160
|
+
inputTokens: 0,
|
|
161
|
+
estimatedInputTokens: 0,
|
|
162
|
+
knownInputTokens: 0,
|
|
163
|
+
inputTokenSource: 'estimated',
|
|
164
|
+
reservedOutputTokens: 0,
|
|
165
|
+
totalTokens: 0,
|
|
166
|
+
contextWindow,
|
|
167
|
+
percent: 0,
|
|
168
|
+
isCompacted: false,
|
|
169
|
+
originalMessageCount: 0,
|
|
170
|
+
effectiveMessageCount: 0,
|
|
171
|
+
breakdown: {
|
|
172
|
+
systemPromptTokens: 0,
|
|
173
|
+
messagesTokens: 0,
|
|
174
|
+
toolsTokens: 0,
|
|
175
|
+
reservedOutputTokens: 0,
|
|
176
|
+
},
|
|
177
|
+
}
|
|
224
178
|
}
|
|
225
179
|
|
|
226
|
-
// Cache by input identity.
|
|
227
|
-
//
|
|
180
|
+
// Cache by input identity. Context usage delegates message token estimation
|
|
181
|
+
// to pi-agent-core and JSON-stringifies the full tools array, but its
|
|
228
182
|
// inputs (messages, model, systemPrompt, tools, contextCompaction) are stable
|
|
229
183
|
// within a run and only change on discrete events (message_end, tool result,
|
|
230
184
|
// compaction). Reference equality makes the cache check essentially free, so
|
|
@@ -255,14 +209,18 @@ export function estimateSessionContextUsage(session, messages = session?.agent?.
|
|
|
255
209
|
}
|
|
256
210
|
|
|
257
211
|
const loopMessages = buildAutoCompactLoopMessages(session, sourceMessages)
|
|
258
|
-
const knownInputTokens = latestKnownInputTokens(sourceMessages, latestCompactTimestampMs(session))
|
|
259
212
|
const value = estimateContextUsage({
|
|
260
213
|
systemPrompt: session.agent.state.systemPrompt,
|
|
261
214
|
messages: loopMessages,
|
|
262
215
|
tools: session.agent.state.tools,
|
|
263
216
|
model: session.model,
|
|
264
|
-
knownInputTokens,
|
|
265
217
|
})
|
|
218
|
+
value.isCompacted = loopMessages !== sourceMessages
|
|
219
|
+
value.originalMessageCount = sourceMessages.length
|
|
220
|
+
value.effectiveMessageCount = loopMessages.length
|
|
221
|
+
if (session.contextCompaction?.summaryMessage) {
|
|
222
|
+
value.compactedUpToIndex = Math.min(sourceMessages.length, Math.max(0, Number(session.contextCompaction.compactedUpToIndex) || 0))
|
|
223
|
+
}
|
|
266
224
|
|
|
267
225
|
session._contextUsageCache = { key: cacheKey, value }
|
|
268
226
|
return value
|
|
@@ -275,16 +233,14 @@ export async function maybeAutoCompactSession({ session, messages, signal, emitS
|
|
|
275
233
|
if (signal?.aborted) return { compacted: false, reason: 'aborted' }
|
|
276
234
|
|
|
277
235
|
const loopMessages = buildAutoCompactLoopMessages(session, messages)
|
|
278
|
-
const knownInputTokens = latestKnownInputTokens(messages, latestCompactTimestampMs(session))
|
|
279
236
|
const usage = estimateContextUsage({
|
|
280
237
|
systemPrompt: session.agent.state.systemPrompt,
|
|
281
238
|
messages: loopMessages,
|
|
282
239
|
tools: session.agent.state.tools,
|
|
283
240
|
model: session.model,
|
|
284
|
-
knownInputTokens,
|
|
285
241
|
})
|
|
286
242
|
if (!usage.contextWindow) return { compacted: false, usage, reason: 'missing_context_window' }
|
|
287
|
-
if (usage
|
|
243
|
+
if (!shouldCompactContextByPercent(usage, settings.thresholdPercent)) return { compacted: false, usage, reason: 'below_threshold' }
|
|
288
244
|
if (shouldSuppressAfterRejection(session, messages, usage)) return { compacted: false, usage, reason: 'user_rejected_recently' }
|
|
289
245
|
|
|
290
246
|
const now = Date.now()
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import {
|
|
2
|
+
estimateContextTokens,
|
|
3
|
+
estimateTokens,
|
|
4
|
+
shouldCompact,
|
|
5
|
+
} from '@earendil-works/pi-agent-core'
|
|
6
|
+
|
|
7
|
+
function safeJson(value) {
|
|
8
|
+
try {
|
|
9
|
+
return JSON.stringify(value)
|
|
10
|
+
} catch {
|
|
11
|
+
return ''
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function normalizeMessageForTokenEstimate(message) {
|
|
16
|
+
if (!message || typeof message !== 'object') return message
|
|
17
|
+
if (message.role !== 'user-with-attachments') return message
|
|
18
|
+
|
|
19
|
+
const content = typeof message.content === 'string'
|
|
20
|
+
? [{ type: 'text', text: message.content }]
|
|
21
|
+
: Array.isArray(message.content)
|
|
22
|
+
? [...message.content]
|
|
23
|
+
: []
|
|
24
|
+
|
|
25
|
+
if (Array.isArray(message.attachments)) {
|
|
26
|
+
for (const attachment of message.attachments) {
|
|
27
|
+
if (attachment?.type === 'image' && attachment.content) {
|
|
28
|
+
content.push({ type: 'image', data: attachment.content, mimeType: attachment.mimeType })
|
|
29
|
+
} else if (attachment?.type === 'document' && attachment.extractedText) {
|
|
30
|
+
content.push({ type: 'text', text: `\n\n[Document: ${attachment.fileName || 'Untitled'}]\n${attachment.extractedText}` })
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return { ...message, role: 'user', content }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function normalizeMessagesForTokenEstimate(messages) {
|
|
39
|
+
return (Array.isArray(messages) ? messages : []).map(normalizeMessageForTokenEstimate)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function textTokens(text) {
|
|
43
|
+
if (!text) return 0
|
|
44
|
+
return estimateTokens({ role: 'user', content: String(text), timestamp: 0 })
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function localMessagesTokens(messages) {
|
|
48
|
+
return normalizeMessagesForTokenEstimate(messages).reduce((total, message) => total + estimateTokens(message), 0)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function estimateContextUsage({ systemPrompt, messages, tools, model }) {
|
|
52
|
+
const contextWindow = Number(model?.contextWindow) || 0
|
|
53
|
+
const reservedOutputTokens = Math.max(0, Number(model?.maxTokens) || 4096)
|
|
54
|
+
const normalizedMessages = normalizeMessagesForTokenEstimate(messages)
|
|
55
|
+
const coreEstimate = estimateContextTokens(normalizedMessages)
|
|
56
|
+
const systemPromptTokens = textTokens(systemPrompt)
|
|
57
|
+
const toolsTokens = textTokens(safeJson(tools))
|
|
58
|
+
const messagesTokens = localMessagesTokens(normalizedMessages)
|
|
59
|
+
const estimatedInputTokens = systemPromptTokens + messagesTokens + toolsTokens
|
|
60
|
+
const providerBasedContextTokens = Math.max(0, Number(coreEstimate.usageTokens) || 0) > 0
|
|
61
|
+
? Math.max(0, Number(coreEstimate.tokens) || 0)
|
|
62
|
+
: 0
|
|
63
|
+
const inputTokens = providerBasedContextTokens > 0
|
|
64
|
+
? Math.max(estimatedInputTokens, providerBasedContextTokens)
|
|
65
|
+
: estimatedInputTokens
|
|
66
|
+
const totalTokens = inputTokens + reservedOutputTokens
|
|
67
|
+
const percent = contextWindow > 0 ? Math.round((totalTokens / contextWindow) * 1000) / 10 : 0
|
|
68
|
+
const inputTokenSource = providerBasedContextTokens > 0
|
|
69
|
+
? providerBasedContextTokens >= estimatedInputTokens ? 'provider' : 'mixed'
|
|
70
|
+
: 'estimated'
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
inputTokens,
|
|
74
|
+
estimatedInputTokens,
|
|
75
|
+
knownInputTokens: providerBasedContextTokens,
|
|
76
|
+
providerContextTokens: providerBasedContextTokens,
|
|
77
|
+
inputTokenSource,
|
|
78
|
+
reservedOutputTokens,
|
|
79
|
+
totalTokens,
|
|
80
|
+
contextWindow,
|
|
81
|
+
percent,
|
|
82
|
+
breakdown: {
|
|
83
|
+
systemPromptTokens,
|
|
84
|
+
messagesTokens,
|
|
85
|
+
toolsTokens,
|
|
86
|
+
reservedOutputTokens,
|
|
87
|
+
providerUsageTokens: Math.max(0, Number(coreEstimate.usageTokens) || 0),
|
|
88
|
+
trailingTokens: Math.max(0, Number(coreEstimate.trailingTokens) || 0),
|
|
89
|
+
lastUsageIndex: coreEstimate.lastUsageIndex,
|
|
90
|
+
localEstimatedContextTokens: estimatedInputTokens,
|
|
91
|
+
},
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function shouldCompactContextByPercent(usage, thresholdPercent) {
|
|
96
|
+
const contextWindow = Number(usage?.contextWindow) || 0
|
|
97
|
+
const totalTokens = Math.max(0, Number(usage?.totalTokens) || 0)
|
|
98
|
+
const threshold = Math.min(100, Math.max(0, Number(thresholdPercent) || 0))
|
|
99
|
+
if (!contextWindow) return false
|
|
100
|
+
|
|
101
|
+
const thresholdTokens = Math.ceil(contextWindow * threshold / 100)
|
|
102
|
+
const reserveTokens = Math.min(contextWindow, Math.max(0, contextWindow - thresholdTokens + 1))
|
|
103
|
+
return shouldCompact(totalTokens, contextWindow, {
|
|
104
|
+
enabled: true,
|
|
105
|
+
reserveTokens,
|
|
106
|
+
keepRecentTokens: 0,
|
|
107
|
+
})
|
|
108
|
+
}
|