@smartmemory/compose 0.1.19-beta → 0.1.21-beta

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 (61) hide show
  1. package/bin/backfill-feature-groups.js +44 -0
  2. package/dist/assets/{_baseUniq-QNhBl_9Q.js → _baseUniq-BoC7tHWD.js} +1 -1
  3. package/dist/assets/{arc-CSjW4ScB.js → arc-DG-LrgfX.js} +1 -1
  4. package/dist/assets/{architectureDiagram-Q4EWVU46-DR5rByeQ.js → architectureDiagram-Q4EWVU46-BXZQWzDu.js} +1 -1
  5. package/dist/assets/{blockDiagram-DXYQGD6D-B5LT7yiK.js → blockDiagram-DXYQGD6D-C9qnuluR.js} +1 -1
  6. package/dist/assets/{c4Diagram-AHTNJAMY-DJClEyPg.js → c4Diagram-AHTNJAMY-DYEMaJ7d.js} +1 -1
  7. package/dist/assets/channel-BGcvsSwM.js +1 -0
  8. package/dist/assets/{chunk-4BX2VUAB-f2X6ZPy3.js → chunk-4BX2VUAB-DlmXAtxq.js} +1 -1
  9. package/dist/assets/{chunk-4TB4RGXK-D1Trzzjy.js → chunk-4TB4RGXK-B1lSlMg_.js} +1 -1
  10. package/dist/assets/{chunk-55IACEB6-B_neChv-.js → chunk-55IACEB6-DJPSJwK0.js} +1 -1
  11. package/dist/assets/{chunk-EDXVE4YY-HBFulheC.js → chunk-EDXVE4YY-CvhTiFdk.js} +1 -1
  12. package/dist/assets/{chunk-FMBD7UC4-Dq0S7mgY.js → chunk-FMBD7UC4-B_zWHn94.js} +1 -1
  13. package/dist/assets/{chunk-OYMX7WX6-CmCV5icO.js → chunk-OYMX7WX6-DKQK-sUj.js} +1 -1
  14. package/dist/assets/{chunk-QZHKN3VN-CLOxZqIy.js → chunk-QZHKN3VN-CEE-OaBX.js} +1 -1
  15. package/dist/assets/{chunk-YZCP3GAM-BaMX2_No.js → chunk-YZCP3GAM-BYSMlTyG.js} +1 -1
  16. package/dist/assets/classDiagram-6PBFFD2Q-CfQNM6xw.js +1 -0
  17. package/dist/assets/classDiagram-v2-HSJHXN6E-CfQNM6xw.js +1 -0
  18. package/dist/assets/clone-LLYc7OPp.js +1 -0
  19. package/dist/assets/{cose-bilkent-S5V4N54A-dJkv3nTB.js → cose-bilkent-S5V4N54A-BLsO77pR.js} +1 -1
  20. package/dist/assets/{dagre-KV5264BT-BMLwQ7Vp.js → dagre-KV5264BT-h3fBz2A7.js} +1 -1
  21. package/dist/assets/{diagram-5BDNPKRD-DQxnkGXY.js → diagram-5BDNPKRD-Bjfjr222.js} +1 -1
  22. package/dist/assets/{diagram-G4DWMVQ6-3IjUBYPi.js → diagram-G4DWMVQ6-BUsxr5F4.js} +1 -1
  23. package/dist/assets/{diagram-MMDJMWI5-BwAWFCz7.js → diagram-MMDJMWI5-tTPyzsqS.js} +1 -1
  24. package/dist/assets/{diagram-TYMM5635-D-hA5Yi9.js → diagram-TYMM5635-Qt3hgXx7.js} +1 -1
  25. package/dist/assets/{erDiagram-SMLLAGMA-B7l-0L4L.js → erDiagram-SMLLAGMA-BLpKb0ir.js} +1 -1
  26. package/dist/assets/{flowDiagram-DWJPFMVM-BiUBONun.js → flowDiagram-DWJPFMVM-CGxUXnwU.js} +1 -1
  27. package/dist/assets/{ganttDiagram-T4ZO3ILL-GaehJEQH.js → ganttDiagram-T4ZO3ILL-svDtLm_7.js} +1 -1
  28. package/dist/assets/{gitGraphDiagram-UUTBAWPF-JTBfdwux.js → gitGraphDiagram-UUTBAWPF-DjCn5PgG.js} +1 -1
  29. package/dist/assets/{graph-CMQluXQ6.js → graph-B0vICnHf.js} +1 -1
  30. package/dist/assets/{index-DNrB2NcO.js → index-CYFzqfu6.js} +78 -78
  31. package/dist/assets/{infoDiagram-42DDH7IO-SwFX4yEg.js → infoDiagram-42DDH7IO-X0xPs5QF.js} +1 -1
  32. package/dist/assets/{ishikawaDiagram-UXIWVN3A-IMoXnZOl.js → ishikawaDiagram-UXIWVN3A-Hpx73hmV.js} +1 -1
  33. package/dist/assets/{journeyDiagram-VCZTEJTY-IR21xpjG.js → journeyDiagram-VCZTEJTY-DK2AuNw9.js} +1 -1
  34. package/dist/assets/{kanban-definition-6JOO6SKY-ROw3Xl42.js → kanban-definition-6JOO6SKY-MSReBfQ_.js} +1 -1
  35. package/dist/assets/{layout-8gmAR0ZJ.js → layout-BzyY99nS.js} +1 -1
  36. package/dist/assets/{linear-J25X-Fjt.js → linear-DF7hvPAA.js} +1 -1
  37. package/dist/assets/{min-B0et5zsQ.js → min-CmTsklHj.js} +1 -1
  38. package/dist/assets/{mindmap-definition-QFDTVHPH-DMrUjEfY.js → mindmap-definition-QFDTVHPH-Bv_MqqRT.js} +1 -1
  39. package/dist/assets/{pieDiagram-DEJITSTG-B7wt8-Cg.js → pieDiagram-DEJITSTG-gFZqmEu5.js} +1 -1
  40. package/dist/assets/{quadrantDiagram-34T5L4WZ-Dzm5zyw2.js → quadrantDiagram-34T5L4WZ-zJ1Dd8HZ.js} +1 -1
  41. package/dist/assets/{requirementDiagram-MS252O5E-ktCd4N3K.js → requirementDiagram-MS252O5E-BOdFVKqL.js} +1 -1
  42. package/dist/assets/{sankeyDiagram-XADWPNL6-DMMGkg6J.js → sankeyDiagram-XADWPNL6-C4kqCTfK.js} +1 -1
  43. package/dist/assets/{sequenceDiagram-FGHM5R23-CpJIWks2.js → sequenceDiagram-FGHM5R23-IcnsFzyn.js} +1 -1
  44. package/dist/assets/{stateDiagram-FHFEXIEX-BpEQU369.js → stateDiagram-FHFEXIEX-BLTHoa1t.js} +1 -1
  45. package/dist/assets/stateDiagram-v2-QKLJ7IA2-BU3NkBzE.js +1 -0
  46. package/dist/assets/{timeline-definition-GMOUNBTQ-CZrQGVo8.js → timeline-definition-GMOUNBTQ-PUbpkePR.js} +1 -1
  47. package/dist/assets/{vennDiagram-DHZGUBPP-Yx3OZYj1.js → vennDiagram-DHZGUBPP-BgBJOxvA.js} +1 -1
  48. package/dist/assets/{wardley-RL74JXVD-D3Q_ZgB4.js → wardley-RL74JXVD-CU7pJZZ7.js} +1 -1
  49. package/dist/assets/{wardleyDiagram-NUSXRM2D-D56cV-10.js → wardleyDiagram-NUSXRM2D-zvmTSinR.js} +1 -1
  50. package/dist/assets/{xychartDiagram-5P7HB3ND-75UcLBih.js → xychartDiagram-5P7HB3ND-DAqWimOO.js} +1 -1
  51. package/dist/index.html +1 -1
  52. package/package.json +1 -1
  53. package/server/feature-scan.js +96 -1
  54. package/server/graph-layout-routes.js +80 -0
  55. package/server/index.js +2 -0
  56. package/server/vision-routes.js +10 -0
  57. package/dist/assets/channel-CoIe6z-P.js +0 -1
  58. package/dist/assets/classDiagram-6PBFFD2Q-hDYPid8n.js +0 -1
  59. package/dist/assets/classDiagram-v2-HSJHXN6E-hDYPid8n.js +0 -1
  60. package/dist/assets/clone-BnzLFmYo.js +0 -1
  61. package/dist/assets/stateDiagram-v2-QKLJ7IA2-B7zBx6Bf.js +0 -1
@@ -1,4 +1,4 @@
1
- import{s as gi,g as xi,q as Xt,p as di,a as fi,b as pi,_ as a,l as Yt,I as mi,e as yi,z as bi,D as _t,i as Ai,F as Nt,G as wi,K as Ci,aH as Si,R as Wt}from"./index-DNrB2NcO.js";import{i as _i}from"./init-Gi6I4Gst.js";import{o as ki}from"./ordinal-Cboi1Yqb.js";import{l as zt}from"./linear-J25X-Fjt.js";import"./defaultLocale-DX6XiGOO.js";function Ri(e,t,i){e=+e,t=+t,i=(n=arguments.length)<2?(t=e,e=0,1):n<3?1:+i;for(var s=-1,n=Math.max(0,Math.ceil((t-e)/i))|0,o=new Array(n);++s<n;)o[s]=e+s*i;return o}function bt(){var e=ki().unknown(void 0),t=e.domain,i=e.range,s=0,n=1,o,u,p=!1,f=0,T=0,P=.5;delete e.unknown;function _(){var y=t().length,E=n<s,v=E?n:s,L=E?s:n;o=(L-v)/Math.max(1,y-f+T*2),p&&(o=Math.floor(o)),v+=(L-v-o*(y-f))*P,u=o*(1-f),p&&(v=Math.round(v),u=Math.round(u));var I=Ri(y).map(function(m){return v+o*m});return i(E?I.reverse():I)}return e.domain=function(y){return arguments.length?(t(y),_()):t()},e.range=function(y){return arguments.length?([s,n]=y,s=+s,n=+n,_()):[s,n]},e.rangeRound=function(y){return[s,n]=y,s=+s,n=+n,p=!0,_()},e.bandwidth=function(){return u},e.step=function(){return o},e.round=function(y){return arguments.length?(p=!!y,_()):p},e.padding=function(y){return arguments.length?(f=Math.min(1,T=+y),_()):f},e.paddingInner=function(y){return arguments.length?(f=Math.min(1,y),_()):f},e.paddingOuter=function(y){return arguments.length?(T=+y,_()):T},e.align=function(y){return arguments.length?(P=Math.max(0,Math.min(1,y)),_()):P},e.copy=function(){return bt(t(),[s,n]).round(p).paddingInner(f).paddingOuter(T).align(P)},_i.apply(_(),arguments)}var At=(function(){var e=a(function(F,h,c,g){for(c=c||{},g=F.length;g--;c[F[g]]=h);return c},"o"),t=[1,10,12,14,16,18,19,21,23],i=[2,6],s=[1,3],n=[1,5],o=[1,6],u=[1,7],p=[1,5,10,12,14,16,18,19,21,23,34,35,36],f=[1,25],T=[1,26],P=[1,28],_=[1,29],y=[1,30],E=[1,31],v=[1,32],L=[1,33],I=[1,34],m=[1,35],R=[1,36],l=[1,37],W=[1,43],O=[1,42],X=[1,47],Y=[1,50],S=[1,10,12,14,16,18,19,21,23,34,35,36],U=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36],b=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36,41,42,43,44,45,46,47,48,49,50],w=[1,64],V={trace:a(function(){},"trace"),yy:{},symbols_:{error:2,start:3,eol:4,XYCHART:5,chartConfig:6,document:7,CHART_ORIENTATION:8,statement:9,title:10,text:11,X_AXIS:12,parseXAxis:13,Y_AXIS:14,parseYAxis:15,LINE:16,plotData:17,BAR:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,SQUARE_BRACES_START:24,commaSeparatedNumbers:25,SQUARE_BRACES_END:26,NUMBER_WITH_DECIMAL:27,COMMA:28,xAxisData:29,bandData:30,ARROW_DELIMITER:31,commaSeparatedTexts:32,yAxisData:33,NEWLINE:34,SEMI:35,EOF:36,alphaNum:37,STR:38,MD_STR:39,alphaNumToken:40,AMP:41,NUM:42,ALPHA:43,PLUS:44,EQUALS:45,MULT:46,DOT:47,BRKT:48,MINUS:49,UNDERSCORE:50,$accept:0,$end:1},terminals_:{2:"error",5:"XYCHART",8:"CHART_ORIENTATION",10:"title",12:"X_AXIS",14:"Y_AXIS",16:"LINE",18:"BAR",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"SQUARE_BRACES_START",26:"SQUARE_BRACES_END",27:"NUMBER_WITH_DECIMAL",28:"COMMA",31:"ARROW_DELIMITER",34:"NEWLINE",35:"SEMI",36:"EOF",38:"STR",39:"MD_STR",41:"AMP",42:"NUM",43:"ALPHA",44:"PLUS",45:"EQUALS",46:"MULT",47:"DOT",48:"BRKT",49:"MINUS",50:"UNDERSCORE"},productions_:[0,[3,2],[3,3],[3,2],[3,1],[6,1],[7,0],[7,2],[9,2],[9,2],[9,2],[9,2],[9,2],[9,3],[9,2],[9,3],[9,2],[9,2],[9,1],[17,3],[25,3],[25,1],[13,1],[13,2],[13,1],[29,1],[29,3],[30,3],[32,3],[32,1],[15,1],[15,2],[15,1],[33,3],[4,1],[4,1],[4,1],[11,1],[11,1],[11,1],[37,1],[37,2],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1]],performAction:a(function(h,c,g,x,C,r,rt){var d=r.length-1;switch(C){case 5:x.setOrientation(r[d]);break;case 9:x.setDiagramTitle(r[d].text.trim());break;case 12:x.setLineData({text:"",type:"text"},r[d]);break;case 13:x.setLineData(r[d-1],r[d]);break;case 14:x.setBarData({text:"",type:"text"},r[d]);break;case 15:x.setBarData(r[d-1],r[d]);break;case 16:this.$=r[d].trim(),x.setAccTitle(this.$);break;case 17:case 18:this.$=r[d].trim(),x.setAccDescription(this.$);break;case 19:this.$=r[d-1];break;case 20:this.$=[Number(r[d-2]),...r[d]];break;case 21:this.$=[Number(r[d])];break;case 22:x.setXAxisTitle(r[d]);break;case 23:x.setXAxisTitle(r[d-1]);break;case 24:x.setXAxisTitle({type:"text",text:""});break;case 25:x.setXAxisBand(r[d]);break;case 26:x.setXAxisRangeData(Number(r[d-2]),Number(r[d]));break;case 27:this.$=r[d-1];break;case 28:this.$=[r[d-2],...r[d]];break;case 29:this.$=[r[d]];break;case 30:x.setYAxisTitle(r[d]);break;case 31:x.setYAxisTitle(r[d-1]);break;case 32:x.setYAxisTitle({type:"text",text:""});break;case 33:x.setYAxisRangeData(Number(r[d-2]),Number(r[d]));break;case 37:this.$={text:r[d],type:"text"};break;case 38:this.$={text:r[d],type:"text"};break;case 39:this.$={text:r[d],type:"markdown"};break;case 40:this.$=r[d];break;case 41:this.$=r[d-1]+""+r[d];break}},"anonymous"),table:[e(t,i,{3:1,4:2,7:4,5:s,34:n,35:o,36:u}),{1:[3]},e(t,i,{4:2,7:4,3:8,5:s,34:n,35:o,36:u}),e(t,i,{4:2,7:4,6:9,3:10,5:s,8:[1,11],34:n,35:o,36:u}),{1:[2,4],9:12,10:[1,13],12:[1,14],14:[1,15],16:[1,16],18:[1,17],19:[1,18],21:[1,19],23:[1,20]},e(p,[2,34]),e(p,[2,35]),e(p,[2,36]),{1:[2,1]},e(t,i,{4:2,7:4,3:21,5:s,34:n,35:o,36:u}),{1:[2,3]},e(p,[2,5]),e(t,[2,7],{4:22,34:n,35:o,36:u}),{11:23,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},{11:39,13:38,24:W,27:O,29:40,30:41,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},{11:45,15:44,27:X,33:46,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},{11:49,17:48,24:Y,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},{11:52,17:51,24:Y,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},{20:[1,53]},{22:[1,54]},e(S,[2,18]),{1:[2,2]},e(S,[2,8]),e(S,[2,9]),e(U,[2,37],{40:55,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l}),e(U,[2,38]),e(U,[2,39]),e(b,[2,40]),e(b,[2,42]),e(b,[2,43]),e(b,[2,44]),e(b,[2,45]),e(b,[2,46]),e(b,[2,47]),e(b,[2,48]),e(b,[2,49]),e(b,[2,50]),e(b,[2,51]),e(S,[2,10]),e(S,[2,22],{30:41,29:56,24:W,27:O}),e(S,[2,24]),e(S,[2,25]),{31:[1,57]},{11:59,32:58,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},e(S,[2,11]),e(S,[2,30],{33:60,27:X}),e(S,[2,32]),{31:[1,61]},e(S,[2,12]),{17:62,24:Y},{25:63,27:w},e(S,[2,14]),{17:65,24:Y},e(S,[2,16]),e(S,[2,17]),e(b,[2,41]),e(S,[2,23]),{27:[1,66]},{26:[1,67]},{26:[2,29],28:[1,68]},e(S,[2,31]),{27:[1,69]},e(S,[2,13]),{26:[1,70]},{26:[2,21],28:[1,71]},e(S,[2,15]),e(S,[2,26]),e(S,[2,27]),{11:59,32:72,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},e(S,[2,33]),e(S,[2,19]),{25:73,27:w},{26:[2,28]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],72:[2,28],73:[2,20]},parseError:a(function(h,c){if(c.recoverable)this.trace(h);else{var g=new Error(h);throw g.hash=c,g}},"parseError"),parse:a(function(h){var c=this,g=[0],x=[],C=[null],r=[],rt=this.table,d="",ct=0,It=0,hi=2,Mt=1,li=r.slice.call(arguments,1),D=Object.create(this.lexer),$={yy:{}};for(var ft in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ft)&&($.yy[ft]=this.yy[ft]);D.setInput(h,$.yy),$.yy.lexer=D,$.yy.parser=this,typeof D.yylloc>"u"&&(D.yylloc={});var pt=D.yylloc;r.push(pt);var ci=D.options&&D.options.ranges;typeof $.yy.parseError=="function"?this.parseError=$.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function ui(B){g.length=g.length-2*B,C.length=C.length-B,r.length=r.length-B}a(ui,"popStack");function Vt(){var B;return B=x.pop()||D.lex()||Mt,typeof B!="number"&&(B instanceof Array&&(x=B,B=x.pop()),B=c.symbols_[B]||B),B}a(Vt,"lex");for(var M,q,z,mt,G={},ut,N,Bt,gt;;){if(q=g[g.length-1],this.defaultActions[q]?z=this.defaultActions[q]:((M===null||typeof M>"u")&&(M=Vt()),z=rt[q]&&rt[q][M]),typeof z>"u"||!z.length||!z[0]){var yt="";gt=[];for(ut in rt[q])this.terminals_[ut]&&ut>hi&&gt.push("'"+this.terminals_[ut]+"'");D.showPosition?yt="Parse error on line "+(ct+1)+`:
1
+ import{s as gi,g as xi,q as Xt,p as di,a as fi,b as pi,_ as a,l as Yt,I as mi,e as yi,z as bi,D as _t,i as Ai,F as Nt,G as wi,K as Ci,aH as Si,R as Wt}from"./index-CYFzqfu6.js";import{i as _i}from"./init-Gi6I4Gst.js";import{o as ki}from"./ordinal-Cboi1Yqb.js";import{l as zt}from"./linear-DF7hvPAA.js";import"./defaultLocale-DX6XiGOO.js";function Ri(e,t,i){e=+e,t=+t,i=(n=arguments.length)<2?(t=e,e=0,1):n<3?1:+i;for(var s=-1,n=Math.max(0,Math.ceil((t-e)/i))|0,o=new Array(n);++s<n;)o[s]=e+s*i;return o}function bt(){var e=ki().unknown(void 0),t=e.domain,i=e.range,s=0,n=1,o,u,p=!1,f=0,T=0,P=.5;delete e.unknown;function _(){var y=t().length,E=n<s,v=E?n:s,L=E?s:n;o=(L-v)/Math.max(1,y-f+T*2),p&&(o=Math.floor(o)),v+=(L-v-o*(y-f))*P,u=o*(1-f),p&&(v=Math.round(v),u=Math.round(u));var I=Ri(y).map(function(m){return v+o*m});return i(E?I.reverse():I)}return e.domain=function(y){return arguments.length?(t(y),_()):t()},e.range=function(y){return arguments.length?([s,n]=y,s=+s,n=+n,_()):[s,n]},e.rangeRound=function(y){return[s,n]=y,s=+s,n=+n,p=!0,_()},e.bandwidth=function(){return u},e.step=function(){return o},e.round=function(y){return arguments.length?(p=!!y,_()):p},e.padding=function(y){return arguments.length?(f=Math.min(1,T=+y),_()):f},e.paddingInner=function(y){return arguments.length?(f=Math.min(1,y),_()):f},e.paddingOuter=function(y){return arguments.length?(T=+y,_()):T},e.align=function(y){return arguments.length?(P=Math.max(0,Math.min(1,y)),_()):P},e.copy=function(){return bt(t(),[s,n]).round(p).paddingInner(f).paddingOuter(T).align(P)},_i.apply(_(),arguments)}var At=(function(){var e=a(function(F,h,c,g){for(c=c||{},g=F.length;g--;c[F[g]]=h);return c},"o"),t=[1,10,12,14,16,18,19,21,23],i=[2,6],s=[1,3],n=[1,5],o=[1,6],u=[1,7],p=[1,5,10,12,14,16,18,19,21,23,34,35,36],f=[1,25],T=[1,26],P=[1,28],_=[1,29],y=[1,30],E=[1,31],v=[1,32],L=[1,33],I=[1,34],m=[1,35],R=[1,36],l=[1,37],W=[1,43],O=[1,42],X=[1,47],Y=[1,50],S=[1,10,12,14,16,18,19,21,23,34,35,36],U=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36],b=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36,41,42,43,44,45,46,47,48,49,50],w=[1,64],V={trace:a(function(){},"trace"),yy:{},symbols_:{error:2,start:3,eol:4,XYCHART:5,chartConfig:6,document:7,CHART_ORIENTATION:8,statement:9,title:10,text:11,X_AXIS:12,parseXAxis:13,Y_AXIS:14,parseYAxis:15,LINE:16,plotData:17,BAR:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,SQUARE_BRACES_START:24,commaSeparatedNumbers:25,SQUARE_BRACES_END:26,NUMBER_WITH_DECIMAL:27,COMMA:28,xAxisData:29,bandData:30,ARROW_DELIMITER:31,commaSeparatedTexts:32,yAxisData:33,NEWLINE:34,SEMI:35,EOF:36,alphaNum:37,STR:38,MD_STR:39,alphaNumToken:40,AMP:41,NUM:42,ALPHA:43,PLUS:44,EQUALS:45,MULT:46,DOT:47,BRKT:48,MINUS:49,UNDERSCORE:50,$accept:0,$end:1},terminals_:{2:"error",5:"XYCHART",8:"CHART_ORIENTATION",10:"title",12:"X_AXIS",14:"Y_AXIS",16:"LINE",18:"BAR",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"SQUARE_BRACES_START",26:"SQUARE_BRACES_END",27:"NUMBER_WITH_DECIMAL",28:"COMMA",31:"ARROW_DELIMITER",34:"NEWLINE",35:"SEMI",36:"EOF",38:"STR",39:"MD_STR",41:"AMP",42:"NUM",43:"ALPHA",44:"PLUS",45:"EQUALS",46:"MULT",47:"DOT",48:"BRKT",49:"MINUS",50:"UNDERSCORE"},productions_:[0,[3,2],[3,3],[3,2],[3,1],[6,1],[7,0],[7,2],[9,2],[9,2],[9,2],[9,2],[9,2],[9,3],[9,2],[9,3],[9,2],[9,2],[9,1],[17,3],[25,3],[25,1],[13,1],[13,2],[13,1],[29,1],[29,3],[30,3],[32,3],[32,1],[15,1],[15,2],[15,1],[33,3],[4,1],[4,1],[4,1],[11,1],[11,1],[11,1],[37,1],[37,2],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1]],performAction:a(function(h,c,g,x,C,r,rt){var d=r.length-1;switch(C){case 5:x.setOrientation(r[d]);break;case 9:x.setDiagramTitle(r[d].text.trim());break;case 12:x.setLineData({text:"",type:"text"},r[d]);break;case 13:x.setLineData(r[d-1],r[d]);break;case 14:x.setBarData({text:"",type:"text"},r[d]);break;case 15:x.setBarData(r[d-1],r[d]);break;case 16:this.$=r[d].trim(),x.setAccTitle(this.$);break;case 17:case 18:this.$=r[d].trim(),x.setAccDescription(this.$);break;case 19:this.$=r[d-1];break;case 20:this.$=[Number(r[d-2]),...r[d]];break;case 21:this.$=[Number(r[d])];break;case 22:x.setXAxisTitle(r[d]);break;case 23:x.setXAxisTitle(r[d-1]);break;case 24:x.setXAxisTitle({type:"text",text:""});break;case 25:x.setXAxisBand(r[d]);break;case 26:x.setXAxisRangeData(Number(r[d-2]),Number(r[d]));break;case 27:this.$=r[d-1];break;case 28:this.$=[r[d-2],...r[d]];break;case 29:this.$=[r[d]];break;case 30:x.setYAxisTitle(r[d]);break;case 31:x.setYAxisTitle(r[d-1]);break;case 32:x.setYAxisTitle({type:"text",text:""});break;case 33:x.setYAxisRangeData(Number(r[d-2]),Number(r[d]));break;case 37:this.$={text:r[d],type:"text"};break;case 38:this.$={text:r[d],type:"text"};break;case 39:this.$={text:r[d],type:"markdown"};break;case 40:this.$=r[d];break;case 41:this.$=r[d-1]+""+r[d];break}},"anonymous"),table:[e(t,i,{3:1,4:2,7:4,5:s,34:n,35:o,36:u}),{1:[3]},e(t,i,{4:2,7:4,3:8,5:s,34:n,35:o,36:u}),e(t,i,{4:2,7:4,6:9,3:10,5:s,8:[1,11],34:n,35:o,36:u}),{1:[2,4],9:12,10:[1,13],12:[1,14],14:[1,15],16:[1,16],18:[1,17],19:[1,18],21:[1,19],23:[1,20]},e(p,[2,34]),e(p,[2,35]),e(p,[2,36]),{1:[2,1]},e(t,i,{4:2,7:4,3:21,5:s,34:n,35:o,36:u}),{1:[2,3]},e(p,[2,5]),e(t,[2,7],{4:22,34:n,35:o,36:u}),{11:23,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},{11:39,13:38,24:W,27:O,29:40,30:41,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},{11:45,15:44,27:X,33:46,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},{11:49,17:48,24:Y,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},{11:52,17:51,24:Y,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},{20:[1,53]},{22:[1,54]},e(S,[2,18]),{1:[2,2]},e(S,[2,8]),e(S,[2,9]),e(U,[2,37],{40:55,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l}),e(U,[2,38]),e(U,[2,39]),e(b,[2,40]),e(b,[2,42]),e(b,[2,43]),e(b,[2,44]),e(b,[2,45]),e(b,[2,46]),e(b,[2,47]),e(b,[2,48]),e(b,[2,49]),e(b,[2,50]),e(b,[2,51]),e(S,[2,10]),e(S,[2,22],{30:41,29:56,24:W,27:O}),e(S,[2,24]),e(S,[2,25]),{31:[1,57]},{11:59,32:58,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},e(S,[2,11]),e(S,[2,30],{33:60,27:X}),e(S,[2,32]),{31:[1,61]},e(S,[2,12]),{17:62,24:Y},{25:63,27:w},e(S,[2,14]),{17:65,24:Y},e(S,[2,16]),e(S,[2,17]),e(b,[2,41]),e(S,[2,23]),{27:[1,66]},{26:[1,67]},{26:[2,29],28:[1,68]},e(S,[2,31]),{27:[1,69]},e(S,[2,13]),{26:[1,70]},{26:[2,21],28:[1,71]},e(S,[2,15]),e(S,[2,26]),e(S,[2,27]),{11:59,32:72,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},e(S,[2,33]),e(S,[2,19]),{25:73,27:w},{26:[2,28]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],72:[2,28],73:[2,20]},parseError:a(function(h,c){if(c.recoverable)this.trace(h);else{var g=new Error(h);throw g.hash=c,g}},"parseError"),parse:a(function(h){var c=this,g=[0],x=[],C=[null],r=[],rt=this.table,d="",ct=0,It=0,hi=2,Mt=1,li=r.slice.call(arguments,1),D=Object.create(this.lexer),$={yy:{}};for(var ft in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ft)&&($.yy[ft]=this.yy[ft]);D.setInput(h,$.yy),$.yy.lexer=D,$.yy.parser=this,typeof D.yylloc>"u"&&(D.yylloc={});var pt=D.yylloc;r.push(pt);var ci=D.options&&D.options.ranges;typeof $.yy.parseError=="function"?this.parseError=$.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function ui(B){g.length=g.length-2*B,C.length=C.length-B,r.length=r.length-B}a(ui,"popStack");function Vt(){var B;return B=x.pop()||D.lex()||Mt,typeof B!="number"&&(B instanceof Array&&(x=B,B=x.pop()),B=c.symbols_[B]||B),B}a(Vt,"lex");for(var M,q,z,mt,G={},ut,N,Bt,gt;;){if(q=g[g.length-1],this.defaultActions[q]?z=this.defaultActions[q]:((M===null||typeof M>"u")&&(M=Vt()),z=rt[q]&&rt[q][M]),typeof z>"u"||!z.length||!z[0]){var yt="";gt=[];for(ut in rt[q])this.terminals_[ut]&&ut>hi&&gt.push("'"+this.terminals_[ut]+"'");D.showPosition?yt="Parse error on line "+(ct+1)+`:
2
2
  `+D.showPosition()+`
3
3
  Expecting `+gt.join(", ")+", got '"+(this.terminals_[M]||M)+"'":yt="Parse error on line "+(ct+1)+": Unexpected "+(M==Mt?"end of input":"'"+(this.terminals_[M]||M)+"'"),this.parseError(yt,{text:D.match,token:this.terminals_[M]||M,line:D.yylineno,loc:pt,expected:gt})}if(z[0]instanceof Array&&z.length>1)throw new Error("Parse Error: multiple actions possible at state: "+q+", token: "+M);switch(z[0]){case 1:g.push(M),C.push(D.yytext),r.push(D.yylloc),g.push(z[1]),M=null,It=D.yyleng,d=D.yytext,ct=D.yylineno,pt=D.yylloc;break;case 2:if(N=this.productions_[z[1]][1],G.$=C[C.length-N],G._$={first_line:r[r.length-(N||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(N||1)].first_column,last_column:r[r.length-1].last_column},ci&&(G._$.range=[r[r.length-(N||1)].range[0],r[r.length-1].range[1]]),mt=this.performAction.apply(G,[d,It,ct,$.yy,z[1],C,r].concat(li)),typeof mt<"u")return mt;N&&(g=g.slice(0,-1*N*2),C=C.slice(0,-1*N),r=r.slice(0,-1*N)),g.push(this.productions_[z[1]][0]),C.push(G.$),r.push(G._$),Bt=rt[g[g.length-2]][g[g.length-1]],g.push(Bt);break;case 3:return!0}}return!0},"parse")},k=(function(){var F={EOF:1,parseError:a(function(c,g){if(this.yy.parser)this.yy.parser.parseError(c,g);else throw new Error(c)},"parseError"),setInput:a(function(h,c){return this.yy=c||this.yy||{},this._input=h,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:a(function(){var h=this._input[0];this.yytext+=h,this.yyleng++,this.offset++,this.match+=h,this.matched+=h;var c=h.match(/(?:\r\n?|\n).*/g);return c?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),h},"input"),unput:a(function(h){var c=h.length,g=h.split(/(?:\r\n?|\n)/g);this._input=h+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-c),this.offset-=c;var x=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),g.length-1&&(this.yylineno-=g.length-1);var C=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:g?(g.length===x.length?this.yylloc.first_column:0)+x[x.length-g.length].length-g[0].length:this.yylloc.first_column-c},this.options.ranges&&(this.yylloc.range=[C[0],C[0]+this.yyleng-c]),this.yyleng=this.yytext.length,this},"unput"),more:a(function(){return this._more=!0,this},"more"),reject:a(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
4
4
  `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:a(function(h){this.unput(this.match.slice(h))},"less"),pastInput:a(function(){var h=this.matched.substr(0,this.matched.length-this.match.length);return(h.length>20?"...":"")+h.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:a(function(){var h=this.match;return h.length<20&&(h+=this._input.substr(0,20-h.length)),(h.substr(0,20)+(h.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:a(function(){var h=this.pastInput(),c=new Array(h.length+1).join("-");return h+this.upcomingInput()+`
package/dist/index.html CHANGED
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Compose</title>
7
- <script type="module" crossorigin src="/assets/index-DNrB2NcO.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-CYFzqfu6.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/assets/index-DKBsEUJ-.css">
9
9
  </head>
10
10
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartmemory/compose",
3
- "version": "0.1.19-beta",
3
+ "version": "0.1.21-beta",
4
4
  "description": "Structured AI dev pipeline — goal-to-product orchestration with gates, iteration loops, and feature lifecycle management.",
5
5
  "author": "SmartMemory",
6
6
  "license": "MIT",
@@ -229,7 +229,7 @@ export function scanFeatures(featuresDir) {
229
229
  }
230
230
  // Collect sequence refs (predecessor → this → successor) — only design.md
231
231
  // is authoritative; other docs may inherit copy-paste headers.
232
- if (artifact === 'design.md') {
232
+ if (docFile === 'design.md') {
233
233
  const seq = parseSequenceRefs(raw);
234
234
  for (const code of seq.predecessors) feature.predecessors.push(code);
235
235
  for (const code of seq.successors) feature.successors.push(code);
@@ -311,6 +311,101 @@ export function scanSubPackages() {
311
311
  return packages;
312
312
  }
313
313
 
314
+ // ---------------------------------------------------------------------------
315
+ // Feature.json write-back
316
+ // ---------------------------------------------------------------------------
317
+
318
+ /**
319
+ * Resolve a feature directory for a vision item.
320
+ *
321
+ * Tries lifecycle.featureCode, item.featureCode, then item.title (since the
322
+ * feature directory name equals the feature code, and items seeded from
323
+ * scanFeatures use feature.name === feature code as the title).
324
+ *
325
+ * @returns {string|null} absolute path to docs/features/<code>, or null.
326
+ */
327
+ function resolveFeatureDir(item, featuresDir) {
328
+ if (!item) return null;
329
+ const dir = featuresDir || resolveProjectPath('features');
330
+ const candidates = [
331
+ item.lifecycle?.featureCode,
332
+ item.featureCode,
333
+ item.title,
334
+ ].filter(Boolean);
335
+ for (const code of candidates) {
336
+ const p = path.join(dir, code);
337
+ try {
338
+ if (fs.existsSync(p) && fs.statSync(p).isDirectory()) return p;
339
+ } catch { /* skip */ }
340
+ }
341
+ return null;
342
+ }
343
+
344
+ /**
345
+ * Persist a new `group` value to docs/features/<code>/feature.json.
346
+ *
347
+ * Reads the existing feature.json, sets `spec.group = newGroup` (or removes
348
+ * the field if `newGroup` is null/empty), and writes atomically via temp +
349
+ * rename. Errors are logged but non-fatal — items without a backing
350
+ * feature.json simply skip silently.
351
+ *
352
+ * @param {object} item — vision item (must have lifecycle.featureCode or
353
+ * featureCode or title that matches a feature dir name)
354
+ * @param {string|null} newGroup — new group value (empty string / null to clear)
355
+ * @param {string} [featuresDir] — override features dir (test only)
356
+ * @returns {boolean} true if file was written, false if skipped.
357
+ */
358
+ export function writeFeatureGroupToDisk(item, newGroup, featuresDir) {
359
+ const featureDir = resolveFeatureDir(item, featuresDir);
360
+ if (!featureDir) {
361
+ if (process.env.DEBUG) {
362
+ console.debug(`[feature-scan] writeFeatureGroupToDisk: no feature dir for item ${item?.id || '?'} (${item?.title || ''})`);
363
+ }
364
+ return false;
365
+ }
366
+ const specPath = path.join(featureDir, 'feature.json');
367
+ if (!fs.existsSync(specPath)) {
368
+ if (process.env.DEBUG) {
369
+ console.debug(`[feature-scan] writeFeatureGroupToDisk: no feature.json at ${specPath}`);
370
+ }
371
+ return false;
372
+ }
373
+
374
+ let spec;
375
+ try {
376
+ spec = JSON.parse(fs.readFileSync(specPath, 'utf-8'));
377
+ } catch (err) {
378
+ console.warn(`[feature-scan] writeFeatureGroupToDisk: malformed feature.json at ${specPath}: ${err.message}`);
379
+ return false;
380
+ }
381
+
382
+ const normalized = (typeof newGroup === 'string' && newGroup.trim()) ? newGroup.trim() : null;
383
+ const current = (typeof spec.group === 'string' && spec.group.trim()) ? spec.group.trim() : null;
384
+ if (normalized === current) {
385
+ return false; // idempotent: nothing to do
386
+ }
387
+
388
+ if (normalized === null) {
389
+ delete spec.group;
390
+ } else {
391
+ spec.group = normalized;
392
+ }
393
+ // Bump updated date if the field exists
394
+ if ('updated' in spec) {
395
+ spec.updated = new Date().toISOString().slice(0, 10);
396
+ }
397
+
398
+ try {
399
+ const tmp = path.join(featureDir, `feature.json.tmp.${Date.now()}.${process.pid}`);
400
+ fs.writeFileSync(tmp, JSON.stringify(spec, null, 2) + '\n', 'utf-8');
401
+ fs.renameSync(tmp, specPath);
402
+ return true;
403
+ } catch (err) {
404
+ console.warn(`[feature-scan] writeFeatureGroupToDisk: failed to write ${specPath}: ${err.message}`);
405
+ return false;
406
+ }
407
+ }
408
+
314
409
  // ---------------------------------------------------------------------------
315
410
  // Roadmap graph import
316
411
  // ---------------------------------------------------------------------------
@@ -0,0 +1,80 @@
1
+ /**
2
+ * graph-layout-routes.js — persistent graph node positions.
3
+ *
4
+ * Mounts:
5
+ * GET /api/graph/layout → { positions: { [itemId]: {x, y} } }
6
+ * POST /api/graph/layout → body { positions: {...} } merged into existing.
7
+ *
8
+ * Storage: <dataDir>/graph-layout.json (resolved per-request via getDataDir()
9
+ * so project switches see the right file).
10
+ *
11
+ * Merge semantics: POST is a partial update. Existing entries not present in
12
+ * the body are preserved. Entries present in the body overwrite. Pass
13
+ * `{ positions: { id: null } }` to drop an entry.
14
+ */
15
+ import fs from 'node:fs';
16
+ import path from 'node:path';
17
+ import { getDataDir, ensureDataDir } from './project-root.js';
18
+
19
+ function layoutFile() {
20
+ return path.join(getDataDir(), 'graph-layout.json');
21
+ }
22
+
23
+ function readPositions() {
24
+ try {
25
+ const raw = fs.readFileSync(layoutFile(), 'utf-8');
26
+ const data = JSON.parse(raw);
27
+ return (data && typeof data.positions === 'object' && data.positions) || {};
28
+ } catch (err) {
29
+ if (err.code !== 'ENOENT') {
30
+ console.error('[graph-layout] read failed:', err.message);
31
+ }
32
+ return {};
33
+ }
34
+ }
35
+
36
+ function writePositions(positions) {
37
+ ensureDataDir();
38
+ const file = layoutFile();
39
+ const dir = path.dirname(file);
40
+ const data = JSON.stringify({ positions }, null, 2) + '\n';
41
+ const tmp = path.join(dir, `graph-layout.json.tmp.${Date.now()}`);
42
+ fs.writeFileSync(tmp, data, 'utf-8');
43
+ fs.renameSync(tmp, file);
44
+ }
45
+
46
+ function isFiniteNumber(n) {
47
+ return typeof n === 'number' && Number.isFinite(n);
48
+ }
49
+
50
+ export function attachGraphLayoutRoutes(app) {
51
+ app.get('/api/graph/layout', (_req, res) => {
52
+ res.json({ positions: readPositions() });
53
+ });
54
+
55
+ app.post('/api/graph/layout', (req, res) => {
56
+ const body = req.body || {};
57
+ const incoming = body.positions;
58
+ if (!incoming || typeof incoming !== 'object' || Array.isArray(incoming)) {
59
+ return res.status(400).json({ error: 'positions object required' });
60
+ }
61
+ const existing = readPositions();
62
+ const merged = { ...existing };
63
+ for (const [id, pos] of Object.entries(incoming)) {
64
+ if (pos === null) {
65
+ delete merged[id];
66
+ continue;
67
+ }
68
+ if (!pos || typeof pos !== 'object') continue;
69
+ if (!isFiniteNumber(pos.x) || !isFiniteNumber(pos.y)) continue;
70
+ merged[id] = { x: pos.x, y: pos.y };
71
+ }
72
+ try {
73
+ writePositions(merged);
74
+ } catch (err) {
75
+ console.error('[graph-layout] write failed:', err.message);
76
+ return res.status(500).json({ error: 'failed to persist layout' });
77
+ }
78
+ res.json({ ok: true, positions: merged });
79
+ });
80
+ }
package/server/index.js CHANGED
@@ -10,6 +10,7 @@ import { SessionManager } from './session-manager.js';
10
10
  import { scanFeatures, seedFeatures, scanSubPackages, seedSubPackages, seedFromRoadmapGraph } from './feature-scan.js';
11
11
  import { attachGraphExportRoutes } from './graph-export.js';
12
12
  import { attachWorkspaceRoutes } from './workspace-routes.js';
13
+ import { attachGraphLayoutRoutes } from './graph-layout-routes.js';
13
14
  import { createWorkspaceMiddleware } from './workspace-middleware.js';
14
15
  import { getTargetRoot, getDataDir, ensureDataDir, loadProjectConfig, resolveProjectPath, switchProject } from './project-root.js';
15
16
 
@@ -50,6 +51,7 @@ app.use(cors({ origin: /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/ }));
50
51
  app.use(express.json());
51
52
 
52
53
  attachWorkspaceRoutes(app);
54
+ attachGraphLayoutRoutes(app);
53
55
  app.use(createWorkspaceMiddleware());
54
56
 
55
57
  app.get('/api/health', (_req, res) => res.json({ ok: true }));
@@ -30,6 +30,7 @@ import fs from 'node:fs';
30
30
  import path from 'node:path';
31
31
  import { fileURLToPath } from 'node:url';
32
32
  import { extractFilePaths } from './vision-utils.js';
33
+ import { writeFeatureGroupToDisk } from './feature-scan.js';
33
34
  import { ArtifactManager } from './artifact-manager.js';
34
35
  import { recordIteration, checkCumulativeBudget, readBudget } from '../lib/budget-ledger.js';
35
36
  import { SchemaValidator } from './schema-validator.js';
@@ -83,6 +84,15 @@ export function attachVisionRoutes(app, { store, scheduleBroadcast, broadcastMes
83
84
  app.patch('/api/vision/items/:id', (req, res) => {
84
85
  try {
85
86
  const item = store.updateItem(req.params.id, req.body);
87
+ // If group changed, write back to docs/features/<code>/feature.json
88
+ // so the change survives restart and re-scan. Non-fatal on failure.
89
+ if (Object.prototype.hasOwnProperty.call(req.body || {}, 'group')) {
90
+ try {
91
+ writeFeatureGroupToDisk(item, req.body.group);
92
+ } catch (err) {
93
+ console.warn(`[vision-routes] feature.json group write-back failed: ${err.message}`);
94
+ }
95
+ }
86
96
  scheduleBroadcast();
87
97
  res.json(item);
88
98
  } catch (err) {
@@ -1 +0,0 @@
1
- import{aq as o,ar as n}from"./index-DNrB2NcO.js";const t=(r,a)=>o.lang.round(n.parse(r)[a]);export{t as c};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-4TB4RGXK-D1Trzzjy.js";import{_ as i}from"./index-DNrB2NcO.js";import"./chunk-FMBD7UC4-Dq0S7mgY.js";import"./chunk-YZCP3GAM-BaMX2_No.js";import"./chunk-55IACEB6-B_neChv-.js";import"./chunk-EDXVE4YY-HBFulheC.js";var u={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{u as diagram};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-4TB4RGXK-D1Trzzjy.js";import{_ as i}from"./index-DNrB2NcO.js";import"./chunk-FMBD7UC4-Dq0S7mgY.js";import"./chunk-YZCP3GAM-BaMX2_No.js";import"./chunk-55IACEB6-B_neChv-.js";import"./chunk-EDXVE4YY-HBFulheC.js";var u={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{u as diagram};
@@ -1 +0,0 @@
1
- import{b as r}from"./graph-CMQluXQ6.js";var e=4;function a(o){return r(o,e)}export{a as c};
@@ -1 +0,0 @@
1
- import{s as t,b as r,a,S as s}from"./chunk-OYMX7WX6-CmCV5icO.js";import{_ as i}from"./index-DNrB2NcO.js";import"./chunk-55IACEB6-B_neChv-.js";import"./chunk-EDXVE4YY-HBFulheC.js";var l={parser:a,get db(){return new s(2)},renderer:r,styles:t,init:i(e=>{e.state||(e.state={}),e.state.arrowMarkerAbsolute=e.arrowMarkerAbsolute},"init")};export{l as diagram};