@withgraphite/graphite-cli 1.0.10 → 1.0.12
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/.CHANGELOG.md +13 -1
- package/335.js +3 -0
- package/60.js +3 -0
- package/60.js.map +1 -0
- package/build/asset-manifest.json +7 -7
- package/build/index.html +1 -1
- package/build/static/css/521.c3a7ac34.chunk.css +2 -0
- package/build/static/css/521.c3a7ac34.chunk.css.map +1 -0
- package/build/static/css/main.b91b5c20.css +2 -0
- package/build/static/css/main.b91b5c20.css.map +1 -0
- package/build/static/js/521.6f9fb1c5.chunk.js +1 -0
- package/build/static/js/521.6f9fb1c5.chunk.js.map +1 -0
- package/build/static/js/main.js +1 -1
- package/build/static/js/main.js.map +1 -1
- package/child.js +1 -1
- package/child.js.map +1 -1
- package/graphite.js +1 -1
- package/package.json +1 -1
- package/741.js +0 -3
- package/999.js +0 -3
- package/999.js.map +0 -1
- package/build/static/css/521.ea7bdcfc.chunk.css +0 -2
- package/build/static/css/521.ea7bdcfc.chunk.css.map +0 -1
- package/build/static/css/main.a9f28c16.css +0 -2
- package/build/static/css/main.a9f28c16.css.map +0 -1
- package/build/static/js/521.9e4e25a2.chunk.js +0 -1
- package/build/static/js/521.9e4e25a2.chunk.js.map +0 -1
- /package/{741.js.LICENSE.txt → 335.js.LICENSE.txt} +0 -0
package/999.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";exports.id=999,exports.ids=[999],exports.modules={33800:(e,t)=>{var n;Object.defineProperty(t,"__esModule",{value:!0}),t.comparisonIsAgainstHead=t.labelForComparison=t.revsetArgsForComparison=t.ComparisonType=void 0,function(e){e.UncommittedChanges="UNCOMMITTED",e.HeadChanges="HEAD",e.StackChanges="STACK",e.Committed="InCommit"}(n=t.ComparisonType||(t.ComparisonType={})),t.revsetArgsForComparison=function(e){switch(e.type){case n.UncommittedChanges:return["uncommitted"];case n.HeadChanges:return["head"];case n.StackChanges:return["stack"];case n.Committed:return["stack","--ref",e.hash]}},t.labelForComparison=function(e){switch(e.type){case n.UncommittedChanges:return"Uncommitted Changes";case n.HeadChanges:return"Head Changes";case n.StackChanges:return"Stack Changes";case n.Committed:return`In ${e.hash}`}},t.comparisonIsAgainstHead=function(e){switch(e.type){case n.UncommittedChanges:case n.HeadChanges:case n.StackChanges:return!0;case n.Committed:return!1}}},52060:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},2982:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.cached=t.LRU=void 0;const r=n(30826);class s{constructor(e,t=3){this.maxItems=e,this.maxHashCollision=t,this.cache=new Map}get(e){let t;const n=o(e),s=this.cache.get(n);if(void 0!==s){const o=s.get(e);if(void 0!==o)t=o;else for(const[n,o]of s)if((0,r.is)(e,n)){t=o;break}this.cache.delete(n),this.cache.set(n,s)}return t}set(e,t){const n=o(e);let r=this.cache.get(n);if(void 0===r||r.size>=this.maxHashCollision?r=new Map([[e,t]]):r.set(e,t),this.cache.delete(n),void 0!==t&&(this.cache.set(n,r),this.cache.size>this.maxItems)){const e=this.cache.keys().next();e.done||this.cache.delete(e.value)}}delete(e){const t=o(e);this.cache.delete(t)}clear(){this.cache.clear()}}function o(e){const t=null==e?void 0:e.hashCode;return void 0!==t?t.apply(e):e}function i(e,t){var n,o;const i=null!==(n=null==t?void 0:t.cache)&&void 0!==n?n:new s(null!==(o=null==t?void 0:t.cacheSize)&&void 0!==o?o:10),a=null==t?void 0:t.getExtraKeys,l=function(...t){var n,s,o;const l=i.stats;if(!t.every(c))return null!=l&&(l.skip=(null!==(n=l.skip)&&void 0!==n?n:0)+1),e.apply(this,t);const u=(0,r.List)(a?[...a.apply(this),...t]:t),d=i.get(u);if(void 0!==d)return null!=l&&(l.hit=(null!==(s=l.hit)&&void 0!==s?s:0)+1),d;null!=l&&(l.miss=(null!==(o=l.miss)&&void 0!==o?o:0)+1);const h=e.apply(this,t);return i.set(u,h),h};return l.cache=i,l}t.LRU=s,t.cached=function(e,t){return"function"==typeof e?i(e,t):function(e){var t;const n=null!==(t=null==e?void 0:e.getExtraKeys)&&void 0!==t?t:function(){return(0,r.isValueObject)(this)?[this]:null!=this&&"object"==typeof this?Object.values(this).filter(c):[]};return function(t,r,s){const o=s.value;s.value=i(o,Object.assign(Object.assign({},e),{getExtraKeys:n}))}}(e)};const a=new Set(["number","string","boolean","symbol","bigint","undefined","null"]);function c(e){if(null==e)return!0;const t=typeof e;return!!a.has(t)||!("object"!==t||!(0,r.isValueObject)(e))}},61110:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},5693:function(e,t,n){var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var s=Object.getOwnPropertyDescriptor(t,n);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,s)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),s=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||r(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),s(n(61110),t),s(n(52568),t),s(n(11268),t),s(n(66877),t)},52568:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},11268:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Tracker=void 0;const r=n(48427);class s{constructor(e,t){this.sendData=e,this.context=t}error(e,t,n,r){const s=n instanceof Error?n.message||String(n):n;return this.track(e,Object.assign(Object.assign({},null!=r?r:{}),{errorMessage:s,errorName:t}))}operation(e,t,n,s){var o;const i=Date.now(),a=null!==(o=null==n?void 0:n.id)&&void 0!==o?o:(0,r.randomId)();try{const o=s({parentId:a});if((0,r.isPromise)(o))return o.then((t=>{const r=Date.now()-i;return this.track(e,Object.assign(Object.assign({},null!=n?n:{}),{duration:r,id:a})),t})).catch((r=>{const s=Date.now()-i;return this.error(e,t,r,Object.assign(Object.assign({},null!=n?n:{}),{duration:s,id:a})),Promise.reject(r)}));{const t=Date.now()-i;return this.track(e,Object.assign(Object.assign({},null!=n?n:{}),{duration:t,id:a})),o}}catch(r){const s=Date.now()-i;throw this.error(e,t,r,Object.assign(Object.assign({},null!=n?n:{}),{duration:s,id:a})),r}}trackAsParent(e,t){var n;const o=null!==(n=null==t?void 0:t.id)&&void 0!==n?n:(0,r.randomId)();return this.trackData(Object.assign(Object.assign({},t),{eventName:e,id:o})),new s(((e,t)=>this.trackData(Object.assign(Object.assign({},e),t))),{parentId:o})}track(e,t){return this.trackData(Object.assign(Object.assign({},t),{eventName:e}))}trackData(e){var t,n;const s=null!==(t=null==e?void 0:e.id)&&void 0!==t?t:(0,r.randomId)(),o=null!==(n=null==e?void 0:e.timestamp)&&void 0!==n?n:Date.now(),i=Object.assign({timestamp:o,id:s},null!=e?e:{});this.sendData(i,this.context)}}t.Tracker=s},66877:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},33905:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.newAbortController=void 0;const r=n(53811);t.newAbortController=function(){return"function"==typeof AbortController?new AbortController:new r.AbortController}},66960:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.debounce=void 0,t.debounce=function(e,t,n=void 0,r=!1){let s,o=!0;function i(...a){let c;if(r){if(c=function(){o=!0,s=void 0},!o)return clearTimeout(s),void(s=setTimeout(c,t));o=!1,e.apply(n,a)}else i.reset(),c=function(){s=void 0,e.apply(n,a)};s=setTimeout(c,t)}return i.reset=function(){clearTimeout(s),s=void 0,o=!0},i.isPending=function(){return null!=s},i}},90828:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.SelfUpdate=void 0;class n{constructor(e){this.inner=e}hashCode(){return this.inner.hashCode()+1}equals(e){if(!(e instanceof n))return!1;if(this===e)return!0;const t=e.inner,r=this.inner.equals(t);return r&&this.inner!==t&&(this.inner=t),r}}t.SelfUpdate=n},98696:function(e,t,n){var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var s=Object.getOwnPropertyDescriptor(t,n);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,s)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),s=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||r(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),s(n(5693),t),s(n(33800),t),s(n(86099),t),s(n(40256),t),s(n(85249),t),s(n(48427),t),s(n(66224),t),s(n(2982),t),s(n(13035),t),s(n(90828),t),s(n(52060),t),s(n(66960),t),s(n(33905),t),s(n(75905),t)},13035:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.minimalDisambiguousPaths=void 0,t.minimalDisambiguousPaths=function(e,t={}){const n=e.map((e=>{const t=function(e){return e.replace(/[^\\]/g,"").length>e.replace(/[^/]/g,"").length?"\\":"/"}(e),n=/^(\w:).*/.exec(e),r=null!=n?n[1]:"";return{depth:null,parts:e.split(t).reverse().filter((e=>""!==e&&e!==r)),rootPrefix:r,separator:t,hadLeadingSeparator:e.startsWith(t)||r.length>0&&e.startsWith(r)}})),r=null==t.maxDepth?Math.max(...n.map((e=>e.parts.length))):t.maxDepth,s=new Set(n),o=new Map;for(let e=1;e<=r;e++){o.clear();for(const t of s){const n=t.parts.slice(0,e).join(t.separator);o.has(n)||o.set(n,new Set),o.get(n).add(t)}for(const t of o.values())if(1===t.size){const n=Array.from(t)[0];n.depth=e,s.delete(n)}}return n.map((({depth:e,parts:n,rootPrefix:s,separator:o,hadLeadingSeparator:i})=>{var a;let c=n.slice(0,null==e?r:e).reverse();return 0===c.length?`${s}${o}`:((1===c.length&&""===c[0]||c.length>1&&""!==c[0])&&(c=c.length===n.length?i?[s,...c]:c:(null!==(a=t.alwaysShowLeadingSeparator)&&void 0!==a?a:i)?["",...c]:c),c.join(o))}))}},75905:(e,t)=>{var n;Object.defineProperty(t,"__esModule",{value:!0}),t.parsePatch=t.DiffType=void 0,function(e){e.Modified="Modified",e.Added="Added",e.Removed="Removed",e.Renamed="Renamed",e.Copied="Copied"}(n=t.DiffType||(t.DiffType={}));const r=/^diff --git (.*) (.*)$/,s=/^rename from (.*)$/,o=/^rename to (.*)$/,i=/^copy from (.*)$/,a=/^copy to (.*)$/,c=/^new file mode (\d{6})$/,l=/^deleted file mode (\d{6})$/,u=/^old mode (\d{6})$/,d=/^new mode (\d{6})$/,h=/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/,m=/^--- (.*)$/,p=/^\+\+\+ (.*)$/,g=/\r\n|[\n\v\f\r\x85]/g;function f(e,t){if(!1===e)throw new Error(t)}t.parsePatch=function(e){const t=e.split(g),v=e.match(g)||[],C=[];let y=0;function b(){const e={hunks:[]};for(C.push(e),function(e){for(;y<t.length;){const n=t[y],s=r.exec(n);if(s){e.oldFileName=s[1],e.newFileName=s[2],y++;break}y++}}(e);y<t.length;){const n=t[y];if(/^old mode/.test(n))w(e);else if(/^new mode/.test(n))O(e);else if(/^deleted file mode/.test(n))S(e);else if(/^new file mode/.test(n))E(e);else if(/^copy /.test(n))R(e);else if(/^rename /.test(n))k(e);else{if(/^--- /.test(n)){M(e);break}if(/^diff --git/.test(n))break;y++}}!function(e){for(;y<t.length;){const n=t[y];if(r.test(n))break;/^@@/.test(n)?e.hunks.push(_()):y++}}(e)}function w(e){const r=u.exec(t[y]);f(null!==r,`invalid format '${t[y]}'`),e.oldMode=r[1],e.type=n.Modified,y++}function O(e){const r=d.exec(t[y]);f(null!==r,`invalid format '${t[y]}'`),e.newMode=r[1],e.type=n.Modified,y++}function S(e){const r=l.exec(t[y]);f(null!==r,`invalid format '${t[y]}'`),e.newMode=r[1],e.type=n.Removed,y++}function E(e){const r=c.exec(t[y]);f(null!==r,`invalid format '${t[y]}'`),e.newMode=r[1],e.type=n.Added,y++}function R(e){f(i.test(t[y]),`invalid format '${t[y]}'`),f(a.test(t[y+1]),`invalid format '${t[y+1]}'`),e.type=n.Copied,y+=2}function k(e){f(s.test(t[y]),`invalid format '${t[y]}'`),f(o.test(t[y+1]),`invalid format '${t[y+1]}'`),e.type=n.Renamed,y+=2}function M(e){f(m.test(t[y]),`invalid format '${t[y]}'`),f(p.test(t[y+1]),`invalid format '${t[y+1]}'`),void 0===e.type&&(e.type=n.Modified),y+=2}function _(){const e=t[y++].split(h),n={oldStart:+e[1],oldLines:void 0===e[2]?1:+e[2],newStart:+e[3],newLines:void 0===e[4]?1:+e[4],lines:[],linedelimiters:[]};0===n.oldLines&&(n.oldStart+=1),0===n.newLines&&(n.newStart+=1);let r=0,s=0;for(;y<t.length&&!(0===t[y].indexOf("--- ")&&y+2<t.length&&0===t[y+1].indexOf("+++ ")&&0===t[y+2].indexOf("@@"));y++){const e=0==t[y].length&&y!=t.length-1?" ":t[y][0];if("+"!==e&&"-"!==e&&" "!==e&&"\\"!==e)break;n.lines.push(t[y]),n.linedelimiters.push(v[y]||"\n"),"+"===e?r++:"-"===e?s++:" "===e&&(r++,s++)}return r||1!==n.newLines||(n.newLines=0),s||1!==n.oldLines||(n.oldLines=0),n}for(;y<t.length;)b();return C}},85249:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.deserializeFromString=t.deserialize=t.serializeToString=t.serialize=void 0;const n={__rpcType:"undefined"};function r(e){if(void 0===e)return n;if("number"==typeof e||"boolean"==typeof e||"string"==typeof e||null===e)return e;if(e instanceof Map)return{__rpcType:"Map",data:Array.from(e.entries()).map((([e,t])=>[r(e),r(t)]))};if(e instanceof Set)return{__rpcType:"Set",data:Array.from(e.values()).map(r)};if(e instanceof Error)return{__rpcType:"Error",data:{message:e.message,stack:e.stack}};if(e instanceof Date)return{__rpcType:"Date",data:e.valueOf()};if(Array.isArray(e))return e.map((e=>r(e)));if("object"==typeof e){const t={__rpcType:"object"};for(const[n,s]of Object.entries(e))t[n]=r(s);return t}throw new Error(`cannot serialize argument ${e}`)}function s(e){if("object"!=typeof e||null==e)return e;if(Array.isArray(e))return e.map((e=>s(e)));const t=e;switch(t.__rpcType){case"undefined":return;case"Map":return new Map(t.data.map((([e,t])=>[s(e),s(t)])));case"Set":return new Set(t.data.map(s));case"Error":{const e=new Error;return e.stack=t.data.stack,e.message=t.data.message,e}case"Date":return new Date(t.data);case"object":{const t=e,n={};for(const[e,r]of Object.entries(t))"__rpcType"!==e&&(n[e]=s(r));return n}default:throw new Error(`cannot deserialize unknown type ${t}`)}}t.serialize=r,t.serializeToString=function(e){return JSON.stringify(r(e))},t.deserialize=s,t.deserializeFromString=function(e){return s(JSON.parse(e))}},40256:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},66224:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},50209:(e,t)=>{var n;Object.defineProperty(t,"__esModule",{value:!0}),t.SucceedableRevset=t.CommandRunner=void 0,(n=t.CommandRunner||(t.CommandRunner={})).Graphite="gt",n.CodeReviewProvider="codeReviewProvider",t.SucceedableRevset=function(e){return{type:"succeedable-revset",revset:e}}},74259:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},45852:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},1018:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ErrorShortMessages=t.DEFAULT_DAYS_OF_COMMITS_TO_LOAD=t.ONE_MINUTE_MS=t.CLOSED_AND_SHOULD_NOT_RECONNECT_CODE=void 0,t.CLOSED_AND_SHOULD_NOT_RECONNECT_CODE=4100,t.ONE_MINUTE_MS=6e4,t.DEFAULT_DAYS_OF_COMMITS_TO_LOAD=void 0,(t.ErrorShortMessages||(t.ErrorShortMessages={})).NoCommitsFetched="No commits found"},29641:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},86099:function(e,t,n){var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var s=Object.getOwnPropertyDescriptor(t,n);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,s)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),s=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||r(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),s(n(50209),t),s(n(85119),t),s(n(45852),t),s(n(74259),t),s(n(1018),t),s(n(29641),t)},85119:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},48427:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.isPromise=t.truncate=t.zip=t.generatorContains=t.mapObject=t.findParentWithClassName=t.basename=t.defer=t.randomId=t.unwrap=t.notEmpty=void 0,t.notEmpty=function(e){return null!=e},t.unwrap=function(e){if(null==e)throw new Error(`expected value not to be ${e}`);return e},t.randomId=function(){return Date.now().toString(36)+Math.random().toString(36)},t.defer=function(){const e={promise:void 0,resolve:void 0,reject:void 0};return e.promise=new Promise(((t,n)=>{e.resolve=t,e.reject=n})),e},t.basename=function(e,t="/"){const n=e.lastIndexOf(t);return-1===n?e:e.slice(n+1)},t.findParentWithClassName=function(e,t){var n;let r=e;for(;r;){if(null===(n=r.classList)||void 0===n?void 0:n.contains(t))return r;r=r.parentElement}},t.mapObject=function(e,t){return Object.fromEntries(Object.entries(e).map(t))},t.generatorContains=function(e,t){const n="function"==typeof t?t:e=>e===t;for(const t of e)if(n(t))return!0;return!1},t.zip=function*(e,t){const n=e[Symbol.iterator](),r=t[Symbol.iterator]();for(;;){const e=n.next(),t=r.next();if(e.done||t.done)break;yield[e.value,t.value]}},t.truncate=function(e,t=100){return e.length>t?e.substring(0,Math.max(0,t-1))+"…":e},t.isPromise=function(e){return"function"==typeof(null==e?void 0:e.then)}},25999:(e,t,n)=>{n.r(t),n.d(t,{startServer:()=>X});var r=n(98696),s=n(57147),o=n.n(s),i=n(13685),a=n.n(i),c=n(71017),l=n.n(c),u=n(57310),d=n.n(u),h=n(95352),m=n.n(h),p=n(22037),g=n.n(p);function f(){try{return g().userInfo().username}catch(e){try{const{env:e}=process;return(0,r.unwrap)(e.LOGNAME||e.USER||e.LNAME||e.USERNAME)}catch(t){throw new Error(String(t)+String(e))}}}class v{logger;data;constructor(e,t){this.logger=e,this.data=t}setRepo(e){this.data.repo=e?.codeReviewProvider?.getSummaryName()}}const C=e=>{};var y=n(73837),b=n.n(y);const w=console;var O=n(60492),S=n.n(O),E=n(80909),R=n.n(E),k=n(82361);class M extends k.EventEmitter{}class _{codeReviewSystem;runCommand;constructor(e,t){this.codeReviewSystem=e,this.runCommand=t}diffSummaries=new M;onChangeDiffSummaries(e){const t=t=>e({value:t}),n=t=>e({error:t});return this.diffSummaries.on("data",t),this.diffSummaries.on("error",n),{dispose:()=>{this.diffSummaries.off("data",t),this.diffSummaries.off("error",n)}}}async triggerDiffSummariesFetch(e){const t=await this.runCommand(["internal-only","prs"]),n=JSON.parse(t.stdout);this.diffSummaries.emit("data",n)}dispose(){this.diffSummaries.removeAllListeners()}getSummaryName(){return`github:${this.codeReviewSystem.hostname}/${this.codeReviewSystem.owner}/${this.codeReviewSystem.repo}`}runExternalCommand(e,t,n,r){throw new Error("GitHub code review provider does not support running external commands")}async typeahead(e,t){return Promise.resolve([])}}class D{logger;runCallback;constructor(e,t){this.logger=e,this.runCallback=t}queuedOperations=[];runningOperation=void 0;abortController=void 0;async runOrQueueOperation(e,t,n,s){if(null!=this.runningOperation)return this.queuedOperations.push({...e,tracker:n}),void t({id:e.id,kind:"queue",queue:this.queuedOperations.map((e=>e.id))});this.runningOperation=e;const o=(...n)=>{switch(n[0]){case"spawn":t({id:e.id,kind:"spawn",queue:this.queuedOperations.map((e=>e.id))});break;case"stdout":t({id:e.id,kind:"stdout",message:n[1]});break;case"stderr":t({id:e.id,kind:"stderr",message:n[1]});break;case"exit":t({id:e.id,kind:"exit",exitCode:n[1],timestamp:Date.now()})}};try{const i=(0,r.newAbortController)();if(this.abortController=i,await n.operation(e.trackEventName,"RunOperationError",{extras:{args:e.args,runner:e.runner}},(t=>this.runCallback(e,s,o,i.signal))),this.runningOperation=void 0,this.queuedOperations.length>0){const e=this.queuedOperations.shift();null!=e&&this.runOrQueueOperation(e,t,e.tracker,s)}}catch(n){const r=n.toString();this.logger.log("error running operation: ",e.args[0],r),t({id:e.id,kind:"error",error:r}),this.queuedOperations=[],this.runningOperation=void 0}}abortRunningOperation(e){this.runningOperation?.id==e&&this.abortController?.abort()}}class T{focusedPages=new Set;visiblePages=new Set;onChangeHandlers=new Set;setState(e,t){switch(t){case"focused":this.focusedPages.add(e),this.visiblePages.add(e);break;case"visible":this.focusedPages.delete(e),this.visiblePages.add(e);break;case"hidden":this.focusedPages.delete(e),this.visiblePages.delete(e)}for(const e of this.onChangeHandlers)e(t)}disposePage(e){this.focusedPages.delete(e),this.visiblePages.delete(e)}hasPageWithFocus(){return this.focusedPages.size>0}hasVisiblePage(){return this.visiblePages.size>0}onChange(e){return this.onChangeHandlers.add(e),()=>this.onChangeHandlers.delete(e)}}class P{maxSimultaneousRunning;log;queued=[];running=[];runs=new M;constructor(e,t){this.maxSimultaneousRunning=e,this.log=t}nextId=1;generateId(){return this.nextId++}async enqueueRun(e){const t=this.generateId();this.queued.push(t),this.tryDequeueNext(),this.running.includes(t)||(this.log?.(`${this.running.length} tasks are already running, enqueuing ID:${t}`),await new Promise((e=>{this.runs.on("run",(n=>{n===t&&(this.log?.(`now allowing ID:${t} to run`),e(void 0))}))})));try{return await e()}finally{this.notifyFinished(t)}}notifyFinished(e){this.running=this.running.filter((t=>t!==e)),this.tryDequeueNext()}tryDequeueNext(){if(this.running.length<this.maxSimultaneousRunning){const e=this.queued.shift();null!=e&&this.run(e)}}run(e){this.running.push(e),this.runs.emit("run",e)}}function j(e){let t,n;const r=()=>{const t=e();return n=t.then((()=>n=void 0),(()=>n=void 0)),t},s=()=>(t=void 0,r());return()=>null==n?r():(()=>{if(null==t){if(null==n)throw new Error("pendingCall must not be null!");t=n.then(s,s)}return t})()}var I=n(51887);const N="0.1.4";class x{info;logger;IGNORE_COMMIT_MESSAGE_LINES_REGEX=/^((?:HG|SL):.*)/gm;mergeConflicts=void 0;uncommittedChanges=null;smartlogCommits=null;mergeConflictsEmitter=new M;uncommittedChangesEmitter=new M;smartlogCommitsChangesEmitter=new M;smartlogCommitsBeginFetchingEmitter=new M;uncommittedChangesBeginFetchingEmitter=new M;disposables=[()=>this.mergeConflictsEmitter.removeAllListeners(),()=>this.uncommittedChangesEmitter.removeAllListeners(),()=>this.smartlogCommitsChangesEmitter.removeAllListeners(),()=>this.smartlogCommitsBeginFetchingEmitter.removeAllListeners(),()=>this.uncommittedChangesBeginFetchingEmitter.removeAllListeners()];onDidDispose(e){this.disposables.push(e)}operationQueue;watchForChangesDisposer;pageFocusTracker=new T;codeReviewProvider;currentVisibleCommitRangeIndex=0;visibleCommitRanges=[r.DEFAULT_DAYS_OF_COMMITS_TO_LOAD,60,void 0];constructor(e,t){this.info=e,this.logger=t;const n=e.codeReviewSystem;"github"===n.type&&(this.codeReviewProvider=new _(n,this.runCommand.bind(this))),this.watchForChangesDisposer=function(e,t,n){if("success"!==e.type)return;const{repoRoot:r,dotdir:s}=e;if(null==r||null==s)return void t.error(`skipping chokidar subscription since ${r} is not a repository`);const o=I.watch(s,{cwd:s});o.on("ready",(()=>{n("everything")})),o.on("all",((e,t)=>{t.startsWith("rebase-merge")&&n("merge conflicts"),(t.startsWith("index")||t.startsWith("HEAD"))&&n("uncommitted changes"),(t.startsWith("refs/heads")||t.startsWith("refs/branch-metadata")||t.startsWith("HEAD"))&&n("branches")}));const i=l().relative(r,s),a=I.watch(r,{cwd:r,ignored:`${i}/**`});return a.on("all",(()=>{n("uncommitted changes")})),()=>{a.close().catch((()=>t.error(`failed to close chokidar worktree watcher for ${r}`))),o.close().catch((()=>t.error(`failed to close chokidar dotdir watcher for ${s}`)))}}(e,t,(e=>{"uncommitted changes"===e?(this.fetchUncommittedChanges(),this.checkForMergeConflicts()):"branches"===e?this.fetchSmartlogCommits():"merge conflicts"===e?this.checkForMergeConflicts():"everything"===e&&(this.fetchUncommittedChanges(),this.fetchSmartlogCommits(),this.checkForMergeConflicts())})),this.operationQueue=new D(this.logger,((e,t,n,s)=>{if(e.runner===r.CommandRunner.Graphite)return this.runOperation(e,n,t,s);if(e.runner===r.CommandRunner.CodeReviewProvider){const r=this.normalizeOperationArgs(t,e.args);return null==this.codeReviewProvider?.runExternalCommand?Promise.reject(Error("CodeReviewProvider does not support running external commands")):this.codeReviewProvider?.runExternalCommand(t,r,n,s)??Promise.resolve()}return Promise.resolve()}));const s=new Set,o=this.subscribeToSmartlogCommitsChanges((e=>{if(e.commits.value){const t=[],n=e.commits.value.filter((e=>e.pr)).map((e=>e.pr?.number));for(const e of n)s.has(e)||(t.push(e),s.add(e));t.length>0&&this.codeReviewProvider?.triggerDiffSummariesFetch(this.getAllDiffIds())}}));this.checkForMergeConflicts(),this.disposables.push((()=>o.dispose()))}nextVisibleCommitRangeInDays(){return this.currentVisibleCommitRangeIndex+1<this.visibleCommitRanges.length&&this.currentVisibleCommitRangeIndex++,this.visibleCommitRanges[this.currentVisibleCommitRangeIndex]}dispose(){this.disposables.forEach((e=>e())),this.codeReviewProvider?.dispose(),this.watchForChangesDisposer?.()}onChangeConflictState(e){return this.mergeConflictsEmitter.on("change",e),this.mergeConflicts&&e(this.mergeConflicts),{dispose:()=>this.mergeConflictsEmitter.off("change",e)}}checkForMergeConflicts=(0,r.debounce)(j((async()=>{this.logger.info("checking for merge conflicts");const e=null!=this.mergeConflicts;if(!e&&!await(t=l().join(this.info.dotdir,"rebase-merge"),o().promises.stat(t).then((()=>!0)).catch((e=>{if("ENOENT"===e.code)return!1;throw e}))))return void this.logger.info(`conflict state still the same (${e?"IN merge conflict":"NOT in conflict"})`);var t;null==this.mergeConflicts&&(this.mergeConflicts={state:"loading"},this.mergeConflictsEmitter.emit("change",this.mergeConflicts));const n=Date.now();let r;try{const e=await this.runCommand(["internal-only","status"]);r=JSON.parse(e.stdout)}catch(e){return this.logger.error(`failed to check for merge conflicts: ${e}`),this.mergeConflicts=void 0,void this.mergeConflictsEmitter.emit("change",this.mergeConflicts)}const s=await o().promises.readFile(l().join(this.info.dotdir,"rebase-merge","head-name")).then((e=>{const t=e.toString();return t.startsWith("refs/heads/")?t.slice(11).trimEnd():void 0}),(()=>{}));if(this.mergeConflicts=function(e,t,n,r){const s=n;if(!s?.conflicts||!t)return;const o=s.files.filter((e=>"UNRESOLVED"===e.status)),i={state:"loaded",branchName:t,files:[],fetchStartTimestamp:r,fetchCompletedTimestamp:Date.now()};if(null!=e?.files&&e.files.length>0){const t=new Set(o.map((e=>e.path)));i.files=e.files.map((e=>t.has(e.path)?{path:e.path,status:"UNRESOLVED"}:{path:e.path,status:"RESOLVED"}))}else i.files=o.map((e=>({path:e.path,status:"UNRESOLVED"})));return i}(this.mergeConflicts,s,r,n),this.logger.info(`repo ${this.mergeConflicts?"IS":"IS NOT"} in merge conflicts`,{mergeConflicts:this.mergeConflicts,files:this.mergeConflicts?.files}),this.mergeConflicts){const e=20,t=(this.mergeConflicts.files??[]).filter((e=>"UNRESOLVED"===e.status)).map((e=>e.path)).slice(0,e);this.logger.info("remaining files with conflicts: ",{branchName:s,remainingConflicts:t})}this.mergeConflictsEmitter.emit("change",this.mergeConflicts)})),100);getMergeConflicts(){return this.mergeConflicts}static async getRepoInfo(e,t,n){const r=await async function(e,t,n){try{return(await F({command:e,args:["--version"],logger:t,cwd:n})).stdout}catch(e){throw t.error(`Failed to find gt version in ${n}`,e),e}}(e,t,n).catch((e=>e));if(r instanceof Error)return{type:"invalidCommand",command:e??"gt"};if("local"!==r&&"dev"!==r&&R().lt(r,N))return{type:"invalidVersion",command:e??"gt",versionFound:r,versionRequired:N};const[s,o,i,a]=await Promise.all([L(e,t,n),A(e,t,n),$(e,t,n,"graphite.branch_edit").then((e=>e??"amend")),$(e,t,n,"graphite.create_prs_as").then((e=>e??"draft"))]);if(null==o)return{type:"cwdNotARepository",cwd:n};let c;if(void 0===o.remote)c={type:"none"};else{const{owner:e,name:t,hostname:n}=o.remote;c={type:"github",owner:e,repo:t,hostname:n}}const l={type:"success",command:e,dotdir:o.dotDir,repoRoot:o.rootDir,codeReviewSystem:c,preferredBranchEdit:i,createPrsAs:a,profile:s,trunkBranch:o.trunkBranch};return t.info("repo info: ",l),l}async runOrQueueOperation(e,t,n,r){await this.operationQueue.runOrQueueOperation(e,t,n,r)}abortRunningOpeation(e){this.operationQueue.abortRunningOperation(e)}normalizeOperationArgs(e,t){const n=(0,r.unwrap)(this.info.repoRoot);return t.map((t=>{if("object"==typeof t)switch(t.type){case"repo-relative-file":return l().normalize(l().relative(e,l().join(n,t.path)));case"succeedable-revset":return`max(successors(${t.revset}))`}return t}))}async runOperation(e,t,n,r){const s=this.normalizeOperationArgs(n,e.args),{stdin:o}=e,{command:i,args:a,options:c}=U(this.info.command,s,n,o?{input:o}:void 0);this.logger.log("run operation: ",i,s.join(" "));const l=S()(i,a,{...c,stdout:"pipe",stderr:"pipe"});t("spawn"),l.stdout?.on("data",(e=>{t("stdout",e.toString())})),l.stderr?.on("data",(e=>{t("stderr",e.toString())})),l.on("exit",(e=>{t("exit",e||0)})),r.addEventListener("abort",(()=>{this.logger.log("kill operation: ",i,s.join(" "))})),function(e,t){t.addEventListener("abort",(()=>{"win32"==g().platform()?e.kill("SIGKILL",{forceKillAfterTimeout:!1}):(e.kill("SIGCONT"),e.kill("SIGTERM",{forceKillAfterTimeout:5e3}))}))}(l,r),await l}setPageFocus(e,t){this.pageFocusTracker.setState(e,t)}getUncommittedChanges(){return this.uncommittedChanges}subscribeToUncommittedChanges(e){return this.uncommittedChangesEmitter.on("change",e),{dispose:()=>{this.uncommittedChangesEmitter.off("change",e)}}}fetchUncommittedChanges=(0,r.debounce)(j((async()=>{const e=Date.now();try{this.uncommittedChangesBeginFetchingEmitter.emit("start");const t=await this.runCommand(["internal-only","status"]),n=JSON.parse(t.stdout).files.map((e=>{return{...e,path:(t=e.path,t.startsWith(l().sep)?t.slice(1):t)};var t}));this.uncommittedChanges={fetchStartTimestamp:e,fetchCompletedTimestamp:Date.now(),files:{value:n}},this.uncommittedChangesEmitter.emit("change",this.uncommittedChanges)}catch(n){if(this.logger.error("Error fetching files: ",n),null!=(t=n)&&"object"==typeof t&&"stderr"in t&&n.stderr.includes("checkout is currently in progress"))return void this.logger.info("Ignoring `hg status` error caused by in-progress checkout");this.uncommittedChangesEmitter.emit("change",{fetchStartTimestamp:e,fetchCompletedTimestamp:Date.now(),files:{error:n instanceof Error?n:new Error(n)}})}var t})),100);getSmartlogCommits(){return this.smartlogCommits}subscribeToSmartlogCommitsChanges(e){return this.smartlogCommitsChangesEmitter.on("change",e),{dispose:()=>{this.smartlogCommitsChangesEmitter.off("change",e)}}}subscribeToSmartlogCommitsBeginFetching(e){const t=()=>e(!0);return this.smartlogCommitsBeginFetchingEmitter.on("start",t),{dispose:()=>{this.smartlogCommitsBeginFetchingEmitter.off("start",t)}}}subscribeToUncommittedChangesBeginFetching(e){const t=()=>e(!0);return this.uncommittedChangesBeginFetchingEmitter.on("start",t),{dispose:()=>{this.uncommittedChangesBeginFetchingEmitter.off("start",t)}}}fetchSmartlogCommits=(0,r.debounce)(j((async()=>{const e=Date.now();try{this.smartlogCommitsBeginFetchingEmitter.emit("start");const t=await this.runCommand(["internal-only","log"]),n=function(e,t){let n=[];try{n=JSON.parse(t)}catch(t){e.error("failed to parse branch info",t)}return n}(this.logger,t.stdout.trim());if(0===n.length)throw new Error(r.ErrorShortMessages.NoCommitsFetched);this.smartlogCommits={fetchStartTimestamp:e,fetchCompletedTimestamp:Date.now(),commits:{value:n}},this.smartlogCommitsChangesEmitter.emit("change",this.smartlogCommits)}catch(t){this.logger.error("Error fetching commits: ",t),this.smartlogCommitsChangesEmitter.emit("change",{fetchStartTimestamp:e,fetchCompletedTimestamp:Date.now(),commits:{error:t instanceof Error?t:new Error(t)}})}})),100);subscribeToHeadCommit(e){let t=this.smartlogCommits?.commits.value?.find((e=>e.isHead));null!=t&&e(t);const n=n=>{const r=n?.commits.value?.find((e=>e.isHead));null!=r&&r.branch!==t?.branch&&(e(r),t=r)};return this.smartlogCommitsChangesEmitter.on("change",n),{dispose:()=>{this.smartlogCommitsChangesEmitter.off("change",n)}}}catLimiter=new P(4,(e=>this.logger.info("[cat]",e)));cat(e,t){const n=l().relative(this.info.repoRoot,e);return this.catLimiter.enqueueRun((async()=>(await this.runCommand(["internal-only","relative-cat",...this.catArgs(t,n)],void 0,{stripFinalNewline:!1})).stdout))}catArgs(e,t){switch(e.type){case r.ComparisonType.UncommittedChanges:return["uncommitted",t];case r.ComparisonType.HeadChanges:return["head",t];case r.ComparisonType.StackChanges:return["stack",t];case r.ComparisonType.Committed:return["stack",t,"--ref",e.hash]}}getAllDiffIds(){return this.getSmartlogCommits()?.commits.value?.map((e=>e.pr?.number)).filter(r.notEmpty)??[]}runCommand(e,t,n){return F({command:this.info.command,args:e,logger:this.logger,cwd:(0,r.unwrap)(t??this.info.repoRoot),options:n})}getConfig(e){return $(this.info.command,this.logger,this.info.repoRoot,e)}setConfig(e,t,n){return async function({command:e,logger:t,cwd:n,level:r,configName:s,configValue:o}){await F({command:e,args:["internal-only","set-config","--level",r,s,o],logger:t,cwd:n})}({command:this.info.command,logger:this.logger,cwd:this.info.repoRoot,level:e,configName:t,configValue:n})}}function F({command:e,args:t,logger:n,cwd:r,options:s}){const{command:o,args:i,options:a}=U(e,t,r,s);return n&&n.log("run command: ",o,...i,a),S()(o,i,a)}async function A(e,t,n){try{return JSON.parse((await F({command:e,args:["internal-only","repo-info"],logger:t,cwd:n})).stdout)}catch(e){return void t.error(`Failed to find repository info in ${n}`,e)}}async function L(e,t,n){try{return JSON.parse((await F({command:e,args:["internal-only","profile"],logger:t,cwd:n})).stdout)}catch(e){return t.error(`Failed to find repository profile in ${n}`,e),{appUrl:"https://app.graphite.dev/"}}}async function $(e,t,n,r){try{return(await F({command:e,args:["internal-only","config",r],logger:t,cwd:n})).stdout.trim()}catch{return}}function U(e,t,n,r){let s=[...t];"win32"!==process.platform&&(s=s.map((e=>e.replace(/\\\\/g,"\\"))));const o={...r,env:{LANG:"en_US.utf-8",EDITOR:void 0,GRAPHITE_INTERACTIVE:"true",GIT_OPTIONAL_LOCKS:"0"},cwd:n};return!e&&process.argv[1].startsWith("/snapshot/")?(e=process.argv[0],s=["/snapshot/monologue/apps/public/cli/dist/graphite.js",...s]):e||(e="gt"),{command:e,args:s,options:o}}var q=n(32081);const H={platformName:"browser",handleMessageFromClient:(e,t)=>{switch(t.type){case"platform/openFile":{const n=l().join((0,r.unwrap)(e?.info.repoRoot),t.path);let s;if(null==s)switch(process.platform){case"darwin":s="/usr/bin/open";break;case"win32":s="notepad.exe";break;case"linux":s="xdg-open"}if(s){e?.logger.log("open file",n);const t=(0,q.spawn)(s,[n],{detached:!0,stdio:"ignore",windowsHide:!1,windowsVerbatimArguments:!0});t.on("error",(t=>{e?.logger.log("failed to open",n,t)})),t.unref()}break}}}};class B{promise;disposeFunc;constructor(e,t){this.promise=e,this.disposeFunc=t}unref(){this.disposed||(this.disposed=!0,this.disposeFunc())}internalReference;disposed=!1}class z{value;constructor(e){this.value=e}references=0;isDisposed=!1;ref(){this.references++}getNumberOfReferences(){return this.references}dispose(){this.references--,this.isDisposed||0!==this.references||(this.isDisposed=!0,this.value.dispose())}}const W=new class{RepositoryType;constructor(e=x){this.RepositoryType=e}reposByRoot=new Map;activeReposEmitter=new M;lookup(e){for(const n of this.reposByRoot.values())if((e===n.value.info.repoRoot||e.startsWith((t=n.value.info.repoRoot).endsWith(l().sep)?t:t+l().sep))&&!n.isDisposed)return n;var t}getOrCreate(e,t,n){const r=this.lookup(n);if(r)return r.ref(),new B(Promise.resolve(r.value),(()=>r.dispose()));let s;return s=new B((async()=>{const r=await this.RepositoryType.getRepoInfo(e,t,n);if("success"!==r.type)return r;if(s.disposed)return{type:"unknownError",error:new Error("Repository already disposed")};const o=this.lookup(r.repoRoot);if(o)return o.ref(),s.internalReference=o,o.value;const i=new this.RepositoryType(r,t),a=new z(i);return a.ref(),s.internalReference=a,this.reposByRoot.set(r.repoRoot,a),this.activeReposEmitter.emit("change"),i})(),(()=>{s.internalReference&&s.internalReference.dispose(),s.unref()})),s}cachedRepositoryForPath(e){const t=this.lookup(e);return t?.value}onChangeActiveRepos(e){const t=()=>{e([...this.reposByRoot.values()].map((e=>e.value)))};return this.activeReposEmitter.on("change",t),t(),()=>this.activeReposEmitter.off("change",t)}clearCache(){this.reposByRoot.forEach((e=>e.dispose())),this.reposByRoot=new Map,this.activeReposEmitter.removeAllListeners()}numberOfActiveServers(){let e=0;for(const t of this.reposByRoot.values())e+=t.getNumberOfReferences();return e}};class V{platform;connection;tracker;logger;listenersByType=new Map;incomingListener;repoDisposables=[];subscriptions=new Map;activeRepoRef;queuedMessages=[];currentState={type:"loading"};pageId=(0,r.randomId)();constructor(e,t,n,s){this.platform=e,this.connection=t,this.tracker=n,this.logger=s;let o=null;this.incomingListener=this.connection.onDidReceiveMessage(((e,n)=>{if(n)return null==o?void t.logger?.error("Error: got a binary message when not expecting one"):(this.handleIncomingMessageWithPayload(o,e),void(o=null));if(null!=o)return t.logger?.error("Error: didnt get binary payload after a message that requires one"),void(o=null);const s=e.toString("utf-8"),i=(0,r.deserializeFromString)(s);if(function(e){return null!=e&&"object"==typeof e&&!0===e.hasBinaryPayload}(i))o=i;else if("loading"===this.currentState.type)this.queuedMessages.push(i);else try{this.handleIncomingMessage(i)}catch(e){t.logger?.error("error handling incoming message: ",i,e)}}))}setRepoError(e){this.disposeRepoDisposables(),this.currentState={type:"error",error:e},this.tracker.context.setRepo(void 0),this.processQueuedMessages()}setCurrentRepo(e,t){this.disposeRepoDisposables(),this.currentState={type:"repo",repo:e,cwd:t},this.tracker.context.setRepo(e),null!=e.codeReviewProvider&&this.repoDisposables.push(e.codeReviewProvider.onChangeDiffSummaries((e=>{this.postMessage({type:"fetchedDiffSummaries",summaries:e})}))),this.repoDisposables.push(e.subscribeToHeadCommit((t=>{const n=e.getSmartlogCommits(),r=function(e,t){let n;if(null!=e){const r=new Map(e.map((e=>[e.branch,e])));let s=t;for(;null!=s;){if(s.partOfTrunk){n=s;break}if(null==s.parents[0])break;s=r.get(s.parents[0])}}return n}(n?.commits.value,t);this.tracker.track("HeadCommitChanged",{extras:{hash:t.branch,public:r?.branch}})}))),this.processQueuedMessages()}postMessage(e){this.connection.postMessage((0,r.serializeToString)(e)).catch((()=>{console.warn("Failed to post message to client")}))}setActiveRepoForCwd(e){void 0!==this.activeRepoRef&&this.activeRepoRef.unref(),this.logger.info(`Setting active repo cwd to ${e}`),this.currentState={type:"loading"};const t=this.connection.command;this.activeRepoRef=W.getOrCreate(t,this.logger,e),this.activeRepoRef.promise.then((t=>{t instanceof x?this.setCurrentRepo(t,e):this.setRepoError(t)}))}dispose(){this.incomingListener.dispose(),this.disposeRepoDisposables(),void 0!==this.activeRepoRef&&this.activeRepoRef.unref()}disposeRepoDisposables(){this.repoDisposables.forEach((e=>e.dispose())),this.repoDisposables=[],this.subscriptions.forEach((e=>e.dispose())),this.subscriptions.clear()}processQueuedMessages(){for(const e of this.queuedMessages)try{this.handleIncomingMessage(e)}catch(t){this.connection.logger?.error("error handling queued message: ",e,t)}this.queuedMessages=[]}handleIncomingMessageWithPayload(e,t){switch(e.type){case"uploadFile":{const{id:n,filename:s}=e,o=null;if(null==o)return;this.tracker.operation("UploadImage","UploadImageError",{},(()=>o((0,r.unwrap)(this.connection.logger),{filename:s,data:t}))).then((e=>{this.connection.logger?.info("sucessfully uploaded file",s,e),this.postMessage({type:"uploadFileResult",id:n,result:{value:e}})})).catch((e=>{this.connection.logger?.info("error uploading file",s,e),this.postMessage({type:"uploadFileResult",id:n,result:{error:e}})}));break}}}handleIncomingMessage(e){this.handleIncomingGeneralMessage(e);const{currentState:t}=this;switch(t.type){case"repo":{const{repo:n,cwd:r}=t;this.handleIncomingMessageWithRepo(e,n,r);break}case"loading":case"error":e.type.startsWith("platform/")&&(this.platform.handleMessageFromClient(void 0,e,(e=>this.postMessage(e)),(e=>{this.repoDisposables.push({dispose:e})})),this.notifyListeners(e))}}handleIncomingGeneralMessage(e){switch(e.type){case"track":this.tracker.trackData(e.data);break;case"changeCwd":this.setActiveRepoForCwd(e.cwd);break;case"requestRepoInfo":switch(this.currentState.type){case"repo":this.postMessage({type:"repoInfo",info:this.currentState.repo.info,cwd:this.currentState.cwd});break;case"error":this.postMessage({type:"repoInfo",info:this.currentState.error})}break;case"requestApplicationInfo":this.postMessage({type:"applicationInfo",platformName:this.platform.platformName,version:this.connection.version})}}handleIncomingMessageWithRepo(e,t,n){const{logger:s}=t;switch(e.type){case"subscribe":{const{subscriptionID:n,kind:r}=e;switch(r){case"uncommittedChanges":{const e=e=>{this.postMessage({type:"subscriptionResult",kind:"uncommittedChanges",subscriptionID:n,data:e})},r=t.getUncommittedChanges();null!=r&&e(r);const s=[];s.push(t.subscribeToUncommittedChanges(e)),t.fetchUncommittedChanges(),s.push(t.subscribeToUncommittedChangesBeginFetching((()=>this.postMessage({type:"beganFetchingUncommittedChangesEvent"})))),this.subscriptions.set(n,{dispose:()=>{s.forEach((e=>e.dispose()))}});break}case"smartlogCommits":{const e=e=>{this.postMessage({type:"subscriptionResult",kind:"smartlogCommits",subscriptionID:n,data:e})},r=t.getSmartlogCommits();null!=r&&e(r);const s=[];s.push(t.subscribeToSmartlogCommitsChanges(e)),t.fetchSmartlogCommits(),s.push(t.subscribeToSmartlogCommitsBeginFetching((()=>this.postMessage({type:"beganFetchingSmartlogCommitsEvent"})))),this.subscriptions.set(n,{dispose:()=>{s.forEach((e=>e.dispose()))}});break}case"mergeConflicts":{const e=e=>{this.postMessage({type:"subscriptionResult",kind:"mergeConflicts",subscriptionID:n,data:e})},r=t.getMergeConflicts();null!=r&&e(r),this.subscriptions.set(n,t.onChangeConflictState(e));break}}break}case"unsubscribe":{const t=this.subscriptions.get(e.subscriptionID);t?.dispose(),this.subscriptions.delete(e.subscriptionID);break}case"runOperation":{const{operation:r}=e;t.runOrQueueOperation(r,(e=>{this.postMessage({type:"operationProgress",...e}),"queue"===e.kind&&this.tracker.track("QueueOperation",{extras:{operation:r.trackEventName}})}),this.tracker,n);break}case"abortRunningOperation":{const{operationId:n}=e;t.abortRunningOpeation(n);break}case"getConfig":t.getConfig(e.name).catch((()=>{})).then((t=>{s.info("got config",e.name,t),this.postMessage({type:"gotConfig",name:e.name,value:t})}));break;case"fetchRepoMessage":t.runCommand(["internal-only","repo-message"]).then((e=>({value:e.stdout}))).catch((e=>(s?.error("error fetching repo message",e.toString()),{error:e}))).then((e=>this.postMessage({type:"fetchedRepoMessage",message:e.value||""})));break;case"fetchUpgradePrompt":t.runCommand(["internal-only","upgrade-prompt"]).then((e=>({value:e.stdout}))).catch((e=>(s?.error("error fetching upgrade prompt",e.toString()),{error:e}))).then((e=>this.postMessage({type:"fetchedUpgradePrompt",message:e.value||""})));break;case"setConfig":s.info("set config",e.name,e.value),t.setConfig("user",e.name,e.value).catch((t=>{s.error("error setting config",e.name,e.value,t)}));break;case"deleteFile":{const{filePath:n}=e,r=function(e,t,n=l()){const r=n.resolve(t.info.repoRoot,e);return r.startsWith(t.info.repoRoot+n.sep)?r:null}(n,t);if(null==r)return void s.warn("can't delete file outside of the repo",n);o().promises.rm(r).then((()=>{s.info("deleted file from filesystem",r)})).catch((e=>{s.error("unable to delete file",r,e)}));break}case"requestComparison":{const{comparison:n}=e;t.runCommand(["internal-only","diff",...(0,r.revsetArgsForComparison)(n)]).then((e=>({value:e.stdout}))).catch((e=>(s?.error("error running diff",e.toString()),{error:e}))).then((e=>this.postMessage({type:"comparison",comparison:n,data:{diff:e}})));break}case"requestChangedFiles":{const{branch:n}=e;t.runCommand(["internal-only","changed-files",n]).then((e=>JSON.parse(e.stdout))).catch((e=>(s?.error("error running diff",e.toString()),{error:e}))).then((e=>this.postMessage({type:"changedFiles",branch:n,data:e})));break}case"requestComparisonContextLines":{const{id:{path:n,comparison:r},start:s,numLines:o}=e;t.cat(n,r).catch((()=>"")).then((e=>this.postMessage({type:"comparisonContextLines",lines:e.split("\n").slice(s-1,s-1+o),path:n})));break}case"refresh":s?.log("refresh requested"),t.fetchSmartlogCommits(),t.fetchUncommittedChanges(),t.codeReviewProvider?.triggerDiffSummariesFetch(t.getAllDiffIds());break;case"pageVisibility":t.setPageFocus(this.pageId,e.state);break;case"fetchCommitMessageTemplate":t.runCommand(["internal-only","templates"]).then((e=>{const n=JSON.parse(e.stdout);this.postMessage({type:"fetchedCommitMessageTemplate",templates:Object.fromEntries(Object.entries(n).map((([e,n])=>[e,n.replace(t.IGNORE_COMMIT_MESSAGE_LINES_REGEX,"")])))})})).catch((e=>{s?.error("Could not fetch commit message template",e)}));break;case"typeahead":t.codeReviewProvider?.typeahead?.(e.kind,e.query)?.then((t=>this.postMessage({type:"typeaheadResult",id:e.id,result:t})));break;case"fetchDiffSummaries":t.codeReviewProvider?.triggerDiffSummariesFetch(t.getAllDiffIds());break;case"loadMoreCommits":{const e=t.nextVisibleCommitRangeInDays();return this.postMessage({type:"commitsShownRange",rangeInDays:e}),this.postMessage({type:"beganLoadingMoreCommits"}),t.fetchSmartlogCommits(),void this.tracker.track("LoadMoreCommits",{extras:{daysToFetch:e??"Infinity"}})}default:this.platform.handleMessageFromClient(t,e,(e=>this.postMessage(e)),(e=>{this.repoDisposables.push({dispose:e})}))}this.notifyListeners(e)}notifyListeners(e){const t=this.listenersByType.get(e.type);t&&t.forEach((t=>t(e)))}}var G=n(6113);const J="win32"==process.platform?l().join((0,r.unwrap)(process.env.LOCALAPPDATA),"cache"):"darwin"==process.platform?l().join(g().homedir(),"Library/Caches"):process.env.XDG_CACHE_HOME||l().join(g().homedir(),".cache");function Q(e,t){const n=Buffer.from(e),r=Buffer.from(t);return n.length===r.length&&(0,G.timingSafeEqual)(n,r)}function K(e){const t=e.logger??(e.logFileLocation?function(e){const t=(...t)=>{const n=b().format(...t)+"\n";o().promises.appendFile(e,n)};return{info:t,log:t,warn:t,error:t,getLogFileContents:()=>o().promises.readFile(e,"utf-8")}}(e.logFileLocation):w);e.logger=t;const n=e?.platform??H,s=e?.version??"unknown";t.log(`establish client connection for ${e.cwd}`),t.log(`platform '${n.platformName}', version '${s}', command '${e.command}'`);const i=function(e,t,n,s=C){return new r.Tracker(((e,t)=>{const{logger:n}=t;n.log("[track]",e.eventName,e.errorName??"",e.errorMessage??"",null!=e.extras?JSON.stringify(e.extras):"");try{Promise.resolve(s({...e,...t.data})).catch((e=>{}))}catch{}}),new v(e,function(e,t){return{platform:e,version:t,repo:void 0,sessionId:(0,r.randomId)(),unixname:f(),osArch:g().arch(),osType:g().platform(),osRelease:g().release(),hostname:g().hostname()}}(t.platformName,n)))}(t,n,s,(t=>F({command:e.command||"gt",args:["internal-only","log-action",t.eventName||t.errorName||"UNKNOWN_CLI_EVENT",(t.timestamp?new Date(t.timestamp):new Date).toISOString(),JSON.stringify(t)],cwd:e.cwd})));i.track("ClientConnection",{extras:{cwd:e.cwd}});let a=new V(n,e,i,t);return a.setActiveRepoForCwd(e.cwd),()=>{a?.dispose(),a=null}}function X({port:e,sensitiveToken:t,challengeToken:n,logFileLocation:s,logInfo:i,command:c,gtVersion:u,foreground:h,frontendDir:p}){return new Promise((g=>{try{const e=JSON.parse(o().readFileSync(l().join(p,"build/asset-manifest.json"),"utf-8"));for(const t of Object.values(e.files))t.startsWith("/")||g({type:"error",error:`expected entry to start with / but was: \`${t}\``}),ee[t]=t.slice(1)}catch(e){}ee["/favicon.ico"]="favicon.ico";const f=a().createServer((async(e,r)=>{if(e.url){const{pathname:i}=d().parse(e.url);if(null!=i&&ee.hasOwnProperty(i)){const e=ee[i];let t;try{t=await o().promises.readFile(l().join(p,"build",e))}catch(e){return r.writeHead(500,{"Content-Type":"text/plain"}),void r.end((s=e.toString(),s.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"")))}const n=e.lastIndexOf("."),a=e.slice(n+1),c=Z[a]??"text/plain";return r.writeHead(200,{"Content-Type":c}),void r.end(t)}if("/challenge_authenticity"===i){const s=Y(e.url).get("token");if(s&&Q(s,t)){r.writeHead(200,{"Content-Type":"text/json"});const e={challengeToken:n,pid:process.pid};r.end(JSON.stringify(e))}else r.writeHead(401,{"Content-Type":"text/json"}),r.end(JSON.stringify({error:"invalid token"}));return}}var s;r.writeHead(404,{"Content-Type":"text/html"}),r.end("<html><body>Not Found!</body></html>")})),v=f.listen(e),C=new(m().Server)({noServer:!0,path:"/ws"});C.on("connection",((e,n)=>{let o,a,l;if(n.url){const e=Y(n.url);o=e.get("token");const t=e.get("cwd");l=e.get("platform"),t&&(a=decodeURIComponent(t))}if(!o){const t="No token provided in websocket request";return i("closing ws:",t),void e.close(r.CLOSED_AND_SHOULD_NOT_RECONNECT_CODE,t)}if(!Q(o,t)){const t="Invalid token";return i("closing ws:",t),void e.close(r.CLOSED_AND_SHOULD_NOT_RECONNECT_CODE,t)}const d=K({postMessage:t=>(e.send(t),Promise.resolve(!0)),onDidReceiveMessage(t){const n=e.on("message",t);return{dispose:()=>n.off("message",t)}},cwd:a??process.cwd(),logFileLocation:"stdout"===s?void 0:s,command:c,version:u,platform:void 0});e.on("close",(()=>{d(),h||setTimeout((()=>{0===W.numberOfActiveServers()&&process.exit(0)}),6e4)}))})),v.on("upgrade",((e,t,n)=>{C.handleUpgrade(e,t,n,(t=>{C.emit("connection",t,e)}))})),f.on("error",(function(t){if("listen"!==t.syscall)throw g({type:"error",error:t.toString()}),t;switch(t.code){case"EACCES":throw g({type:"error",error:`Port ${e} requires elevated privileges`}),t;case"EADDRINUSE":return void g({type:"addressInUse"});default:throw g({type:"error",error:t.toString()}),t}})),f.on("listening",(()=>g({type:"success",port:f.address().port,pid:process.pid})))}))}function Y(e){const t=d().parse(e).search?.replace(/^\?/,"").split("&").map((e=>e.split("=")));return new Map(t)}l().join(J,"graphite-gti");const Z={css:"text/css",html:"text/html",js:"text/javascript",ttf:"font/ttf"},ee={"/":"index.html"}}};
|
|
3
|
-
//# sourceMappingURL=999.js.map
|
package/999.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"999.js","mappings":"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","sources":["webpack://@withgraphite/graphite-cli/../../src/Comparison.ts","webpack://@withgraphite/graphite-cli/../../src/LRU.ts","webpack://@withgraphite/graphite-cli/../../../src/analytics/index.ts","webpack://@withgraphite/graphite-cli/../../../src/analytics/tracker.ts","webpack://@withgraphite/graphite-cli/../../src/compat.ts","webpack://@withgraphite/graphite-cli/../../src/debounce.ts","webpack://@withgraphite/graphite-cli/../../src/immutableExt.ts","webpack://@withgraphite/graphite-cli/../../src/index.ts","webpack://@withgraphite/graphite-cli/../../src/minimalDisambiguousPaths.ts","webpack://@withgraphite/graphite-cli/../../../src/patch/parse.ts","webpack://@withgraphite/graphite-cli/../../src/serialize.ts","webpack://@withgraphite/graphite-cli/../../../src/types/client.ts","webpack://@withgraphite/graphite-cli/../../../src/types/constants.ts","webpack://@withgraphite/graphite-cli/../../../src/types/index.ts","webpack://@withgraphite/graphite-cli/../../src/utils.ts","webpack://@withgraphite/graphite-cli/../gti-server/src/analytics/environment.ts","webpack://@withgraphite/graphite-cli/../gti-server/src/analytics/serverSideTracker.ts","webpack://@withgraphite/graphite-cli/../gti-server/src/logger.ts","webpack://@withgraphite/graphite-cli/../gti-server/src/TypedEventEmitter.ts","webpack://@withgraphite/graphite-cli/../gti-server/src/github/githubCodeReviewProvider.ts","webpack://@withgraphite/graphite-cli/../gti-server/src/OperationQueue.ts","webpack://@withgraphite/graphite-cli/../gti-server/src/PageFocusTracker.ts","webpack://@withgraphite/graphite-cli/../gti-server/src/RateLimiter.ts","webpack://@withgraphite/graphite-cli/../gti-server/src/utils.ts","webpack://@withgraphite/graphite-cli/../gti-server/src/Repository.ts","webpack://@withgraphite/graphite-cli/../gti-server/src/WatchForChanges.ts","webpack://@withgraphite/graphite-cli/../gti-server/src/fs.ts","webpack://@withgraphite/graphite-cli/../gti-server/src/serverPlatform.ts","webpack://@withgraphite/graphite-cli/../gti-server/src/RepositoryCache.ts","webpack://@withgraphite/graphite-cli/../gti-server/src/ServerToClientAPI.ts","webpack://@withgraphite/graphite-cli/../gti-server/proxy/existingServerStateFiles.ts","webpack://@withgraphite/graphite-cli/../gti-server/proxy/proxyUtils.ts","webpack://@withgraphite/graphite-cli/../gti-server/src/index.ts","webpack://@withgraphite/graphite-cli/../gti-server/proxy/server.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"import type { ApplicationInfo } from \"@withgraphite/gti-shared\";\nimport { randomId, unwrap } from \"@withgraphite/gti-shared\";\nimport os from \"os\";\n\nexport function getUsername(): string {\n try {\n return os.userInfo().username;\n } catch (osInfoError) {\n try {\n const { env } = process;\n return unwrap(env.LOGNAME || env.USER || env.LNAME || env.USERNAME);\n } catch (processEnvError) {\n throw new Error(String(processEnvError) + String(osInfoError));\n }\n }\n}\n\nexport function generateAnalyticsInfo(\n platformName: string,\n version: string\n): ApplicationInfo {\n return {\n platform: platformName,\n version,\n repo: undefined,\n /**\n * Random id for this GTI session, created at startup.\n * Note: this is only generated on the server, so client-logged events share the ID with the server.\n */\n sessionId: randomId(),\n unixname: getUsername(),\n osArch: os.arch(),\n osType: os.platform(),\n osRelease: os.release(),\n hostname: os.hostname(),\n };\n}\n","import type {\n ApplicationInfo,\n FullTrackData,\n Logger,\n TrackDataWithEventName,\n} from \"@withgraphite/gti-shared\";\nimport { Tracker } from \"@withgraphite/gti-shared\";\n\nimport type { Repository } from \"../Repository\";\nimport type { ServerPlatform } from \"../serverPlatform\";\nimport { generateAnalyticsInfo } from \"./environment\";\n\nexport type ServerSideTracker = Tracker<ServerSideContext>;\n\nclass ServerSideContext {\n constructor(public logger: Logger, public data: ApplicationInfo) {}\n\n public setRepo(repo: Repository | undefined): void {\n this.data.repo = repo?.codeReviewProvider?.getSummaryName();\n }\n}\n\nconst noOp = (_data: FullTrackData): Promise<unknown> | void => {\n /* In open source builds, analytics tracking is completely disabled/removed. */\n};\n\n/**\n * Creates a Tracker which includes server-side-only cached application data like platform, username, etc,\n * and sends data to the underlying analytics engine outside of GTI.\n * This can not be global since two client connections may have different cached data.\n */\nexport function makeServerSideTracker(\n logger: Logger,\n platform: ServerPlatform,\n version: string,\n // prettier-ignore\n writeToServer = noOp\n): ServerSideTracker {\n return new Tracker(\n (data: TrackDataWithEventName, context: ServerSideContext) => {\n const { logger } = context;\n // log track event, since tracking events can be used as datapoints when reviewing logs\n logger.log(\n \"[track]\",\n data.eventName,\n data.errorName ?? \"\",\n data.errorMessage ?? \"\",\n data.extras != null ? JSON.stringify(data.extras) : \"\"\n );\n try {\n Promise.resolve(writeToServer({ ...data, ...context.data })).catch(\n (err) => void err\n );\n } catch {\n // pass\n }\n },\n new ServerSideContext(\n logger,\n generateAnalyticsInfo(platform.platformName, version)\n )\n );\n}\n","import type { Logger } from \"@withgraphite/gti-shared\";\nimport fs from \"fs\";\nimport util from \"util\";\n\nexport const stdoutLogger = console;\n\nexport function fileLogger(filename: string): Logger {\n const log = (...args: Parameters<typeof console.log>) => {\n const str = util.format(...args) + \"\\n\";\n void fs.promises.appendFile(filename, str);\n };\n\n return {\n info: log,\n log,\n warn: log,\n error: log,\n\n getLogFileContents: () => {\n return fs.promises.readFile(filename, \"utf-8\");\n },\n };\n}\n","import { EventEmitter } from \"events\";\n\n/**\n * Like {@link EventEmitter}, but with type checking for one particular subscription type,\n * plus errors.\n * ```\n * const myEmitter = new TypedEventEmitter<'data', number>();\n * myEmitter.on('data', (data: number) => ...); // typechecks 'data' param and callback\n * myEmitter.on('error', (error: Error) => ...); // errors are always allowed too\n * // Fields other than 'data' and 'error' are type errors.\n * ```\n */\nexport declare interface TypedEventEmitter<\n EventName extends string,\n EventType\n> {\n on(event: EventName, listener: (data: EventType) => void): this;\n on(event: \"error\", listener: (error: Error) => void): this;\n off(event: EventName, listener: (data: EventType) => void): this;\n off(event: \"error\", listener: (error: Error) => void): this;\n\n emit(\n ...args: EventType extends undefined\n ? [event: EventName] | [event: EventName, data: EventType]\n : [event: EventName, data: EventType]\n ): boolean;\n emit(event: \"error\", error: Error): boolean;\n}\n\nexport class TypedEventEmitter<\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n EventName extends string,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n EventType\n> extends EventEmitter {}\n","import type { PRInfo, PRNumber } from \"@withgraphite/gti-cli-shared-types\";\nimport type {\n CodeReviewSystem,\n Disposable,\n GitHubDiffSummary,\n OperationCommandProgressReporter,\n Result,\n TypeaheadKind,\n TypeaheadResult,\n} from \"@withgraphite/gti-shared\";\nimport type execa from \"execa\";\n\nimport { TypedEventEmitter } from \"../TypedEventEmitter\";\n\ntype GitHubCodeReviewSystem = CodeReviewSystem & { type: \"github\" };\nexport class GitHubCodeReviewProvider {\n constructor(\n private codeReviewSystem: GitHubCodeReviewSystem,\n private runCommand: (\n args: Array<string>,\n cwd?: string,\n options?: execa.Options\n ) => execa.ExecaChildProcess<string>\n ) {}\n private diffSummaries = new TypedEventEmitter<\"data\", GitHubDiffSummary[]>();\n\n onChangeDiffSummaries(\n callback: (result: Result<GitHubDiffSummary[]>) => unknown\n ): Disposable {\n const handleData = (data: GitHubDiffSummary[]) => callback({ value: data });\n const handleError = (error: Error) => callback({ error });\n this.diffSummaries.on(\"data\", handleData);\n this.diffSummaries.on(\"error\", handleError);\n return {\n dispose: () => {\n this.diffSummaries.off(\"data\", handleData);\n this.diffSummaries.off(\"error\", handleError);\n },\n };\n }\n\n public async triggerDiffSummariesFetch(_diffs: Array<PRNumber>) {\n const value = await this.runCommand([\"internal-only\", \"prs\"]);\n const prs = JSON.parse(value.stdout) as PRInfo[];\n this.diffSummaries.emit(\"data\", prs);\n }\n\n public dispose() {\n this.diffSummaries.removeAllListeners();\n }\n\n public getSummaryName(): string {\n return `github:${this.codeReviewSystem.hostname}/${this.codeReviewSystem.owner}/${this.codeReviewSystem.repo}`;\n }\n\n /** Run a command not handled within graphite, such as a separate submit handler */\n public runExternalCommand(\n _cwd: string,\n _args: Array<string>,\n _onProgress: OperationCommandProgressReporter,\n _signal: AbortSignal\n ): Promise<void> {\n throw new Error(\n \"GitHub code review provider does not support running external commands\"\n );\n }\n\n public async typeahead(\n _kind: TypeaheadKind,\n _query: string\n ): Promise<Array<TypeaheadResult>> {\n return Promise.resolve([]);\n }\n}\n\n// function githubCheckSuitesToCIStatus(\n// checkSuites: CheckSuiteConnection | undefined | null,\n// ): DiffSignalSummary {\n// let anyInProgress = false;\n// let anyWarning = false;\n// for (const checkSuite of checkSuites?.nodes ?? []) {\n// switch (checkSuite?.status) {\n// case CheckStatusState.Completed:\n// {\n// switch (checkSuite?.conclusion) {\n// case CheckConclusionState.Success:\n// break;\n// case CheckConclusionState.Neutral:\n// case CheckConclusionState.Stale:\n// case CheckConclusionState.Skipped:\n// anyWarning = true;\n// break;\n// case CheckConclusionState.ActionRequired:\n// case CheckConclusionState.StartupFailure:\n// case CheckConclusionState.Cancelled:\n// case CheckConclusionState.TimedOut:\n// case CheckConclusionState.Failure:\n// return 'failed'; // no need to look at other signals\n// }\n// }\n// break;\n// case CheckStatusState.Waiting:\n// case CheckStatusState.Requested:\n// case CheckStatusState.Queued:\n// case CheckStatusState.Pending:\n// case CheckStatusState.InProgress:\n// anyInProgress = true;\n// break;\n// }\n// }\n// return anyWarning ? 'warning' : anyInProgress ? 'running' : 'pass';\n// }\n","import type {\n Logger,\n OperationCommandProgressReporter,\n OperationProgress,\n RunnableOperation,\n} from \"@withgraphite/gti-shared\";\nimport { newAbortController } from \"@withgraphite/gti-shared\";\n\nimport type { ServerSideTracker } from \"./analytics/serverSideTracker\";\n\n/**\n * Handle running & queueing all Operations so that only one Operation runs at once.\n * Operations may be run by gt in the Repository or other providers like ghstack in the RemoteRepository.\n */\nexport class OperationQueue {\n constructor(\n private logger: Logger,\n private runCallback: (\n operation: RunnableOperation,\n cwd: string,\n handleProgress: OperationCommandProgressReporter,\n signal: AbortSignal\n ) => Promise<void>\n ) {}\n\n private queuedOperations: Array<\n RunnableOperation & { tracker: ServerSideTracker }\n > = [];\n private runningOperation: RunnableOperation | undefined = undefined;\n private abortController: AbortController | undefined = undefined;\n\n async runOrQueueOperation(\n operation: RunnableOperation,\n onProgress: (progress: OperationProgress) => void,\n tracker: ServerSideTracker,\n cwd: string\n ): Promise<void> {\n if (this.runningOperation != null) {\n this.queuedOperations.push({ ...operation, tracker });\n onProgress({\n id: operation.id,\n kind: \"queue\",\n queue: this.queuedOperations.map((o) => o.id),\n });\n return;\n }\n this.runningOperation = operation;\n\n const handleCommandProgress: OperationCommandProgressReporter = (\n ...args\n ) => {\n switch (args[0]) {\n case \"spawn\":\n onProgress({\n id: operation.id,\n kind: \"spawn\",\n queue: this.queuedOperations.map((op) => op.id),\n });\n break;\n\n case \"stdout\":\n onProgress({ id: operation.id, kind: \"stdout\", message: args[1] });\n break;\n\n case \"stderr\":\n onProgress({ id: operation.id, kind: \"stderr\", message: args[1] });\n break;\n\n case \"exit\":\n onProgress({\n id: operation.id,\n kind: \"exit\",\n exitCode: args[1],\n timestamp: Date.now(),\n });\n break;\n }\n };\n\n try {\n const controller = newAbortController();\n this.abortController = controller;\n await tracker.operation(\n operation.trackEventName,\n \"RunOperationError\",\n { extras: { args: operation.args, runner: operation.runner } },\n (_p) =>\n this.runCallback(\n operation,\n cwd,\n handleCommandProgress,\n controller.signal\n )\n );\n this.runningOperation = undefined;\n\n // now that we successfully ran this operation, dequeue the next\n if (this.queuedOperations.length > 0) {\n const op = this.queuedOperations.shift();\n if (op != null) {\n // don't await this, the caller should resolve when the original operation finishes.\n void this.runOrQueueOperation(\n op,\n // TODO: we're using the onProgress from the LAST `runOperation`... should we be keeping the newer onProgress in the queued operation?\n onProgress,\n op.tracker,\n cwd\n );\n }\n }\n } catch (err) {\n const errString = (err as Error).toString();\n this.logger.log(\n \"error running operation: \",\n operation.args[0],\n errString\n );\n onProgress({ id: operation.id, kind: \"error\", error: errString });\n // clear queue to run when we hit an error\n this.queuedOperations = [];\n this.runningOperation = undefined;\n }\n }\n\n /**\n * Send kill signal to the running operation if the operationId matches.\n * If the process exits, the exit event will be noticed by the queue.\n * This function does not block on waiting for the operation process to exit.\n */\n abortRunningOperation(operationId: string) {\n if (this.runningOperation?.id == operationId) {\n this.abortController?.abort();\n }\n }\n}\n","import type { PageVisibility } from \"@withgraphite/gti-shared\";\n\n/**\n * Aggregates if any GTI page has focus or visibility.\n */\nexport class PageFocusTracker {\n private focusedPages = new Set();\n private visiblePages = new Set();\n\n private onChangeHandlers = new Set<(state: PageVisibility) => unknown>();\n\n setState(page: string, state: PageVisibility) {\n switch (state) {\n case \"focused\":\n this.focusedPages.add(page);\n this.visiblePages.add(page);\n break;\n\n case \"visible\":\n this.focusedPages.delete(page);\n this.visiblePages.add(page);\n break;\n\n case \"hidden\":\n this.focusedPages.delete(page);\n this.visiblePages.delete(page);\n break;\n }\n for (const handler of this.onChangeHandlers) {\n handler(state);\n }\n }\n\n public disposePage(page: string) {\n this.focusedPages.delete(page);\n this.visiblePages.delete(page);\n }\n\n public hasPageWithFocus() {\n return this.focusedPages.size > 0;\n }\n public hasVisiblePage() {\n return this.visiblePages.size > 0;\n }\n\n public onChange(callback: () => unknown): () => void {\n this.onChangeHandlers.add(callback);\n return () => this.onChangeHandlers.delete(callback);\n }\n}\n","import { TypedEventEmitter } from \"./TypedEventEmitter\";\n\ntype Id = number;\n\n/**\n * Rate limits requests to run an arbitrary task.\n * Up to `maxSimultaneousRunning` tasks can run at once,\n * futher requests will be queued and run when a running task finishes.\n *\n * Usage:\n * ```\n * const rateLimiter = new RateLimiter(5);\n * const result = await rateLimiter.enqueueRun(() => {\n * // ...do arbitrary async work...\n * });\n * ```\n */\nexport class RateLimiter {\n private queued: Array<Id> = [];\n private running: Array<Id> = [];\n private runs = new TypedEventEmitter<\"run\", Id>();\n\n constructor(\n private maxSimultaneousRunning: number,\n private log?: (s: string) => unknown\n ) {}\n\n private nextId = 1;\n private generateId(): Id {\n return this.nextId++;\n }\n\n async enqueueRun<T>(runner: () => Promise<T>): Promise<T> {\n const id = this.generateId();\n\n this.queued.push(id);\n this.tryDequeueNext();\n\n if (!this.running.includes(id)) {\n this.log?.(\n `${this.running.length} tasks are already running, enqueuing ID:${id}`\n );\n await new Promise((res) => {\n this.runs.on(\"run\", (ran) => {\n if (ran === id) {\n this.log?.(`now allowing ID:${id} to run`);\n res(undefined);\n }\n });\n });\n }\n\n try {\n return await runner();\n } finally {\n this.notifyFinished(id);\n }\n }\n\n private notifyFinished(id: Id): void {\n this.running = this.running.filter((running) => running !== id);\n this.tryDequeueNext();\n }\n\n private tryDequeueNext() {\n if (this.running.length < this.maxSimultaneousRunning) {\n const toRun = this.queued.shift();\n if (toRun != null) {\n this.run(toRun);\n }\n }\n }\n\n private run(id: Id) {\n this.running.push(id);\n this.runs.emit(\"run\", id);\n }\n}\n","import type { BranchInfo } from \"@withgraphite/gti-cli-shared-types\";\nimport type { SmartlogCommits } from \"@withgraphite/gti-shared\";\nimport { truncate } from \"@withgraphite/gti-shared\";\nimport type { ExecaChildProcess } from \"execa\";\nimport type execa from \"execa\";\nimport os from \"os\";\n\nexport function sleep(timeMs: number): Promise<void> {\n return new Promise((res) => setTimeout(res, timeMs));\n}\n\nexport function firstOfIterable<T>(\n iterable: IterableIterator<T>\n): T | undefined {\n return iterable.next().value;\n}\n\n/**\n * Limits async function execution parallelism to only one at a time.\n * Hence, if a call is already running, it will wait for it to finish,\n * then start the next async execution, but if called again while not finished,\n * it will return the scheduled execution promise.\n *\n * Sample Usage:\n * ```\n * let i = 1;\n * const oneExecAtATime = serializeAsyncCall(() => {\n * return new Promise((resolve, reject) => {\n * setTimeout(200, () => resolve(i++));\n * });\n * });\n *\n * const result1Promise = oneExecAtATime(); // Start an async, and resolve to 1 in 200 ms.\n * const result2Promise = oneExecAtATime(); // Schedule the next async, and resolve to 2 in 400 ms.\n * const result3Promise = oneExecAtATime(); // Reuse scheduled promise and resolve to 2 in 400 ms.\n * ```\n */\nexport function serializeAsyncCall<T>(\n asyncFun: () => Promise<T>\n): () => Promise<T> {\n let scheduledCall: Promise<T> | undefined = undefined;\n let pendingCall: Promise<undefined> | undefined = undefined;\n const startAsyncCall = () => {\n const resultPromise = asyncFun();\n pendingCall = resultPromise.then(\n () => (pendingCall = undefined),\n () => (pendingCall = undefined)\n );\n return resultPromise;\n };\n const callNext = () => {\n scheduledCall = undefined;\n return startAsyncCall();\n };\n const scheduleNextCall = () => {\n if (scheduledCall == null) {\n if (pendingCall == null) {\n throw new Error(\"pendingCall must not be null!\");\n }\n scheduledCall = pendingCall.then(callNext, callNext);\n }\n return scheduledCall;\n };\n return () => {\n if (pendingCall == null) {\n return startAsyncCall();\n } else {\n return scheduleNextCall();\n }\n };\n}\n\n/**\n * Kill `child` on `AbortSignal`.\n *\n * This is slightly more robust than execa 6.0 and nodejs' `signal` support:\n * if a process was stopped (by `SIGTSTP` or `SIGSTOP`), it can still be killed.\n */\nexport function handleAbortSignalOnProcess(\n child: ExecaChildProcess,\n signal: AbortSignal\n) {\n signal.addEventListener(\"abort\", () => {\n if (os.platform() == \"win32\") {\n // Signals are ignored on Windows.\n // execa's default forceKillAfterTimeout behavior does not\n // make sense for Windows. Disable it explicitly.\n child.kill(\"SIGKILL\", { forceKillAfterTimeout: false });\n } else {\n // If the process is stopped (ex. Ctrl+Z, kill -STOP), make it\n // continue first so it can respond to signals including SIGKILL.\n child.kill(\"SIGCONT\");\n // A good citizen process should exit soon after recieving SIGTERM.\n // In case it doesn't, send SIGKILL after 5 seconds.\n child.kill(\"SIGTERM\", { forceKillAfterTimeout: 5000 });\n }\n });\n}\n\n/**\n * Given a list of commits and a starting commit,\n * traverse up the chain of `parents` until we find a public commit\n */\nexport function findPublicAncestor(\n allCommits: SmartlogCommits | undefined,\n from: BranchInfo\n): BranchInfo | undefined {\n let publicCommit: BranchInfo | undefined;\n if (allCommits != null) {\n const map = new Map(allCommits.map((commit) => [commit.branch, commit]));\n\n let current: BranchInfo | undefined = from;\n while (current != null) {\n if (current.partOfTrunk) {\n publicCommit = current;\n break;\n }\n if (current.parents[0] == null) {\n break;\n }\n current = map.get(current.parents[0]);\n }\n }\n\n return publicCommit;\n}\n\n/**\n * Run a command that is expected to produce JSON output.\n * Return a JSON object. On error, the JSON object has property \"error\".\n */\nexport function parseExecJson<T>(\n exec: execa.ExecaChildProcess,\n reply: (parsed?: T, error?: string) => void\n) {\n exec\n .then((result) => {\n const stdout = result.stdout;\n try {\n const parsed = JSON.parse(stdout);\n if (parsed.error != null) {\n reply(undefined, parsed.error);\n } else {\n reply(parsed as T);\n }\n } catch (err) {\n const msg = `Cannot parse ${truncate(\n result.escapedCommand\n )} output. (error: ${err}, stdout: ${stdout})`;\n reply(undefined, msg);\n }\n })\n .catch((err) => {\n // Try extracting error from stdout '{error: message}'.\n try {\n const parsed = JSON.parse(err.stdout);\n if (parsed.error != null) {\n reply(undefined, parsed.error);\n return;\n }\n } catch {\n // pass\n }\n // Fallback to general error.\n const msg = `Cannot run ${truncate(err.escapedCommand)}. (error: ${err})`;\n reply(undefined, msg);\n });\n}\n","import type {\n BranchInfo,\n PRNumber,\n RepoInfo as RepoInfoFromCLI,\n RepoRelativePath,\n Status,\n} from \"@withgraphite/gti-cli-shared-types\";\nimport type {\n AbsolutePath,\n CodeReviewSystem,\n CommandArg,\n Disposable,\n FetchedCommits,\n FetchedUncommittedChanges,\n Logger,\n MergeConflicts,\n OperationCommandProgressReporter,\n OperationProgress,\n PageVisibility,\n RepoInfo,\n RunnableOperation,\n SmartlogCommits,\n SuccessorInfo,\n ValidatedRepoInfo,\n} from \"@withgraphite/gti-shared\";\nimport {\n CommandRunner,\n Comparison,\n ComparisonType,\n debounce,\n DEFAULT_DAYS_OF_COMMITS_TO_LOAD,\n ErrorShortMessages,\n notEmpty,\n unwrap,\n} from \"@withgraphite/gti-shared\";\nimport execa from \"execa\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport semver from \"semver\";\n\nimport type { ServerSideTracker } from \"./analytics/serverSideTracker\";\nimport { exists, removeLeadingPathSep } from \"./fs\";\nimport { GitHubCodeReviewProvider } from \"./github/githubCodeReviewProvider\";\nimport { OperationQueue } from \"./OperationQueue\";\nimport { PageFocusTracker } from \"./PageFocusTracker\";\nimport { RateLimiter } from \"./RateLimiter\";\nimport { TypedEventEmitter } from \"./TypedEventEmitter\";\nimport { handleAbortSignalOnProcess, serializeAsyncCall } from \"./utils\";\nimport { watchForChanges } from \"./WatchForChanges\";\n\nexport const COMMIT_END_MARK = \"<<COMMIT_END_MARK>>\";\nexport const NULL_CHAR = \"\\0\";\nconst MAX_SIMULTANEOUS_CAT_CALLS = 4;\n\nconst MIN_REQUIRED_CLI_VERSION = \"0.1.4\";\n\ntype ConflictFileData = {\n contents: string;\n exists: boolean;\n isexec: boolean;\n issymlink: boolean;\n};\nexport type ResolveCommandConflictOutput = [\n | {\n command: null;\n conflicts: [];\n pathconflicts: [];\n }\n | {\n command: string;\n command_details: { cmd: string; to_abort: string; to_continue: string };\n conflicts: Array<{\n base: ConflictFileData;\n local: ConflictFileData;\n output: ConflictFileData;\n other: ConflictFileData;\n path: string;\n }>;\n pathconflicts: Array<never>;\n }\n];\n\n/**\n * This class is responsible for providing information about the working copy\n * for a Graphite repository.\n *\n * A Repository may be reused by multiple connections, not just one GTI window.\n * This is so we don't duplicate watchman subscriptions and calls to status/log.\n * A Repository does not have a pre-defined `cwd`, so it may be re-used across cwds.\n *\n * Prefer using `RepositoryCache.getOrCreate()` to access and dispose `Repository`s.\n */\nexport class Repository {\n public IGNORE_COMMIT_MESSAGE_LINES_REGEX = /^((?:HG|SL):.*)/gm;\n\n private mergeConflicts: MergeConflicts | undefined = undefined;\n private uncommittedChanges: FetchedUncommittedChanges | null = null;\n private smartlogCommits: FetchedCommits | null = null;\n\n private mergeConflictsEmitter = new TypedEventEmitter<\n \"change\",\n MergeConflicts | undefined\n >();\n private uncommittedChangesEmitter = new TypedEventEmitter<\n \"change\",\n FetchedUncommittedChanges\n >();\n private smartlogCommitsChangesEmitter = new TypedEventEmitter<\n \"change\",\n FetchedCommits\n >();\n\n private smartlogCommitsBeginFetchingEmitter = new TypedEventEmitter<\n \"start\",\n undefined\n >();\n private uncommittedChangesBeginFetchingEmitter = new TypedEventEmitter<\n \"start\",\n undefined\n >();\n\n private disposables: Array<() => void> = [\n () => this.mergeConflictsEmitter.removeAllListeners(),\n () => this.uncommittedChangesEmitter.removeAllListeners(),\n () => this.smartlogCommitsChangesEmitter.removeAllListeners(),\n () => this.smartlogCommitsBeginFetchingEmitter.removeAllListeners(),\n () => this.uncommittedChangesBeginFetchingEmitter.removeAllListeners(),\n ];\n public onDidDispose(callback: () => unknown): void {\n this.disposables.push(callback);\n }\n\n private operationQueue: OperationQueue;\n private watchForChangesDisposer: undefined | (() => void);\n private pageFocusTracker = new PageFocusTracker();\n public codeReviewProvider?: GitHubCodeReviewProvider;\n\n private currentVisibleCommitRangeIndex = 0;\n private visibleCommitRanges: Array<number | undefined> = [\n DEFAULT_DAYS_OF_COMMITS_TO_LOAD,\n 60,\n undefined,\n ];\n\n /** Prefer using `RepositoryCache.getOrCreate()` to access and dispose `Repository`s. */\n constructor(public info: ValidatedRepoInfo, public logger: Logger) {\n const remote = info.codeReviewSystem;\n if (remote.type === \"github\") {\n this.codeReviewProvider = new GitHubCodeReviewProvider(\n remote,\n this.runCommand.bind(this)\n );\n }\n\n this.watchForChangesDisposer = watchForChanges(info, logger, (kind) => {\n if (kind === \"uncommitted changes\") {\n void this.fetchUncommittedChanges();\n void this.checkForMergeConflicts();\n } else if (kind === \"branches\") {\n void this.fetchSmartlogCommits();\n } else if (kind === \"merge conflicts\") {\n void this.checkForMergeConflicts();\n } else if (kind === \"everything\") {\n void this.fetchUncommittedChanges();\n void this.fetchSmartlogCommits();\n void this.checkForMergeConflicts();\n }\n });\n\n this.operationQueue = new OperationQueue(\n this.logger,\n (\n operation: RunnableOperation,\n cwd: string,\n handleCommandProgress,\n signal: AbortSignal\n ): Promise<void> => {\n if (operation.runner === CommandRunner.Graphite) {\n return this.runOperation(\n operation,\n handleCommandProgress,\n cwd,\n signal\n );\n } else if (operation.runner === CommandRunner.CodeReviewProvider) {\n const normalizedArgs = this.normalizeOperationArgs(\n cwd,\n operation.args\n );\n\n if (this.codeReviewProvider?.runExternalCommand == null) {\n return Promise.reject(\n Error(\n \"CodeReviewProvider does not support running external commands\"\n )\n );\n }\n\n return (\n this.codeReviewProvider?.runExternalCommand(\n cwd,\n normalizedArgs,\n handleCommandProgress,\n signal\n ) ?? Promise.resolve()\n );\n }\n return Promise.resolve();\n }\n );\n\n // refetch summaries whenever we see new diffIds\n const seenDiffs = new Set();\n const subscription = this.subscribeToSmartlogCommitsChanges((fetched) => {\n if (fetched.commits.value) {\n const newDiffs = [];\n const diffIds = fetched.commits.value\n .filter((commit) => commit.pr)\n .map((commit) => commit.pr?.number);\n for (const diffId of diffIds) {\n if (!seenDiffs.has(diffId)) {\n newDiffs.push(diffId);\n seenDiffs.add(diffId);\n }\n }\n if (newDiffs.length > 0) {\n void this.codeReviewProvider?.triggerDiffSummariesFetch(\n // We could choose to only fetch the diffs that changed (`newDiffs`) rather than all diffs,\n // but our UI doesn't cache old values, thus all other diffs would appear empty\n this.getAllDiffIds()\n );\n }\n }\n });\n\n // the repo may already be in a conflict state on startup\n void this.checkForMergeConflicts();\n\n this.disposables.push(() => subscription.dispose());\n }\n\n public nextVisibleCommitRangeInDays(): number | undefined {\n if (\n this.currentVisibleCommitRangeIndex + 1 <\n this.visibleCommitRanges.length\n ) {\n this.currentVisibleCommitRangeIndex++;\n }\n return this.visibleCommitRanges[this.currentVisibleCommitRangeIndex];\n }\n\n /**\n * Typically, disposing is handled by `RepositoryCache` and not used directly.\n */\n public dispose() {\n this.disposables.forEach((dispose) => dispose());\n this.codeReviewProvider?.dispose();\n this.watchForChangesDisposer?.();\n }\n\n public onChangeConflictState(\n callback: (conflicts: MergeConflicts | undefined) => unknown\n ): Disposable {\n this.mergeConflictsEmitter.on(\"change\", callback);\n\n if (this.mergeConflicts) {\n // if we're already in merge conflicts, let the client know right away\n callback(this.mergeConflicts);\n }\n\n return {\n dispose: () => this.mergeConflictsEmitter.off(\"change\", callback),\n };\n }\n\n checkForMergeConflicts = debounce(\n serializeAsyncCall(async () => {\n this.logger.info(\"checking for merge conflicts\");\n // Fast path: check if .git/merge dir changed\n const wasAlreadyInConflicts = this.mergeConflicts != null;\n if (!wasAlreadyInConflicts) {\n const mergeDirExists = await exists(\n path.join(this.info.dotdir, \"rebase-merge\")\n );\n if (!mergeDirExists) {\n // Not in a conflict\n this.logger.info(\n `conflict state still the same (${\n wasAlreadyInConflicts ? \"IN merge conflict\" : \"NOT in conflict\"\n })`\n );\n return;\n }\n }\n\n if (this.mergeConflicts == null) {\n // notify UI that merge conflicts were detected and full details are loading\n this.mergeConflicts = { state: \"loading\" };\n this.mergeConflictsEmitter.emit(\"change\", this.mergeConflicts);\n }\n\n // More expensive full check for conflicts. Necessary if we see .gt/merge change, or if\n // we're already in a conflict and need to re-check if a conflict was resolved.\n\n const fetchStartTimestamp = Date.now();\n let output: Status;\n try {\n const proc = await this.runCommand([\"internal-only\", \"status\"]);\n output = JSON.parse(proc.stdout) as Status;\n } catch (err) {\n this.logger.error(`failed to check for merge conflicts: ${err}`);\n // To avoid being stuck in \"loading\" state forever, let's pretend there's no conflicts.\n this.mergeConflicts = undefined;\n this.mergeConflictsEmitter.emit(\"change\", this.mergeConflicts);\n return;\n }\n const branchName = await fs.promises\n .readFile(path.join(this.info.dotdir, \"rebase-merge\", \"head-name\"))\n .then(\n (contents) => {\n const contentsString = contents.toString();\n return contentsString.startsWith(\"refs/heads/\")\n ? contentsString.slice(\"refs/heads/\".length).trimEnd()\n : undefined;\n },\n () => undefined\n );\n\n this.mergeConflicts = computeNewConflicts(\n this.mergeConflicts,\n branchName,\n output,\n fetchStartTimestamp\n );\n this.logger.info(\n `repo ${this.mergeConflicts ? \"IS\" : \"IS NOT\"} in merge conflicts`,\n {\n mergeConflicts: this.mergeConflicts,\n files: this.mergeConflicts?.files,\n }\n );\n if (this.mergeConflicts) {\n const maxConflictsToLog = 20;\n const remainingConflicts = (this.mergeConflicts.files ?? [])\n .filter((conflict) => conflict.status === \"UNRESOLVED\")\n .map((conflict) => conflict.path)\n .slice(0, maxConflictsToLog);\n this.logger.info(\"remaining files with conflicts: \", {\n branchName,\n remainingConflicts,\n });\n }\n this.mergeConflictsEmitter.emit(\"change\", this.mergeConflicts);\n }),\n 100\n );\n\n public getMergeConflicts(): MergeConflicts | undefined {\n return this.mergeConflicts;\n }\n\n /**\n * Determine basic repo info including the root and important config values.\n * Resulting RepoInfo may have null fields if cwd is not a valid repo root.\n * Throws if `command` is not found.\n */\n static async getRepoInfo(\n command: string | undefined,\n logger: Logger,\n cwd: string\n ): Promise<RepoInfo> {\n const repoVersion = await findVersion(command, logger, cwd).catch(\n (err: Error) => err\n );\n if (repoVersion instanceof Error) {\n return { type: \"invalidCommand\", command: command ?? \"gt\" };\n }\n if (\n repoVersion !== \"local\" &&\n repoVersion !== \"dev\" &&\n semver.lt(repoVersion, MIN_REQUIRED_CLI_VERSION)\n ) {\n return {\n type: \"invalidVersion\",\n command: command ?? \"gt\",\n versionFound: repoVersion,\n versionRequired: MIN_REQUIRED_CLI_VERSION,\n };\n }\n\n const [profile, repoInfoRaw, preferredBranchEdit, createPrsAs] =\n await Promise.all([\n findRepoProfile(command, logger, cwd),\n findRepoInfo(command, logger, cwd),\n getConfig(command, logger, cwd, \"graphite.branch_edit\").then(\n (value) => (value as \"commit\" | \"amend\") ?? (\"amend\" as const)\n ),\n getConfig(command, logger, cwd, \"graphite.create_prs_as\").then(\n (value) => (value as \"draft\" | \"publish\") ?? (\"draft\" as const)\n ),\n ]);\n if (repoInfoRaw == null) {\n return { type: \"cwdNotARepository\", cwd };\n }\n\n let codeReviewSystem: CodeReviewSystem;\n if (typeof repoInfoRaw.remote === \"undefined\") {\n codeReviewSystem = { type: \"none\" };\n } else {\n const { owner, name, hostname } = repoInfoRaw.remote;\n codeReviewSystem = {\n type: \"github\",\n owner,\n repo: name,\n hostname,\n };\n }\n\n const result: RepoInfo = {\n type: \"success\",\n command,\n dotdir: repoInfoRaw.dotDir,\n repoRoot: repoInfoRaw.rootDir,\n codeReviewSystem,\n preferredBranchEdit,\n createPrsAs,\n profile,\n trunkBranch: repoInfoRaw.trunkBranch,\n };\n logger.info(\"repo info: \", result);\n return result;\n }\n\n /**\n * Run long-lived command which mutates the repository state.\n * Progress is streamed back as it comes in.\n * Operations are run immediately. For queueing, see OperationQueue.\n */\n async runOrQueueOperation(\n operation: RunnableOperation,\n onProgress: (progress: OperationProgress) => void,\n tracker: ServerSideTracker,\n cwd: string\n ): Promise<void> {\n await this.operationQueue.runOrQueueOperation(\n operation,\n onProgress,\n tracker,\n cwd\n );\n }\n\n /**\n * Abort the running operation if it matches the given id.\n */\n abortRunningOpeation(operationId: string) {\n this.operationQueue.abortRunningOperation(operationId);\n }\n\n /**\n * Called by this.operationQueue in response to runOrQueueOperation when an operation is ready to actually run.\n */\n private normalizeOperationArgs(\n cwd: string,\n args: Array<CommandArg>\n ): Array<string> {\n const repoRoot = unwrap(this.info.repoRoot);\n\n return args.map((arg) => {\n if (typeof arg === \"object\") {\n switch (arg.type) {\n case \"repo-relative-file\":\n return path.normalize(\n path.relative(cwd, path.join(repoRoot, arg.path))\n );\n\n case \"succeedable-revset\":\n return `max(successors(${arg.revset}))`;\n }\n }\n return arg;\n });\n }\n\n /**\n * Called by this.operationQueue in response to runOrQueueOperation when an operation is ready to actually run.\n */\n private async runOperation(\n operation: {\n id: string;\n args: Array<CommandArg>;\n stdin?: string;\n },\n onProgress: OperationCommandProgressReporter,\n cwd: string,\n signal: AbortSignal\n ): Promise<void> {\n const cwdRelativeArgs = this.normalizeOperationArgs(cwd, operation.args);\n const { stdin } = operation;\n const { command, args, options } = getExecParams(\n this.info.command,\n cwdRelativeArgs,\n cwd,\n stdin ? { input: stdin } : undefined\n );\n\n this.logger.log(\"run operation: \", command, cwdRelativeArgs.join(\" \"));\n\n const execution = execa(command, args, {\n ...options,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n // It would be more appropriate to call this in reponse to execution.on('spawn'), but\n // this seems to be inconsistent about firing in all versions of node.\n // Just send spawn immediately. Errors during spawn like ENOENT will still be reported by `exit`.\n onProgress(\"spawn\");\n execution.stdout?.on(\"data\", (data) => {\n onProgress(\"stdout\", data.toString());\n });\n execution.stderr?.on(\"data\", (data) => {\n onProgress(\"stderr\", data.toString());\n });\n void execution.on(\"exit\", (exitCode) => {\n onProgress(\"exit\", exitCode || 0);\n });\n signal.addEventListener(\"abort\", () => {\n this.logger.log(\"kill operation: \", command, cwdRelativeArgs.join(\" \"));\n });\n handleAbortSignalOnProcess(execution, signal);\n await execution;\n }\n\n setPageFocus(page: string, state: PageVisibility) {\n this.pageFocusTracker.setState(page, state);\n }\n\n /** Return the latest fetched value for UncommittedChanges. */\n getUncommittedChanges(): FetchedUncommittedChanges | null {\n return this.uncommittedChanges;\n }\n\n subscribeToUncommittedChanges(\n callback: (result: FetchedUncommittedChanges) => unknown\n ): Disposable {\n this.uncommittedChangesEmitter.on(\"change\", callback);\n return {\n dispose: () => {\n this.uncommittedChangesEmitter.off(\"change\", callback);\n },\n };\n }\n\n fetchUncommittedChanges = debounce(\n serializeAsyncCall(async () => {\n const fetchStartTimestamp = Date.now();\n try {\n this.uncommittedChangesBeginFetchingEmitter.emit(\"start\");\n const proc = await this.runCommand([\"internal-only\", \"status\"]);\n const files = (JSON.parse(proc.stdout) as Status).files.map(\n (change) => ({\n ...change,\n path: removeLeadingPathSep(change.path),\n })\n );\n\n this.uncommittedChanges = {\n fetchStartTimestamp,\n fetchCompletedTimestamp: Date.now(),\n files: { value: files },\n };\n this.uncommittedChangesEmitter.emit(\"change\", this.uncommittedChanges);\n } catch (err) {\n this.logger.error(\"Error fetching files: \", err);\n if (isProcessError(err)) {\n if (err.stderr.includes(\"checkout is currently in progress\")) {\n this.logger.info(\n \"Ignoring `hg status` error caused by in-progress checkout\"\n );\n return;\n }\n }\n // emit an error, but don't save it to this.uncommittedChanges\n this.uncommittedChangesEmitter.emit(\"change\", {\n fetchStartTimestamp,\n fetchCompletedTimestamp: Date.now(),\n files: {\n error: err instanceof Error ? err : new Error(err as string),\n },\n });\n }\n }),\n 100\n );\n\n /** Return the latest fetched value for SmartlogCommits. */\n getSmartlogCommits(): FetchedCommits | null {\n return this.smartlogCommits;\n }\n\n subscribeToSmartlogCommitsChanges(\n callback: (result: FetchedCommits) => unknown\n ) {\n this.smartlogCommitsChangesEmitter.on(\"change\", callback);\n return {\n dispose: () => {\n this.smartlogCommitsChangesEmitter.off(\"change\", callback);\n },\n };\n }\n\n subscribeToSmartlogCommitsBeginFetching(\n callback: (isFetching: boolean) => unknown\n ) {\n const onStart = () => callback(true);\n this.smartlogCommitsBeginFetchingEmitter.on(\"start\", onStart);\n return {\n dispose: () => {\n this.smartlogCommitsBeginFetchingEmitter.off(\"start\", onStart);\n },\n };\n }\n\n subscribeToUncommittedChangesBeginFetching(\n callback: (isFetching: boolean) => unknown\n ) {\n const onStart = () => callback(true);\n this.uncommittedChangesBeginFetchingEmitter.on(\"start\", onStart);\n return {\n dispose: () => {\n this.uncommittedChangesBeginFetchingEmitter.off(\"start\", onStart);\n },\n };\n }\n\n fetchSmartlogCommits = debounce(\n serializeAsyncCall(async () => {\n const fetchStartTimestamp = Date.now();\n try {\n this.smartlogCommitsBeginFetchingEmitter.emit(\"start\");\n const proc = await this.runCommand([\"internal-only\", \"log\"]);\n const commits = parseCommitInfoOutput(this.logger, proc.stdout.trim());\n if (commits.length === 0) {\n throw new Error(ErrorShortMessages.NoCommitsFetched);\n }\n this.smartlogCommits = {\n fetchStartTimestamp,\n fetchCompletedTimestamp: Date.now(),\n commits: { value: commits },\n };\n this.smartlogCommitsChangesEmitter.emit(\"change\", this.smartlogCommits);\n } catch (err) {\n this.logger.error(\"Error fetching commits: \", err);\n this.smartlogCommitsChangesEmitter.emit(\"change\", {\n fetchStartTimestamp,\n fetchCompletedTimestamp: Date.now(),\n commits: {\n error: err instanceof Error ? err : new Error(err as string),\n },\n });\n }\n }),\n 100\n );\n\n /** Watch for changes to the head commit, e.g. from checking out a new commit */\n subscribeToHeadCommit(callback: (head: BranchInfo) => unknown) {\n let headCommit = this.smartlogCommits?.commits.value?.find(\n (commit) => commit.isHead\n );\n if (headCommit != null) {\n callback(headCommit);\n }\n const onData = (data: FetchedCommits) => {\n const newHead = data?.commits.value?.find((commit) => commit.isHead);\n if (newHead != null && newHead.branch !== headCommit?.branch) {\n callback(newHead);\n headCommit = newHead;\n }\n };\n this.smartlogCommitsChangesEmitter.on(\"change\", onData);\n return {\n dispose: () => {\n this.smartlogCommitsChangesEmitter.off(\"change\", onData);\n },\n };\n }\n\n private catLimiter = new RateLimiter(MAX_SIMULTANEOUS_CAT_CALLS, (s) =>\n this.logger.info(\"[cat]\", s)\n );\n /** Return file content at a given revset, e.g. hash or `.` */\n public cat(file: AbsolutePath, comparison: Comparison): Promise<string> {\n const relativePath = path.relative(this.info.repoRoot, file);\n\n return this.catLimiter.enqueueRun(async () => {\n // For `gt cat`, we want the output of the command verbatim.\n const options = { stripFinalNewline: false };\n return (\n await this.runCommand(\n [\n \"internal-only\",\n \"relative-cat\",\n ...this.catArgs(comparison, relativePath),\n ],\n /*cwd=*/ undefined,\n options\n )\n ).stdout;\n });\n }\n\n private catArgs(comparison: Comparison, file: string): Array<string> {\n switch (comparison.type) {\n case ComparisonType.UncommittedChanges:\n return [\"uncommitted\", file];\n\n case ComparisonType.HeadChanges:\n return [\"head\", file];\n\n case ComparisonType.StackChanges:\n return [\"stack\", file];\n\n case ComparisonType.Committed:\n return [\"stack\", file, \"--ref\", comparison.hash];\n }\n }\n\n public getAllDiffIds(): Array<PRNumber> {\n return (\n this.getSmartlogCommits()\n ?.commits.value?.map((commit) => commit.pr?.number)\n .filter(notEmpty) ?? []\n );\n }\n\n public runCommand(\n args: Array<string>,\n cwd?: string,\n options?: execa.Options\n ): execa.ExecaChildProcess<string> {\n return runCommand({\n command: this.info.command,\n args,\n logger: this.logger,\n cwd: unwrap(cwd ?? this.info.repoRoot),\n options,\n });\n }\n\n public getConfig(configName: string): Promise<string | undefined> {\n return getConfig(\n this.info.command,\n this.logger,\n this.info.repoRoot,\n configName\n );\n }\n public setConfig(\n level: ConfigLevel,\n configName: string,\n configValue: string\n ): Promise<void> {\n return setConfig({\n command: this.info.command,\n logger: this.logger,\n cwd: this.info.repoRoot,\n level,\n configName,\n configValue,\n });\n }\n}\n\nexport function runCommand({\n command: command_,\n args: args_,\n logger,\n cwd,\n options: options_,\n}: {\n command?: string;\n args: Array<string>;\n logger?: Logger;\n cwd: string;\n options?: execa.Options;\n}): execa.ExecaChildProcess {\n const { command, args, options } = getExecParams(\n command_,\n args_,\n cwd,\n options_\n );\n if (logger) {\n logger.log(\"run command: \", command, ...args, options);\n }\n\n return execa(command, args, options);\n}\n\nasync function findVersion(\n command: string | undefined,\n logger: Logger,\n cwd: string\n): Promise<string> {\n try {\n return (\n await runCommand({\n command,\n args: [\"--version\"],\n logger,\n cwd,\n })\n ).stdout;\n } catch (error) {\n logger.error(`Failed to find gt version in ${cwd}`, error);\n throw error;\n }\n}\n\nasync function findRepoInfo(\n command: string | undefined,\n logger: Logger,\n cwd: string\n): Promise<RepoInfoFromCLI | undefined> {\n try {\n return JSON.parse(\n (\n await runCommand({\n command,\n args: [\"internal-only\", \"repo-info\"],\n logger,\n cwd,\n })\n ).stdout\n );\n } catch (error) {\n logger.error(`Failed to find repository info in ${cwd}`, error);\n return undefined;\n }\n}\n\nasync function findRepoProfile(\n command: string | undefined,\n logger: Logger,\n cwd: string\n): Promise<{\n appUrl: string;\n}> {\n try {\n return JSON.parse(\n (\n await runCommand({\n command,\n args: [\"internal-only\", \"profile\"],\n logger,\n cwd,\n })\n ).stdout\n );\n } catch (error) {\n logger.error(`Failed to find repository profile in ${cwd}`, error);\n return {\n appUrl: \"https://app.graphite.dev/\",\n };\n }\n}\n\nasync function getConfig(\n command: string | undefined,\n logger: Logger,\n cwd: string,\n configName: string\n): Promise<string | undefined> {\n try {\n return (\n await runCommand({\n command,\n args: [\"internal-only\", \"config\", configName],\n logger,\n cwd,\n })\n ).stdout.trim();\n } catch {\n // `config` exits with status 1 if config is not set. This is not an error.\n return undefined;\n }\n}\n\n// Eventually add repo\ntype ConfigLevel = \"user\";\nasync function setConfig({\n command,\n logger,\n cwd,\n level,\n configName,\n configValue,\n}: {\n command?: string;\n logger: Logger;\n cwd: string;\n level: ConfigLevel;\n configName: string;\n configValue: string;\n}): Promise<void> {\n await runCommand({\n command,\n args: [\n \"internal-only\",\n \"set-config\",\n `--level`,\n level,\n configName,\n configValue,\n ],\n logger,\n cwd,\n });\n}\n\nfunction getExecParams(\n command: string | undefined,\n args_: Array<string>,\n cwd: string,\n options_?: execa.Options\n): {\n command: string;\n args: Array<string>;\n options: execa.Options;\n} {\n let args = [...args_];\n // expandHomeDir is not supported on windows\n if (process.platform !== \"win32\") {\n // commit/amend have unconventional ways of escaping slashes from messages.\n // We have to 'unescape' to make it work correctly.\n args = args.map((arg) => arg.replace(/\\\\\\\\/g, \"\\\\\"));\n }\n const options = {\n ...options_,\n env: {\n LANG: \"en_US.utf-8\", // make sure to use unicode if user hasn't set LANG themselves\n EDITOR: undefined,\n GRAPHITE_INTERACTIVE: \"true\",\n GIT_OPTIONAL_LOCKS: \"0\", // workaround for not grabbing index.lock until cli change lands\n },\n cwd,\n };\n\n // Hack: for pkg'd CLI, pointing to the executable at itself doesn't work. We need to treat it like a node script.\n if (!command && process.argv[1].startsWith(\"/snapshot/\")) {\n command = process.argv[0];\n args = [\"/snapshot/monologue/apps/public/cli/dist/graphite.js\", ...args];\n } else if (!command) {\n command = \"gt\";\n }\n\n // TODO: we could run with systemd for better OOM protection when on linux\n return { command, args, options };\n}\n\n/**\n * Extract CommitInfos from log calls that use FETCH_TEMPLATE.\n */\nexport function parseCommitInfoOutput(\n logger: Logger,\n output: string\n): SmartlogCommits {\n let commitInfos: Array<BranchInfo> = [];\n try {\n commitInfos = JSON.parse(output);\n } catch (err) {\n logger.error(\"failed to parse branch info\", err);\n }\n return commitInfos;\n}\nexport function parseSuccessorData(\n successorData: string\n): SuccessorInfo | undefined {\n const [successorString] = successorData.split(\",\", 1); // we're only interested in the first available mutation\n if (!successorString) {\n return undefined;\n }\n const successor = successorString.split(\":\");\n return {\n hash: successor[1],\n type: successor[0],\n };\n}\n\n/**\n * Returns absolute path for a repo-relative file path.\n * If the path \"escapes\" the repository's root dir, returns null\n * Used to validate that a file path does not \"escape\" the repo, and the file can safely be modified on the filesystem.\n * absolutePathForFileInRepo(\"foo/bar/file.txt\", repo) -> /path/to/repo/foo/bar/file.txt\n * absolutePathForFileInRepo(\"../file.txt\", repo) -> null\n */\nexport function absolutePathForFileInRepo(\n filePath: RepoRelativePath,\n repo: Repository,\n pathMod = path\n): AbsolutePath | null {\n // Note that resolve() is contractually obligated to return an absolute path.\n const fullPath = pathMod.resolve(repo.info.repoRoot, filePath);\n // Prefix checks on paths can be footguns on Windows for C:\\\\ vs c:\\\\, but since\n // we use the same exact path check here and in the resolve, there should be\n // no incompatibility here.\n if (fullPath.startsWith(repo.info.repoRoot + pathMod.sep)) {\n return fullPath;\n } else {\n return null;\n }\n}\n\nexport function repoRelativePathForAbsolutePath(\n absolutePath: AbsolutePath,\n repo: Repository,\n pathMod = path\n): RepoRelativePath {\n return pathMod.relative(repo.info.repoRoot, absolutePath);\n}\n\nfunction isProcessError(s: unknown): s is { stderr: string } {\n return s != null && typeof s === \"object\" && \"stderr\" in s;\n}\n\nfunction computeNewConflicts(\n previousConflicts: MergeConflicts,\n branchName: string | undefined,\n commandOutput: Status,\n fetchStartTimestamp: number\n): MergeConflicts | undefined {\n const newConflictData = commandOutput;\n if (!newConflictData?.conflicts || !branchName) {\n return undefined;\n }\n\n const newConflicts = newConflictData.files.filter(\n (file) => file.status === \"UNRESOLVED\"\n );\n const conflicts: MergeConflicts = {\n state: \"loaded\",\n branchName,\n files: [],\n fetchStartTimestamp,\n fetchCompletedTimestamp: Date.now(),\n };\n if (previousConflicts?.files != null && previousConflicts.files.length > 0) {\n // we saw conflicts before, some of which might now be resolved. Preserve previous ordering.\n const newConflictSet = new Set(\n newConflicts.map((conflict) => conflict.path)\n );\n conflicts.files = previousConflicts.files.map((conflict) =>\n newConflictSet.has(conflict.path)\n ? { path: conflict.path, status: \"UNRESOLVED\" }\n : // 'R' is overloaded to mean \"removed\" for `gt status` but 'Resolved' for `gt resolve --list`\n // let's re-write this to make the UI layer simpler.\n { path: conflict.path, status: \"RESOLVED\" }\n );\n } else {\n conflicts.files = newConflicts.map((conflict) => ({\n path: conflict.path,\n status: \"UNRESOLVED\",\n }));\n }\n\n return conflicts;\n}\n","import type { Logger, RepoInfo } from \"@withgraphite/gti-shared\";\nimport chokidar from \"chokidar\";\nimport path from \"path\";\n\nexport type KindOfChange =\n | \"uncommitted changes\"\n | \"branches\"\n | \"merge conflicts\"\n | \"everything\";\n\n/**\n * Handles watching for changes to files on disk which should trigger refetching data,\n * and polling for changes when watching is not reliable.\n * @returns a disposer\n */\nexport function watchForChanges(\n repoInfo: RepoInfo,\n logger: Logger,\n changeCallback: (kind: KindOfChange) => unknown\n) {\n if (repoInfo.type !== \"success\") {\n return;\n }\n\n const { repoRoot, dotdir } = repoInfo;\n\n if (repoRoot == null || dotdir == null) {\n logger.error(\n `skipping chokidar subscription since ${repoRoot} is not a repository`\n );\n return;\n }\n\n const dotDirWatcher = chokidar.watch(dotdir, { cwd: dotdir });\n dotDirWatcher.on(\"ready\", () => {\n // if the repo changes, also recheck files. E.g. if you commit, your uncommitted changes will also change.\n changeCallback(\"everything\");\n });\n dotDirWatcher.on(\"all\", (_event, path) => {\n if (path.startsWith(\"rebase-merge\")) {\n changeCallback(\"merge conflicts\");\n }\n if (path.startsWith(\"index\") || path.startsWith(\"HEAD\")) {\n changeCallback(\"uncommitted changes\");\n }\n if (\n path.startsWith(\"refs/heads\") ||\n path.startsWith(\"refs/branch-metadata\") ||\n path.startsWith(\"HEAD\")\n ) {\n changeCallback(\"branches\");\n }\n });\n\n const relativeDotDir = path.relative(repoRoot, dotdir);\n\n const worktreeWatcher = chokidar.watch(repoRoot, {\n cwd: repoRoot,\n ignored: `${relativeDotDir}/**`,\n });\n worktreeWatcher.on(\"all\", () => {\n changeCallback(\"uncommitted changes\");\n });\n return () => {\n worktreeWatcher\n .close()\n .catch(() =>\n logger.error(\n `failed to close chokidar worktree watcher for ${repoRoot}`\n )\n );\n dotDirWatcher\n .close()\n .catch(() =>\n logger.error(`failed to close chokidar dotdir watcher for ${dotdir}`)\n );\n };\n}\n","import fs from \"fs\";\nimport path from \"path\";\n\n/**\n * Check if file path exists.\n * May still throw non-ENOENT fs access errors.\n * Note: this works on Node 10.x\n */\nexport function exists(file: string): Promise<boolean> {\n return fs.promises\n .stat(file)\n .then(() => true)\n .catch((error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") {\n return false;\n } else {\n throw error;\n }\n });\n}\n\n/**\n * Add a trailing path sep (/ or \\) if one does not exist\n */\nexport function ensureTrailingPathSep(p: string): string {\n if (p.endsWith(path.sep)) {\n return p;\n }\n return p + path.sep;\n}\n\n/**\n * Add a trailing path sep (/ or \\) if one does not exist\n */\nexport function removeLeadingPathSep(p: string): string {\n if (p.startsWith(path.sep)) {\n return p.slice(1);\n }\n return p;\n}\n","import type {\n AbsolutePath,\n PlatformSpecificClientToServerMessages,\n ServerToClientMessage,\n} from \"@withgraphite/gti-shared\";\nimport { unwrap } from \"@withgraphite/gti-shared\";\nimport { spawn } from \"child_process\";\nimport pathModule from \"path\";\n\nimport type { Repository } from \"./Repository\";\n\n/**\n * Platform-specific server-side API for each target: vscode extension host, electron standalone, browser, ...\n * See also platform.ts\n */\nexport interface ServerPlatform {\n platformName: string;\n handleMessageFromClient(\n repo: Repository | undefined,\n message: PlatformSpecificClientToServerMessages,\n postMessage: (message: ServerToClientMessage) => void,\n onDispose: (disapose: () => unknown) => void\n ): void | Promise<void>;\n}\n\nexport const browserServerPlatform: ServerPlatform = {\n platformName: \"browser\",\n handleMessageFromClient: (\n repo: Repository | undefined,\n message: PlatformSpecificClientToServerMessages\n ) => {\n switch (message.type) {\n case \"platform/openFile\": {\n const path: AbsolutePath = pathModule.join(\n unwrap(repo?.info.repoRoot),\n message.path\n );\n let command;\n if (command == null) {\n // use OS-builtin open command to open files\n // (which may open different file extensions with different programs)\n // TODO: add a config option to determine which program to launch\n switch (process.platform) {\n case \"darwin\":\n command = \"/usr/bin/open\";\n break;\n\n case \"win32\":\n command = \"notepad.exe\";\n break;\n\n case \"linux\":\n command = \"xdg-open\";\n break;\n\n default:\n }\n }\n if (command) {\n // Because the GTI server is likely running in the background and is\n // no longer attached to a terminal, this is designed for the case\n // where the user opens the file in a windowed editor (hence\n // `windowsHide: false`, which is the default for\n // `child_process.spawn()`, but not for `execa()`):\n //\n // - For users using a simple one-window-per-file graphical text\n // editor, like notepad.exe, this is relatively straightforward.\n // - For users who prefer a terminal-based editor, like Emacs,\n // a conduit like EmacsClient would be required.\n //\n // Further, killing GTI should not kill the editor, so this follows\n // the pattern for spawning an independent, long-running process in\n // Node.js as described here:\n //\n // https://nodejs.org/docs/latest-v10.x/api/child_process.html#child_process_options_detached\n repo?.logger.log(\"open file\", path);\n // TODO: Report error if spawn() fails?\n const proc = spawn(command, [path], {\n detached: true,\n stdio: \"ignore\",\n windowsHide: false,\n windowsVerbatimArguments: true,\n });\n // Silent error. Don't crash the server process.\n proc.on(\"error\", (err) => {\n repo?.logger.log(\"failed to open\", path, err);\n });\n proc.unref();\n }\n break;\n }\n\n default:\n }\n },\n};\n","import type {\n AbsolutePath,\n Logger,\n RepositoryError,\n ValidatedRepoInfo,\n} from \"@withgraphite/gti-shared\";\n\nimport { ensureTrailingPathSep } from \"./fs\";\nimport { Repository } from \"./Repository\";\nimport { TypedEventEmitter } from \"./TypedEventEmitter\";\n\n/**\n * Reference-counting access to a {@link Repository}, via a Promise.\n * Be sure to `unref()` when no longer needed.\n */\nexport interface RepositoryReference {\n promise: Promise<Repository | RepositoryError>;\n unref: () => unknown;\n}\n\n/**\n * We return `RepositoryReference`s synchronously before we have the Repository,\n * but reference counts should be associated with the actual async constructed Repository,\n * which is why we can't return RefCounted<Repository> directly.\n */\nclass RepositoryReferenceImpl implements RepositoryReference {\n constructor(\n public promise: Promise<Repository | RepositoryError>,\n private disposeFunc: () => void\n ) {}\n public unref() {\n if (!this.disposed) {\n this.disposed = true;\n this.disposeFunc();\n }\n }\n\n internalReference: RefCounted<Repository> | undefined;\n disposed = false;\n}\n\nclass RefCounted<T extends { dispose: () => void }> {\n constructor(public value: T) {}\n private references = 0;\n\n public isDisposed = false;\n public ref() {\n this.references++;\n }\n public getNumberOfReferences() {\n return this.references;\n }\n public dispose() {\n this.references--;\n if (!this.isDisposed && this.references === 0) {\n this.isDisposed = true;\n this.value.dispose();\n }\n }\n}\n\n/**\n * Allow re-using Repository instances by storing instances by path,\n * and controlling how Repositories are created.\n *\n * Some async work is needed to construct repositories (finding repo root dir),\n * so it's possible to duplicate some work if multiple repos are constructed at similar times.\n * We still enable Repository re-use in this case by double checking for pre-existing Repos at the last second.\n */\nclass RepositoryCache {\n // allow mocking Repository in tests\n constructor(private RepositoryType = Repository) {}\n\n /**\n * Previously distributed RepositoryReferences, keyed by repository root path\n * Note that Repositories do not define their own `cwd`, and can be re-used across cwds.\n */\n private reposByRoot = new Map<AbsolutePath, RefCounted<Repository>>();\n private activeReposEmitter = new TypedEventEmitter<\"change\", undefined>();\n\n private lookup(dirGuess: AbsolutePath): RefCounted<Repository> | undefined {\n for (const repo of this.reposByRoot.values()) {\n if (\n dirGuess === repo.value.info.repoRoot ||\n dirGuess.startsWith(ensureTrailingPathSep(repo.value.info.repoRoot))\n ) {\n if (!repo.isDisposed) {\n return repo;\n }\n }\n }\n return undefined;\n }\n\n /**\n * Create a new Repository, or re-use if one already exists.\n * Repositories are reference-counted to ensure they can be disposed when no longer needed.\n */\n getOrCreate(\n cmd: string | undefined,\n logger: Logger,\n cwd: string\n ): RepositoryReference {\n // Fast path: if this cwd is already a known repo root, we can use it directly.\n // This only works if the cwd happens to be the repo root.\n const found = this.lookup(cwd);\n if (found) {\n found.ref();\n return new RepositoryReferenceImpl(Promise.resolve(found.value), () =>\n found.dispose()\n );\n }\n\n // More typically, we can re-use a Repository among different cwds:\n\n // eslint-disable-next-line prefer-const\n let ref: RepositoryReferenceImpl;\n const lookupRepoInfoAndReuseIfPossible = async (): Promise<\n Repository | RepositoryError\n > => {\n // TODO: we should rate limit how many getRepoInfos we run at a time, and make other callers just wait.\n // this would guard against querying lots of redundant paths within the same repo.\n // This is probably not necessary right now, but would be useful for a VS Code extension where we need to query\n // individual file paths to add diff gutters.\n const repoInfo = await this.RepositoryType.getRepoInfo(cmd, logger, cwd);\n // important: there should be no `await` points after here, to ensure there is no race when re-using Repositories.\n if (repoInfo.type !== \"success\") {\n // No repository found at this root, or some other error prevents the repo from being created\n return repoInfo;\n }\n\n if (ref.disposed) {\n // If the reference is disposed, the caller gave up while waiting for the repo to be created.\n // make sure we don't create a dangling Repository.\n return {\n type: \"unknownError\",\n error: new Error(\"Repository already disposed\"),\n };\n }\n\n // Now that we've spent some async time to determine this repo's actual root,\n // we can check if we already have a reference to it saved.\n // This way, we can still re-use a Repository, and only risk duplicating `getRepoInfo` work.\n const newlyFound = this.lookup(repoInfo.repoRoot);\n if (newlyFound) {\n // if it is found now, it means either the cwd differs from the repo root (lookup fails), or\n // another instance was created at the same time and finished faster than this one (lookup failed before, but succeeds now).\n\n newlyFound.ref();\n ref.internalReference = newlyFound;\n return newlyFound.value;\n }\n\n // This is where we actually start new subscriptions and trigger work, so we should only do this\n // once we're sure we don't have a repository to re-use.\n const repo = new this.RepositoryType(\n repoInfo as ValidatedRepoInfo, // repoInfo is now guaranteed to have these root/dotdir set\n logger\n );\n\n const internalRef = new RefCounted(repo);\n internalRef.ref();\n ref.internalReference = internalRef;\n this.reposByRoot.set(repoInfo.repoRoot, internalRef);\n this.activeReposEmitter.emit(\"change\");\n return repo;\n };\n ref = new RepositoryReferenceImpl(\n lookupRepoInfoAndReuseIfPossible(),\n () => {\n if (ref.internalReference) {\n ref.internalReference.dispose();\n }\n ref.unref();\n }\n );\n return ref;\n }\n\n /**\n * Lookup a cached repository without creating a new one if it doens't exist\n */\n public cachedRepositoryForPath(path: AbsolutePath): Repository | undefined {\n const ref = this.lookup(path);\n return ref?.value;\n }\n\n public onChangeActiveRepos(\n cb: (repos: Array<Repository>) => unknown\n ): () => unknown {\n const onChange = () => {\n cb([...this.reposByRoot.values()].map((ref) => ref.value));\n };\n this.activeReposEmitter.on(\"change\", onChange);\n // start with initial repos set\n onChange();\n return () => this.activeReposEmitter.off(\"change\", onChange);\n }\n\n /** Clean up all known repos. Mostly useful for testing. */\n clearCache() {\n this.reposByRoot.forEach((value) => value.dispose());\n this.reposByRoot = new Map();\n this.activeReposEmitter.removeAllListeners();\n }\n\n public numberOfActiveServers(): number {\n let numActive = 0;\n for (const repo of this.reposByRoot.values()) {\n numActive += repo.getNumberOfReferences();\n }\n return numActive;\n }\n}\n\nexport const __TEST__ = { RepositoryCache };\n\nexport const repositoryCache = new RepositoryCache();\n","import type { ChangedFiles } from \"@withgraphite/gti-cli-shared-types\";\nimport type {\n ClientToServerMessage,\n ClientToServerMessageWithPayload,\n Disposable,\n FetchedCommits,\n FetchedUncommittedChanges,\n Logger,\n MergeConflicts,\n PlatformSpecificClientToServerMessages,\n RepositoryError,\n Result,\n ServerToClientMessage,\n} from \"@withgraphite/gti-shared\";\nimport {\n deserializeFromString,\n randomId,\n revsetArgsForComparison,\n serializeToString,\n unwrap,\n} from \"@withgraphite/gti-shared\";\nimport fs from \"fs\";\n\nimport type { ClientConnection } from \".\";\nimport type { ServerSideTracker } from \"./analytics/serverSideTracker\";\nimport { absolutePathForFileInRepo, Repository } from \"./Repository\";\nimport type { RepositoryReference } from \"./RepositoryCache\";\nimport { repositoryCache } from \"./RepositoryCache\";\nimport type { ServerPlatform } from \"./serverPlatform\";\nimport { findPublicAncestor } from \"./utils\";\n\ntype IncomingMessageWithPayload = ClientToServerMessageWithPayload;\nexport type IncomingMessage = ClientToServerMessage;\nexport type OutgoingMessage = ServerToClientMessage;\n\ntype GeneralMessage = IncomingMessage &\n (\n | { type: \"changeCwd\" }\n | { type: \"requestRepoInfo\" }\n | { type: \"requestApplicationInfo\" }\n | { type: \"fileBugReport\" }\n | { type: \"track\" }\n );\ntype WithRepoMessage = Exclude<IncomingMessage, GeneralMessage>;\n\n/**\n * Return true if a ClientToServerMessage is a ClientToServerMessageWithPayload\n */\nfunction expectsBinaryPayload(\n message: unknown\n): message is ClientToServerMessageWithPayload {\n return (\n message != null &&\n typeof message === \"object\" &&\n (message as ClientToServerMessageWithPayload).hasBinaryPayload === true\n );\n}\n\n/**\n * Message passing channel built on top of ClientConnection.\n * Use to send and listen for well-typed events with the client\n *\n * Note: you must set the current repository to start sending data back to the client.\n */\nexport class ServerToClientAPI {\n private listenersByType = new Map<\n string,\n Set<(message: IncomingMessage) => void | Promise<void>>\n >();\n private incomingListener: Disposable;\n\n /** Disposables that must be disposed whenever the current repo is changed */\n private repoDisposables: Array<Disposable> = [];\n private subscriptions = new Map<string, Disposable>();\n private activeRepoRef: RepositoryReference | undefined;\n\n private queuedMessages: Array<IncomingMessage> = [];\n private currentState:\n | { type: \"loading\" }\n | { type: \"repo\"; repo: Repository; cwd: string }\n | { type: \"error\"; error: RepositoryError } = { type: \"loading\" };\n\n private pageId = randomId();\n\n constructor(\n private platform: ServerPlatform,\n private connection: ClientConnection,\n private tracker: ServerSideTracker,\n private logger: Logger\n ) {\n // messages with binary payloads are sent as two post calls. We first get the JSON message, then the binary payload,\n // which we will reconstruct together.\n let messageExpectingBinaryFollowup: ClientToServerMessageWithPayload | null =\n null;\n this.incomingListener = this.connection.onDidReceiveMessage(\n (buf, isBinary) => {\n if (isBinary) {\n if (messageExpectingBinaryFollowup == null) {\n connection.logger?.error(\n \"Error: got a binary message when not expecting one\"\n );\n return;\n }\n // TODO: we don't handle queueing up messages with payloads...\n this.handleIncomingMessageWithPayload(\n messageExpectingBinaryFollowup,\n buf\n );\n messageExpectingBinaryFollowup = null;\n return;\n } else if (messageExpectingBinaryFollowup != null) {\n connection.logger?.error(\n \"Error: didnt get binary payload after a message that requires one\"\n );\n messageExpectingBinaryFollowup = null;\n return;\n }\n const message = buf.toString(\"utf-8\");\n const data = deserializeFromString(message) as IncomingMessage;\n if (expectsBinaryPayload(data)) {\n // remember this message, and wait to get the binary payload before handling it\n messageExpectingBinaryFollowup = data;\n return;\n }\n\n // When the client is connected, we want to immediately start listening to messages.\n // However, we can't properly respond to these messages until we have a repository set up.\n // Queue up messages until a repository is set.\n if (this.currentState.type === \"loading\") {\n this.queuedMessages.push(data);\n } else {\n try {\n this.handleIncomingMessage(data);\n } catch (err) {\n connection.logger?.error(\n \"error handling incoming message: \",\n data,\n err\n );\n }\n }\n }\n );\n }\n\n private setRepoError(error: RepositoryError) {\n this.disposeRepoDisposables();\n\n this.currentState = { type: \"error\", error };\n\n this.tracker.context.setRepo(undefined);\n\n this.processQueuedMessages();\n }\n\n private setCurrentRepo(repo: Repository, cwd: string) {\n this.disposeRepoDisposables();\n\n this.currentState = { type: \"repo\", repo, cwd };\n\n this.tracker.context.setRepo(repo);\n\n if (repo.codeReviewProvider != null) {\n this.repoDisposables.push(\n repo.codeReviewProvider.onChangeDiffSummaries((value) => {\n this.postMessage({ type: \"fetchedDiffSummaries\", summaries: value });\n })\n );\n }\n\n this.repoDisposables.push(\n repo.subscribeToHeadCommit((head) => {\n const allCommits = repo.getSmartlogCommits();\n const ancestor = findPublicAncestor(allCommits?.commits.value, head);\n this.tracker.track(\"HeadCommitChanged\", {\n extras: {\n hash: head.branch,\n public: ancestor?.branch,\n },\n });\n })\n );\n\n this.processQueuedMessages();\n }\n\n postMessage(message: OutgoingMessage) {\n void this.connection.postMessage(serializeToString(message)).catch(() => {\n // eslint-disable-next-line no-console\n console.warn(\"Failed to post message to client\");\n });\n }\n\n /** Get a repository reference for a given cwd, and set that as the active repo. */\n setActiveRepoForCwd(newCwd: string) {\n if (this.activeRepoRef !== undefined) {\n this.activeRepoRef.unref();\n }\n this.logger.info(`Setting active repo cwd to ${newCwd}`);\n // Set as loading right away while we determine the new cwd's repo\n // This ensures new messages coming in will be queued and handled only with the new repository\n this.currentState = { type: \"loading\" };\n const command = this.connection.command;\n this.activeRepoRef = repositoryCache.getOrCreate(\n command,\n this.logger,\n newCwd\n );\n void this.activeRepoRef.promise.then((repoOrError) => {\n if (repoOrError instanceof Repository) {\n this.setCurrentRepo(repoOrError, newCwd);\n } else {\n this.setRepoError(repoOrError);\n }\n });\n }\n\n dispose() {\n this.incomingListener.dispose();\n this.disposeRepoDisposables();\n\n if (this.activeRepoRef !== undefined) {\n this.activeRepoRef.unref();\n }\n }\n\n private disposeRepoDisposables() {\n this.repoDisposables.forEach((disposable) => disposable.dispose());\n this.repoDisposables = [];\n\n this.subscriptions.forEach((sub) => sub.dispose());\n this.subscriptions.clear();\n }\n\n private processQueuedMessages() {\n for (const message of this.queuedMessages) {\n try {\n this.handleIncomingMessage(message);\n } catch (err) {\n this.connection.logger?.error(\n \"error handling queued message: \",\n message,\n err\n );\n }\n }\n this.queuedMessages = [];\n }\n\n private handleIncomingMessageWithPayload(\n message: IncomingMessageWithPayload,\n payload: ArrayBuffer\n ) {\n switch (message.type) {\n case \"uploadFile\": {\n const { id, filename } = message;\n const uploadFile: null | ((value: any, opts: any) => Promise<string>) =\n null as null | ((value: any) => Promise<string>);\n if (uploadFile == null) {\n return;\n }\n this.tracker\n .operation(\"UploadImage\", \"UploadImageError\", {}, () =>\n uploadFile(unwrap(this.connection.logger), {\n filename,\n data: payload,\n })\n )\n .then((result: string) => {\n this.connection.logger?.info(\n \"sucessfully uploaded file\",\n filename,\n result\n );\n this.postMessage({\n type: \"uploadFileResult\",\n id,\n result: { value: result },\n });\n })\n .catch((error: Error) => {\n this.connection.logger?.info(\n \"error uploading file\",\n filename,\n error\n );\n this.postMessage({\n type: \"uploadFileResult\",\n id,\n result: { error },\n });\n });\n break;\n }\n }\n }\n\n private handleIncomingMessage(data: IncomingMessage) {\n this.handleIncomingGeneralMessage(data as GeneralMessage);\n const { currentState } = this;\n switch (currentState.type) {\n case \"repo\": {\n const { repo, cwd } = currentState;\n this.handleIncomingMessageWithRepo(data as WithRepoMessage, repo, cwd);\n break;\n }\n\n // If the repo is in the loading or error state, the client may still send\n // platform messages such as `platform/openExternal` that should be processed.\n case \"loading\":\n case \"error\":\n if (data.type.startsWith(\"platform/\")) {\n void this.platform.handleMessageFromClient(\n /*repo=*/ undefined,\n data as PlatformSpecificClientToServerMessages,\n (message) => this.postMessage(message),\n (dispose: () => unknown) => {\n this.repoDisposables.push({ dispose });\n }\n );\n this.notifyListeners(data);\n }\n break;\n }\n }\n\n /**\n * Handle messages which can be handled regardless of if a repo was successfully created or not\n */\n private handleIncomingGeneralMessage(data: GeneralMessage) {\n switch (data.type) {\n case \"track\": {\n this.tracker.trackData(data.data);\n break;\n }\n\n case \"changeCwd\": {\n this.setActiveRepoForCwd(data.cwd);\n break;\n }\n\n case \"requestRepoInfo\": {\n switch (this.currentState.type) {\n case \"repo\":\n this.postMessage({\n type: \"repoInfo\",\n info: this.currentState.repo.info,\n cwd: this.currentState.cwd,\n });\n break;\n\n case \"error\":\n this.postMessage({\n type: \"repoInfo\",\n info: this.currentState.error,\n });\n break;\n\n case \"loading\":\n }\n break;\n }\n\n case \"requestApplicationInfo\": {\n this.postMessage({\n type: \"applicationInfo\",\n platformName: this.platform.platformName,\n version: this.connection.version,\n });\n break;\n }\n\n case \"fileBugReport\": {\n // Internal.fileABug?.(\n // data.data,\n // data.uiState,\n // this.tracker,\n // this.logger,\n // (progress: FileABugProgress) => {\n // this.connection.logger?.info('file a bug progress: ', JSON.stringify(progress));\n // this.postMessage({type: 'fileBugReportProgress', ...progress});\n // },\n // );\n break;\n }\n }\n }\n\n /**\n * Handle messages which require a repository to have been successfully set up to run\n */\n private handleIncomingMessageWithRepo(\n data: WithRepoMessage,\n repo: Repository,\n cwd: string\n ) {\n const { logger } = repo;\n switch (data.type) {\n case \"subscribe\": {\n const { subscriptionID, kind } = data;\n switch (kind) {\n case \"uncommittedChanges\": {\n const postUncommittedChanges = (\n result: FetchedUncommittedChanges\n ) => {\n this.postMessage({\n type: \"subscriptionResult\",\n kind: \"uncommittedChanges\",\n subscriptionID,\n data: result,\n });\n };\n\n const uncommittedChanges = repo.getUncommittedChanges();\n if (uncommittedChanges != null) {\n postUncommittedChanges(uncommittedChanges);\n }\n const disposables: Array<Disposable> = [];\n\n // send changes as they come in from watchman\n disposables.push(\n repo.subscribeToUncommittedChanges(postUncommittedChanges)\n );\n // trigger a fetch on startup\n void repo.fetchUncommittedChanges();\n\n disposables.push(\n repo.subscribeToUncommittedChangesBeginFetching(() =>\n this.postMessage({\n type: \"beganFetchingUncommittedChangesEvent\",\n })\n )\n );\n this.subscriptions.set(subscriptionID, {\n dispose: () => {\n disposables.forEach((d) => d.dispose());\n },\n });\n break;\n }\n\n case \"smartlogCommits\": {\n const postSmartlogCommits = (result: FetchedCommits) => {\n this.postMessage({\n type: \"subscriptionResult\",\n kind: \"smartlogCommits\",\n subscriptionID,\n data: result,\n });\n };\n\n const smartlogCommits = repo.getSmartlogCommits();\n if (smartlogCommits != null) {\n postSmartlogCommits(smartlogCommits);\n }\n const disposables: Array<Disposable> = [];\n // send changes as they come from file watcher\n disposables.push(\n repo.subscribeToSmartlogCommitsChanges(postSmartlogCommits)\n );\n // trigger a fetch on startup\n void repo.fetchSmartlogCommits();\n\n disposables.push(\n repo.subscribeToSmartlogCommitsBeginFetching(() =>\n this.postMessage({ type: \"beganFetchingSmartlogCommitsEvent\" })\n )\n );\n\n this.subscriptions.set(subscriptionID, {\n dispose: () => {\n disposables.forEach((d) => d.dispose());\n },\n });\n break;\n }\n\n case \"mergeConflicts\": {\n const postMergeConflicts = (\n conflicts: MergeConflicts | undefined\n ) => {\n this.postMessage({\n type: \"subscriptionResult\",\n kind: \"mergeConflicts\",\n subscriptionID,\n data: conflicts,\n });\n };\n\n const mergeConflicts = repo.getMergeConflicts();\n if (mergeConflicts != null) {\n postMergeConflicts(mergeConflicts);\n }\n this.subscriptions.set(\n subscriptionID,\n repo.onChangeConflictState(postMergeConflicts)\n );\n break;\n }\n }\n break;\n }\n\n case \"unsubscribe\": {\n const subscription = this.subscriptions.get(data.subscriptionID);\n subscription?.dispose();\n this.subscriptions.delete(data.subscriptionID);\n break;\n }\n\n case \"runOperation\": {\n const { operation } = data;\n void repo.runOrQueueOperation(\n operation,\n (progress) => {\n this.postMessage({ type: \"operationProgress\", ...progress });\n if (progress.kind === \"queue\") {\n this.tracker.track(\"QueueOperation\", {\n extras: { operation: operation.trackEventName },\n });\n }\n },\n this.tracker,\n cwd\n );\n break;\n }\n\n case \"abortRunningOperation\": {\n const { operationId } = data;\n repo.abortRunningOpeation(operationId);\n break;\n }\n\n case \"getConfig\": {\n void repo\n .getConfig(data.name)\n .catch(() => undefined)\n .then((value) => {\n logger.info(\"got config\", data.name, value);\n this.postMessage({ type: \"gotConfig\", name: data.name, value });\n });\n break;\n }\n\n case \"fetchRepoMessage\": {\n const repoMessage: Promise<Result<string>> = repo\n .runCommand([\"internal-only\", \"repo-message\"])\n .then((o) => ({ value: o.stdout }))\n .catch((error) => {\n logger?.error(\"error fetching repo message\", error.toString());\n return { error };\n });\n void repoMessage.then((data) =>\n this.postMessage({\n type: \"fetchedRepoMessage\",\n message: data.value || \"\",\n })\n );\n break;\n }\n\n case \"fetchUpgradePrompt\": {\n const upgradePrompt: Promise<Result<string>> = repo\n .runCommand([\"internal-only\", \"upgrade-prompt\"])\n .then((o) => ({ value: o.stdout }))\n .catch((error) => {\n logger?.error(\"error fetching upgrade prompt\", error.toString());\n return { error };\n });\n void upgradePrompt.then((data) =>\n this.postMessage({\n type: \"fetchedUpgradePrompt\",\n message: data.value || \"\",\n })\n );\n break;\n }\n\n case \"setConfig\": {\n logger.info(\"set config\", data.name, data.value);\n repo.setConfig(\"user\", data.name, data.value).catch((err) => {\n logger.error(\"error setting config\", data.name, data.value, err);\n });\n break;\n }\n\n case \"deleteFile\": {\n const { filePath } = data;\n const absolutePath = absolutePathForFileInRepo(filePath, repo);\n // security: don't trust client messages to allow us to delete files outside the repository\n if (absolutePath == null) {\n logger.warn(\"can't delete file outside of the repo\", filePath);\n return;\n }\n\n fs.promises\n .rm(absolutePath)\n .then(() => {\n logger.info(\"deleted file from filesystem\", absolutePath);\n })\n .catch((err) => {\n logger.error(\"unable to delete file\", absolutePath, err);\n });\n break;\n }\n\n case \"requestComparison\": {\n const { comparison } = data;\n const diff: Promise<Result<string>> = repo\n .runCommand([\n \"internal-only\",\n \"diff\",\n ...revsetArgsForComparison(comparison),\n ])\n .then((o) => ({ value: o.stdout }))\n .catch((error) => {\n logger?.error(\"error running diff\", error.toString());\n return { error };\n });\n void diff.then((data) =>\n this.postMessage({\n type: \"comparison\",\n comparison,\n data: { diff: data },\n })\n );\n break;\n }\n\n case \"requestChangedFiles\": {\n const { branch } = data;\n const resultPromise: Promise<ChangedFiles> = repo\n .runCommand([\"internal-only\", \"changed-files\", branch])\n .then((o) => JSON.parse(o.stdout))\n .catch((error) => {\n logger?.error(\"error running diff\", error.toString());\n return { error };\n });\n void resultPromise.then((result) =>\n this.postMessage({\n type: \"changedFiles\",\n branch,\n data: result,\n })\n );\n break;\n }\n\n case \"requestComparisonContextLines\": {\n const {\n id: { path: relativePath, comparison },\n start,\n numLines,\n } = data;\n\n // TODO: For context lines, before/after sides of the comparison\n // are identical... except for line numbers.\n // Typical comparisons with '.' would be much faster (nearly instant)\n // by reading from the filesystem rather than using cat,\n // we just need the caller to ask with \"after\" line numbers instead of \"before\".\n // Note: we would still need to fall back to cat for comparisons that do not involve\n // the working copy.\n const cat: Promise<string> = repo\n .cat(relativePath, comparison)\n .catch(() => \"\");\n\n void cat.then((content) =>\n this.postMessage({\n type: \"comparisonContextLines\",\n lines: content.split(\"\\n\").slice(start - 1, start - 1 + numLines),\n path: relativePath,\n })\n );\n break;\n }\n\n case \"refresh\": {\n logger?.log(\"refresh requested\");\n void repo.fetchSmartlogCommits();\n void repo.fetchUncommittedChanges();\n void repo.codeReviewProvider?.triggerDiffSummariesFetch(\n repo.getAllDiffIds()\n );\n break;\n }\n\n case \"pageVisibility\": {\n repo.setPageFocus(this.pageId, data.state);\n break;\n }\n\n case \"fetchCommitMessageTemplate\": {\n repo\n .runCommand([\"internal-only\", \"templates\"])\n .then((result) => {\n const templates: Record<string, string> = JSON.parse(result.stdout);\n this.postMessage({\n type: \"fetchedCommitMessageTemplate\",\n templates: Object.fromEntries(\n Object.entries(templates).map(([path, contents]) => [\n path,\n contents.replace(repo.IGNORE_COMMIT_MESSAGE_LINES_REGEX, \"\"),\n ])\n ),\n });\n })\n .catch((err) => {\n logger?.error(\"Could not fetch commit message template\", err);\n });\n break;\n }\n\n case \"typeahead\": {\n // Current repo's code review provider should be able to handle all\n // TypeaheadKinds for the fields in its defined schema.\n void repo.codeReviewProvider\n ?.typeahead?.(data.kind, data.query)\n ?.then((result) =>\n this.postMessage({\n type: \"typeaheadResult\",\n id: data.id,\n result,\n })\n );\n break;\n }\n\n case \"fetchDiffSummaries\": {\n void repo.codeReviewProvider?.triggerDiffSummariesFetch(\n repo.getAllDiffIds()\n );\n break;\n }\n\n case \"loadMoreCommits\": {\n const rangeInDays = repo.nextVisibleCommitRangeInDays();\n this.postMessage({ type: \"commitsShownRange\", rangeInDays });\n this.postMessage({ type: \"beganLoadingMoreCommits\" });\n void repo.fetchSmartlogCommits();\n this.tracker.track(\"LoadMoreCommits\", {\n extras: { daysToFetch: rangeInDays ?? \"Infinity\" },\n });\n return;\n }\n\n default: {\n void this.platform.handleMessageFromClient(\n repo,\n data,\n (message) => this.postMessage(message),\n (dispose: () => unknown) => {\n this.repoDisposables.push({ dispose });\n }\n );\n break;\n }\n }\n\n this.notifyListeners(data);\n }\n\n private notifyListeners(data: IncomingMessage): void {\n const listeners = this.listenersByType.get(data.type);\n if (listeners) {\n listeners.forEach((handle) => handle(data));\n }\n }\n}\n","import { unwrap } from \"@withgraphite/gti-shared\";\nimport fs from \"fs\";\nimport os from \"os\";\nimport path from \"path\";\n\nimport rmtree from \"./rmtree\";\n\nexport type ExistingServerInfo = {\n sensitiveToken: string;\n challengeToken: string;\n logFileLocation: string;\n /** Which command name was used to launch this server instance,\n * so it can be propagated to run further gt commands by the server.\n * Usually, \"gt\". */\n command?: string;\n /**\n * `gt version` string. If the version of gt changes, we shouldn't re-use that server instance,\n * due to potential incompatibilities between the old running server javascript and the new client javascript.\n */\n gtVersion: string;\n};\n\nconst cacheDir =\n process.platform == \"win32\"\n ? path.join(unwrap(process.env.LOCALAPPDATA), \"cache\")\n : process.platform == \"darwin\"\n ? path.join(os.homedir(), \"Library/Caches\")\n : process.env.XDG_CACHE_HOME || path.join(os.homedir(), \".cache\");\n\n/**\n * Per-user cache dir with restrictive permissions.\n * Inside this folder will be a number of files, one per port for an active GTI server.\n */\nconst savedActiveServerUrlsDirectory = path.join(cacheDir, \"graphite-gti\");\n\nfunction fileNameForPort(port: number): string {\n return `reusable_server_${port}`;\n}\n\nfunction isMode700(stat: fs.Stats): boolean {\n // eslint-disable-next-line no-bitwise\n return (stat.mode & 0o777) === 0o700;\n}\n\n/**\n * Make a temp directory with restrictive permissions where we can write existing server information.\n * Ensures directory has proper restrictive mode if the directory already exists.\n */\nexport async function ensureExistingServerFolder(): Promise<void> {\n await fs.promises.mkdir(savedActiveServerUrlsDirectory, {\n // directory needs rwx\n mode: 0o700,\n recursive: true,\n });\n\n const stat = await fs.promises.stat(savedActiveServerUrlsDirectory);\n if (process.platform !== \"win32\" && !isMode700(stat)) {\n throw new Error(\n `active servers folder ${savedActiveServerUrlsDirectory} has the wrong permissions: ${stat.mode}`\n );\n }\n if (stat.isSymbolicLink()) {\n throw new Error(\n `active servers folder ${savedActiveServerUrlsDirectory} is a symlink`\n );\n }\n}\n\nexport function deleteExistingServerFile(port: number): Promise<void> {\n const folder = path.join(\n savedActiveServerUrlsDirectory,\n fileNameForPort(port)\n );\n if (typeof fs.promises.rm === \"function\") {\n return fs.promises.rm(folder, { force: true });\n } else {\n return rmtree(folder);\n }\n}\n\nexport async function writeExistingServerFile(\n port: number,\n data: ExistingServerInfo\n): Promise<void> {\n await fs.promises.writeFile(\n path.join(savedActiveServerUrlsDirectory, fileNameForPort(port)),\n JSON.stringify(data),\n { encoding: \"utf-8\", flag: \"w\", mode: 0o600 }\n );\n}\n\nexport async function readExistingServerFile(\n port: number\n): Promise<ExistingServerInfo> {\n // TODO: do we need to verify the permissions of this file?\n const data: string = await fs.promises.readFile(\n path.join(savedActiveServerUrlsDirectory, fileNameForPort(port)),\n { encoding: \"utf-8\", flag: \"r\" }\n );\n return JSON.parse(data) as ExistingServerInfo;\n}\n","import { timingSafeEqual } from \"crypto\";\n\n/**\n * Timing safe comparison of tokens coming from strings.\n */\nexport function areTokensEqual(a: string, b: string): boolean {\n const aBuf = Buffer.from(a);\n const bBuf = Buffer.from(b);\n return aBuf.length === bBuf.length && timingSafeEqual(aBuf, bBuf);\n}\n","import type { Logger } from \"@withgraphite/gti-shared\";\n\nimport { makeServerSideTracker } from \"./analytics/serverSideTracker\";\nimport { fileLogger, stdoutLogger } from \"./logger\";\nimport { runCommand } from \"./Repository\";\nimport type { ServerPlatform } from \"./serverPlatform\";\nimport { browserServerPlatform } from \"./serverPlatform\";\nimport { ServerToClientAPI } from \"./ServerToClientAPI\";\n\nexport { DEFAULT_PORT, runProxyMain } from \"../proxy/startServer\";\n\nexport interface ClientConnection {\n /**\n * Used to send a message from the server to the client.\n *\n * Designed to match\n * https://code.visualstudio.com/api/references/vscode-api#Webview.postMessage\n */\n postMessage(message: string): Promise<boolean>;\n\n /**\n * Designed to match\n * https://code.visualstudio.com/api/references/vscode-api#Webview.onDidReceiveMessage\n */\n onDidReceiveMessage(\n hander: (event: Buffer, isBinary: boolean) => void | Promise<void>\n ): {\n dispose(): void;\n };\n\n /**\n * Which command to use to run `gt`\n */\n command?: string;\n /**\n * Platform-specific version string.\n * For `gt interactive web`, this is the `gt` version.\n * For the VS Code extension, this is the extension version.\n */\n version: string;\n logFileLocation?: string;\n logger?: Logger;\n cwd: string;\n\n platform?: ServerPlatform;\n}\n\nexport function onClientConnection(connection: ClientConnection): () => void {\n const logger =\n connection.logger ??\n (connection.logFileLocation\n ? fileLogger(connection.logFileLocation)\n : stdoutLogger);\n connection.logger = logger;\n const platform = connection?.platform ?? browserServerPlatform;\n const version = connection?.version ?? \"unknown\";\n logger.log(`establish client connection for ${connection.cwd}`);\n logger.log(\n `platform '${platform.platformName}', version '${version}', command '${connection.command}'`\n );\n\n const tracker = makeServerSideTracker(logger, platform, version, (data) => {\n return runCommand({\n command: connection.command || \"gt\",\n args: [\n \"internal-only\",\n \"log-action\",\n data.eventName || data.errorName || \"UNKNOWN_CLI_EVENT\",\n (data.timestamp ? new Date(data.timestamp) : new Date()).toISOString(),\n JSON.stringify(data),\n ],\n cwd: connection.cwd,\n });\n });\n tracker.track(\"ClientConnection\", { extras: { cwd: connection.cwd } });\n\n // start listening to messages\n let api: ServerToClientAPI | null = new ServerToClientAPI(\n platform,\n connection,\n tracker,\n logger\n );\n api.setActiveRepoForCwd(connection.cwd);\n\n return () => {\n api?.dispose();\n api = null;\n };\n}\n","import type { PlatformName } from \"@withgraphite/gti-shared\";\nimport { CLOSED_AND_SHOULD_NOT_RECONNECT_CODE } from \"@withgraphite/gti-shared\";\nimport fs from \"fs\";\nimport http from \"http\";\nimport type { AddressInfo } from \"net\";\nimport path from \"path\";\nimport urlModule from \"url\";\nimport WebSocket from \"ws\";\n\nimport { onClientConnection } from \"../src/index\";\nimport { repositoryCache } from \"../src/RepositoryCache\";\nimport type { ServerPlatform } from \"../src/serverPlatform\";\nimport { areTokensEqual } from \"./proxyUtils\";\n\nexport type StartServerArgs = {\n port: number;\n sensitiveToken: string;\n challengeToken: string;\n logFileLocation: string;\n logInfo: (...args: Parameters<typeof console.log>) => void;\n command?: string;\n gtVersion: string;\n foreground: boolean;\n frontendDir: string;\n};\n\nexport type StartServerResult =\n | { type: \"addressInUse\" }\n | { type: \"success\"; port: number; pid: number }\n | { type: \"error\"; error: string };\n\nexport type ServerChallengeResponse = {\n challengeToken: string;\n /** Process ID for the server. */\n pid: number;\n};\n\nexport function startServer({\n port,\n sensitiveToken,\n challengeToken,\n logFileLocation,\n logInfo,\n command,\n gtVersion,\n foreground,\n frontendDir,\n}: StartServerArgs): Promise<StartServerResult> {\n return new Promise((resolve) => {\n try {\n const manifest = JSON.parse(\n fs.readFileSync(\n path.join(frontendDir, \"build/asset-manifest.json\"),\n \"utf-8\"\n )\n ) as { files: Array<string> };\n for (const file of Object.values(manifest.files)) {\n if (!file.startsWith(\"/\")) {\n resolve({\n type: \"error\",\n error: `expected entry to start with / but was: \\`${file}\\``,\n });\n }\n\n requestUrlToResource[file] = file.slice(1);\n }\n } catch (e) {\n // ignore...\n }\n\n // Anything not part of the asset-manifest we need to explicitly serve\n requestUrlToResource[`/favicon.ico`] = \"favicon.ico\";\n\n /**\n * Event listener for HTTP server \"error\" event.\n */\n function onError(error: { syscall?: string; code?: string }) {\n if (error.syscall !== \"listen\") {\n resolve({ type: \"error\", error: error.toString() });\n throw error;\n }\n\n // handle specific listen errors with friendly messages\n switch (error.code) {\n case \"EACCES\": {\n resolve({\n type: \"error\",\n error: `Port ${port} requires elevated privileges`,\n });\n throw error;\n }\n\n case \"EADDRINUSE\": {\n resolve({ type: \"addressInUse\" });\n return;\n }\n\n default:\n resolve({ type: \"error\", error: error.toString() });\n throw error;\n }\n }\n\n /**\n * Create HTTP server.\n */\n const server = http.createServer(async (req, res) => {\n if (req.url) {\n // Only the websocket is sensitive and requires the token.\n // Normal resource requests don't need to check the token.\n const { pathname } = urlModule.parse(req.url);\n // eslint-disable-next-line no-prototype-builtins\n if (pathname != null && requestUrlToResource.hasOwnProperty(pathname)) {\n const relativePath = requestUrlToResource[pathname];\n let contents: string | Buffer;\n try {\n contents = await fs.promises.readFile(\n path.join(frontendDir, \"build\", relativePath)\n );\n } catch (e: unknown) {\n res.writeHead(500, { \"Content-Type\": \"text/plain\" });\n res.end(htmlEscape((e as Error).toString()));\n return;\n }\n\n const lastDot = relativePath.lastIndexOf(\".\");\n const ext = relativePath.slice(lastDot + 1);\n const contentType = extensionToMIMEType[ext] ?? \"text/plain\";\n\n res.writeHead(200, { \"Content-Type\": contentType });\n res.end(contents);\n return;\n } else if (pathname === \"/challenge_authenticity\") {\n // requests to /challenge_authenticity?token=... allow using the sensistive token to ask\n // for the secondary challenge token.\n const requestToken = getSearchParams(req.url).get(\"token\");\n if (requestToken && areTokensEqual(requestToken, sensitiveToken)) {\n // they know the original token, we can tell them our challenge token\n res.writeHead(200, { \"Content-Type\": \"text/json\" });\n const response: ServerChallengeResponse = {\n challengeToken,\n pid: process.pid,\n };\n res.end(JSON.stringify(response));\n } else {\n res.writeHead(401, { \"Content-Type\": \"text/json\" });\n res.end(JSON.stringify({ error: \"invalid token\" }));\n }\n return;\n }\n }\n\n res.writeHead(404, { \"Content-Type\": \"text/html\" });\n res.end(\"<html><body>Not Found!</body></html>\");\n });\n\n /**\n * Listen on provided port, on all network interfaces.\n */\n const httpServer = server.listen(port);\n const wsServer = new WebSocket.Server({ noServer: true, path: \"/ws\" });\n wsServer.on(\"connection\", (socket, connectionRequest) => {\n // We require websocket connections to contain the token as a URL search parameter.\n let providedToken: string | undefined;\n let cwd: string | undefined;\n let platform: string | undefined;\n if (connectionRequest.url) {\n const searchParams = getSearchParams(connectionRequest.url);\n providedToken = searchParams.get(\"token\");\n const cwdParam = searchParams.get(\"cwd\");\n platform = searchParams.get(\"platform\") as string;\n if (cwdParam) {\n cwd = decodeURIComponent(cwdParam);\n }\n }\n if (!providedToken) {\n const reason = \"No token provided in websocket request\";\n logInfo(\"closing ws:\", reason);\n socket.close(CLOSED_AND_SHOULD_NOT_RECONNECT_CODE, reason);\n return;\n }\n if (!areTokensEqual(providedToken, sensitiveToken)) {\n const reason = \"Invalid token\";\n logInfo(\"closing ws:\", reason);\n socket.close(CLOSED_AND_SHOULD_NOT_RECONNECT_CODE, reason);\n return;\n }\n\n const platformImpl: ServerPlatform | undefined = undefined;\n switch (platform as PlatformName) {\n default:\n case undefined:\n break;\n }\n\n const dispose = onClientConnection({\n postMessage(message: string | ArrayBuffer) {\n socket.send(message);\n return Promise.resolve(true);\n },\n onDidReceiveMessage(handler) {\n const emitter = socket.on(\"message\", handler);\n const dispose = () => emitter.off(\"message\", handler);\n return { dispose };\n },\n cwd: cwd ?? process.cwd(),\n logFileLocation:\n logFileLocation === \"stdout\" ? undefined : logFileLocation,\n command,\n version: gtVersion,\n\n platform: platformImpl,\n });\n socket.on(\"close\", () => {\n dispose();\n\n // After disposing, we may not have anymore servers alive anymore.\n // We can proactively clean up the server so you get the latest version next time you try.\n // This way, we only re-use servers if you keep the tab open.\n // Note: since we trigger this cleanup on dispose, if you start a server with `--no-open`,\n // it won't clean itself up until you connect at least once.\n if (!foreground) {\n // We do this on a 1-minute delay in case you close a tab and quickly re-open it.\n setTimeout(() => {\n checkIfServerShouldCleanItselfUp();\n }, 60_000);\n }\n });\n });\n httpServer.on(\"upgrade\", (request, socket, head) => {\n wsServer.handleUpgrade(request, socket, head, (socket) => {\n wsServer.emit(\"connection\", socket, request);\n });\n });\n\n server.on(\"error\", onError);\n\n // return succesful result when the server is successfully listening\n server.on(\"listening\", () =>\n resolve({\n type: \"success\",\n port: (server.address() as AddressInfo).port,\n pid: process.pid,\n })\n );\n });\n}\n\nfunction checkIfServerShouldCleanItselfUp() {\n if (repositoryCache.numberOfActiveServers() === 0) {\n process.exit(0);\n }\n}\n\nfunction getSearchParams(url: string): Map<string, string> {\n const searchParamsArray = urlModule\n .parse(url)\n .search?.replace(/^\\?/, \"\")\n .split(\"&\")\n .map(\n (pair: string): [string, string] => pair.split(\"=\") as [string, string]\n );\n\n return new Map(searchParamsArray);\n}\n\nconst extensionToMIMEType: { [key: string]: string } = {\n css: \"text/css\",\n html: \"text/html\",\n js: \"text/javascript\",\n ttf: \"font/ttf\",\n};\n\nconst requestUrlToResource: { [key: string]: string } = {\n \"/\": \"index.html\",\n};\n\nfunction htmlEscape(str: string): string {\n return str\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"\");\n}\n"],"names":["ComparisonType","exports","comparison","type","UncommittedChanges","HeadChanges","StackChanges","Committed","hash","LRU","constructor","maxItems","maxHashCollision","Map","get","key","result","hashKey","getHashKey","valueMap","cache","undefined","maybeValue","k","v","delete","set","value","size","next","keys","done","clear","hashCodeFunc","hashCode","apply","cachedFunction","func","opts","_a","cacheSize","_b","getExtraKeys","cachedFunc","args","stats","every","isCachable","skip","cacheKey","cachedValue","hit","miss","_c","arg1","arg2","Object","values","filter","_target","_propertyKey","descriptor","originalFunc","cacheDecorator","cachableTypeNames","Set","arg","typeName","has","__exportStar","Tracker","sendData","context","error","eventName","errorName","data","errorMessage","Error","message","String","track","operation","startTime","Date","now","id","parentId","then","finalResult","duration","catch","err","Promise","reject","trackAsParent","trackData","childData","ctx","timestamp","AbortController","node_abort_controller_1","wait","leading","timeout","shouldCallLeading","debouncer","callback","clearTimeout","setTimeout","reset","isPending","SelfUpdate","inner","equals","other","otherInner","paths","options","pathObjects","map","path","separator","replace","length","guessSeparator","rootPrefixResult","exec","rootPrefix","depth","parts","split","reverse","part","hadLeadingSeparator","startsWith","maxDepth","Math","max","pathObject","pathObjectsToProcess","groupedPathObjects","currentDepth","slice","join","add","pathObjectGroup","Array","from","resultPathParts","alwaysShowLeadingSeparator","DiffType","DIFF","RENAME_FROM","RENAME_TO","COPY_FROM","COPY_TO","NEW_FILE_MODE","DELETED_FILE_MODE","OLD_MODE","NEW_MODE","HUNK_HEADER","OLD_FILE_HEADER","NEW_FILE_HEADER","DELIMITERS","assert","condition","msg","patch","diffstr","delimiters","match","list","i","parseIndex","index","hunks","push","line","header","oldFileName","newFileName","parseHeader","test","parseOldMode","parseNewMode","parseDeletedFileMode","parseNewFileMode","parseCopy","parseRename","parseFileHeader","parseHunk","parseHunks","arr","oldMode","Modified","newMode","Removed","Added","Copied","Renamed","hunkHeader","hunk","oldStart","oldLines","newStart","newLines","lines","linedelimiters","addCount","removeCount","indexOf","UNDEFINED_SERIALIZED","__rpcType","serialize","entries","val","stack","valueOf","isArray","a","newObj","propertyName","propertyValue","deserialize","specific","e","standardObject","JSON","stringify","parse","CommandRunner","revset","ErrorShortMessages","toString","random","deferred","promise","resolve","s","delimiter","foundIndex","lastIndexOf","start","className","el","classList","contains","parentElement","o","fromEntries","gen","iter1","iter2","iterator1","Symbol","iterator","iterator2","result1","result2","text","maxLength","substring","getUsername","username","osInfoError","env","process","unwrap","LOGNAME","USER","LNAME","USERNAME","processEnvError","ServerSideContext","logger","setRepo","repo","this","codeReviewProvider","getSummaryName","noOp","_data","stdoutLogger","console","TypedEventEmitter","EventEmitter","GitHubCodeReviewProvider","codeReviewSystem","runCommand","diffSummaries","onChangeDiffSummaries","handleData","handleError","on","dispose","off","async","_diffs","prs","stdout","emit","removeAllListeners","hostname","owner","runExternalCommand","_cwd","_args","_onProgress","_signal","_kind","_query","OperationQueue","runCallback","queuedOperations","runningOperation","abortController","onProgress","tracker","cwd","kind","queue","handleCommandProgress","op","exitCode","controller","newAbortController","trackEventName","extras","runner","_p","signal","shift","runOrQueueOperation","errString","log","abortRunningOperation","operationId","abort","PageFocusTracker","focusedPages","visiblePages","onChangeHandlers","setState","page","state","handler","disposePage","hasPageWithFocus","hasVisiblePage","onChange","RateLimiter","maxSimultaneousRunning","queued","running","runs","nextId","generateId","tryDequeueNext","includes","res","ran","notifyFinished","toRun","run","serializeAsyncCall","asyncFun","scheduledCall","pendingCall","startAsyncCall","resultPromise","callNext","scheduleNextCall","MIN_REQUIRED_CLI_VERSION","Repository","info","IGNORE_COMMIT_MESSAGE_LINES_REGEX","mergeConflicts","uncommittedChanges","smartlogCommits","mergeConflictsEmitter","uncommittedChangesEmitter","smartlogCommitsChangesEmitter","smartlogCommitsBeginFetchingEmitter","uncommittedChangesBeginFetchingEmitter","disposables","onDidDispose","operationQueue","watchForChangesDisposer","pageFocusTracker","currentVisibleCommitRangeIndex","visibleCommitRanges","DEFAULT_DAYS_OF_COMMITS_TO_LOAD","remote","bind","repoInfo","changeCallback","repoRoot","dotdir","dotDirWatcher","chokidar","watch","_event","relativeDotDir","worktreeWatcher","ignored","close","watchForChanges","fetchUncommittedChanges","checkForMergeConflicts","fetchSmartlogCommits","Graphite","runOperation","CodeReviewProvider","normalizedArgs","normalizeOperationArgs","seenDiffs","subscription","subscribeToSmartlogCommitsChanges","fetched","commits","newDiffs","diffIds","commit","pr","number","diffId","triggerDiffSummariesFetch","getAllDiffIds","nextVisibleCommitRangeInDays","forEach","onChangeConflictState","debounce","wasAlreadyInConflicts","file","stat","code","fetchStartTimestamp","output","proc","branchName","readFile","contents","contentsString","trimEnd","previousConflicts","commandOutput","newConflictData","conflicts","newConflicts","files","status","fetchCompletedTimestamp","newConflictSet","conflict","computeNewConflicts","maxConflictsToLog","remainingConflicts","getMergeConflicts","static","command","repoVersion","findVersion","versionFound","versionRequired","profile","repoInfoRaw","preferredBranchEdit","createPrsAs","all","findRepoProfile","findRepoInfo","getConfig","name","dotDir","rootDir","trunkBranch","abortRunningOpeation","cwdRelativeArgs","stdin","getExecParams","input","execution","stderr","addEventListener","child","kill","forceKillAfterTimeout","handleAbortSignalOnProcess","setPageFocus","getUncommittedChanges","subscribeToUncommittedChanges","change","p","getSmartlogCommits","subscribeToSmartlogCommitsBeginFetching","onStart","subscribeToUncommittedChangesBeginFetching","commitInfos","parseCommitInfoOutput","trim","NoCommitsFetched","subscribeToHeadCommit","headCommit","find","isHead","onData","newHead","branch","catLimiter","cat","relativePath","enqueueRun","catArgs","stripFinalNewline","notEmpty","configName","setConfig","level","configValue","command_","args_","options_","appUrl","platform","LANG","EDITOR","GRAPHITE_INTERACTIVE","GIT_OPTIONAL_LOCKS","argv","browserServerPlatform","platformName","handleMessageFromClient","spawn","detached","stdio","windowsHide","windowsVerbatimArguments","unref","RepositoryReferenceImpl","disposeFunc","disposed","internalReference","RefCounted","references","isDisposed","ref","getNumberOfReferences","repositoryCache","RepositoryType","reposByRoot","activeReposEmitter","lookup","dirGuess","endsWith","getOrCreate","cmd","found","getRepoInfo","newlyFound","internalRef","lookupRepoInfoAndReuseIfPossible","cachedRepositoryForPath","onChangeActiveRepos","cb","clearCache","numberOfActiveServers","numActive","ServerToClientAPI","connection","listenersByType","incomingListener","repoDisposables","subscriptions","activeRepoRef","queuedMessages","currentState","pageId","randomId","messageExpectingBinaryFollowup","onDidReceiveMessage","buf","isBinary","handleIncomingMessageWithPayload","deserializeFromString","hasBinaryPayload","expectsBinaryPayload","handleIncomingMessage","setRepoError","disposeRepoDisposables","processQueuedMessages","setCurrentRepo","postMessage","summaries","head","allCommits","ancestor","publicCommit","current","partOfTrunk","parents","findPublicAncestor","public","serializeToString","warn","setActiveRepoForCwd","newCwd","repoOrError","disposable","sub","payload","filename","uploadFile","handleIncomingGeneralMessage","handleIncomingMessageWithRepo","notifyListeners","version","subscriptionID","postUncommittedChanges","d","postSmartlogCommits","postMergeConflicts","progress","filePath","absolutePath","pathMod","fullPath","sep","absolutePathForFileInRepo","rm","revsetArgsForComparison","diff","numLines","content","templates","typeahead","query","rangeInDays","daysToFetch","listeners","handle","cacheDir","LOCALAPPDATA","XDG_CACHE_HOME","b","aBuf","Buffer","bBuf","timingSafeEqual","onClientConnection","logFileLocation","str","appendFile","getLogFileContents","fileLogger","writeToServer","sessionId","unixname","osArch","osType","osRelease","generateAnalyticsInfo","makeServerSideTracker","toISOString","api","startServer","port","sensitiveToken","challengeToken","logInfo","gtVersion","foreground","frontendDir","manifest","requestUrlToResource","server","req","url","pathname","hasOwnProperty","writeHead","end","lastDot","ext","contentType","extensionToMIMEType","requestToken","getSearchParams","response","pid","httpServer","listen","wsServer","noServer","socket","connectionRequest","providedToken","searchParams","cwdParam","decodeURIComponent","reason","CLOSED_AND_SHOULD_NOT_RECONNECT_CODE","send","emitter","exit","request","handleUpgrade","syscall","address","searchParamsArray","search","pair","css","html","js","ttf"],"sourceRoot":""}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
.SplitDiffView-hunk-table{border-spacing:0;table-layout:fixed;width:100%}.SplitDiffView-hunk-table tbody{vertical-align:top}.SplitDiffView-hunk-table td{font-size:12px;line-height:16px;padding:2px 0 2px 6px;white-space:pre-wrap;word-break:break-all}.SplitDiffView-hunk-table td.lineNumber{padding-left:10px;padding-right:10px;text-align:right;white-space:nowrap}.SplitDiffView-hunk-table td.separator{line-height:20px;padding-bottom:0;padding-top:0;text-align:center}
|
|
2
|
-
/*# sourceMappingURL=521.ea7bdcfc.chunk.css.map*/
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"static/css/521.ea7bdcfc.chunk.css","mappings":"AAAA,0BACE,iBACA,mBACA,WAGF,gCACE,mBAGF,6BACE,eACA,iBACA,sBACA,qBACA,qBAGF,wCACE,kBACA,mBACA,iBACA,mBAGF,uCACE,iBAEA,iBADA,cAEA","sources":["parts/split-diff-view/SplitDiffHunk.scss"],"sourcesContent":[".SplitDiffView-hunk-table {\n border-spacing: 0;\n table-layout: fixed;\n width: 100%;\n}\n\n.SplitDiffView-hunk-table tbody {\n vertical-align: top;\n}\n\n.SplitDiffView-hunk-table td {\n font-size: 12px;\n line-height: 16px;\n padding: 2px 0 2px 6px;\n white-space: pre-wrap;\n word-break: break-all;\n}\n\n.SplitDiffView-hunk-table td.lineNumber {\n padding-left: 10px;\n padding-right: 10px;\n text-align: right;\n white-space: nowrap;\n}\n\n.SplitDiffView-hunk-table td.separator {\n line-height: 20px;\n padding-top: 0;\n padding-bottom: 0;\n text-align: center;\n}\n"],"names":[],"sourceRoot":""}
|