<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Hacker News: ksri</title><link>https://news.ycombinator.com/user?id=ksri</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Mon, 13 Apr 2026 09:52:23 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=ksri" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by ksri in "Ask HN: What Are You Working On? (April 2026)"]]></title><description><![CDATA[
<p>I am working on a way to edit google docs using markdown. Many tools exist to convert google docs to markdown and to import markdown to google docs - but none of them make in place edits. 
The core logic is to convert the google docs to md. The user then edits the md. Then diff the markdown files, and apply the changes back to the source google docs. This way, features not represented in markdown do not get overwritten.<p>Lots of effort has gone into testing against real world docs. Its beta quality right now.<p><a href="https://github.com/think41/extrasuite" rel="nofollow">https://github.com/think41/extrasuite</a></p>
]]></description><pubDate>Mon, 13 Apr 2026 02:24:33 +0000</pubDate><link>https://news.ycombinator.com/item?id=47746846</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=47746846</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47746846</guid></item><item><title><![CDATA[New comment by ksri in "Ask HN: What Are You Working On? (March 2026)"]]></title><description><![CDATA[
<p>I am working on a declarative CLI for google docs/sheets/slides etc. The general idea is a "pull" command that converts the proprietary document into a local files like tsv or xml. The agent (claude code) then simply edits these files in place and calls "push". The library then figures out the diff and applies only the diff, taking care to preserve formatting and comments.<p>The hypothesis is that llms are better off getting the "big picture" by reading local files. They can then spend tokens to edit the document as per the business needs rather than spending tokens to figure out how to edit the document.<p>Another aspect is the security model. Extrasuite assigns a permission-less service account per employee. The agent gets this service account to make API calls. This means the agent only gets access to documents explicitly shared with it, and any changes it makes show up in version history separate from the user's changes.<p>Early release can be found over here - <a href="https://github.com/think41/extrasuite" rel="nofollow">https://github.com/think41/extrasuite</a>.</p>
]]></description><pubDate>Mon, 09 Mar 2026 17:51:29 +0000</pubDate><link>https://news.ycombinator.com/item?id=47312621</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=47312621</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47312621</guid></item><item><title><![CDATA[New comment by ksri in "Google Workspace CLI"]]></title><description><![CDATA[
<p>re. comparing with other editing agents - actually, I didn't find any that could work with google docs. Many workflows were basically "replace the whole document" - and that was a non-starter.<p>re. what happens if its a big book - each "tab" in the google doc is a folder with its own document.xml. A top-level index.xml captures the table of contents across tabs. The agent reads index.xml and then decides what else to read. I am now improving this by giving it xpath expressions so it can directly pick the specific sections of interest.<p>Philosophically, we wanted "declarative" instead of "imperative". Our key design - the agent needs to "think" in terms of the business, and not worry about how to edit the document. We move all the reconcilliation logic in the library, and free the agent from worrying about the google doc. Same approach in other libraries as well.</p>
]]></description><pubDate>Fri, 06 Mar 2026 07:20:04 +0000</pubDate><link>https://news.ycombinator.com/item?id=47272002</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=47272002</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47272002</guid></item><item><title><![CDATA[Show HN: ExtraSuite – pull / push for Google Drive]]></title><description><![CDATA[
<p>ExtraSuite is a terraform like tool for google drive files - sheets/docs/slides/forms/app scripts. It is meant for agents to make targeted edits to files.<p>While ChatGPT / Claude etc can create the initial versions of the files, the real complexity is in the workflow <i>after</i> the initial version. Team members add comments to provide feedback, or you decide several days later to make minor edits. Re-generating the entire sheet or doc is just not feasible. Our team members resorted to manual edits.<p>We looked around for a library to edit google drive files. We found gspread for google sheets - and our first version used it. It worked well - but it used way too many tokens. Every change required writing python code. This led to the first version of `extrasheet` - which pulls a spreadsheet and converts it into data.tsv, formula.json and several other files. Initial versions duplicated the formula in every cell for a column; subsequently we detected a formula was the same for a range and automatically compress it. Result - our teams were able to make more complex excel models, make targeted edits and perform analysis using fewer tokens and less capable models.<p>Subsequently, we followed the same approach for google docs. This turned out WAY COMPLEX. The batchUpdate API for google docs in insanely complex - you have to painstakingly compute the index. `extrasuite doc push` now detects changes, computes indexes, resolves internal dependencies and ultimately pushes the changes only to google docs.<p>As usage increased, we added google slides (this is pre-alpha), google forms, and even app scripts - all using the same pull-edit-push workflow.<p>One more differentiator is the usage of service accounts for the agent. The SA has no permissions other than the ability to read/comment/edit the specific files that have been shared with it. This means that agent edits are completely auditable. It is clear to everyone in the team that "Alice used her agent to write this document" - because it shows up clearly in the documents version history.<p>To achieve this service account, we deploy a lightweight gateway server that mints 1:1 service accounts per employee on demand. This isn't scalable as there are limits to how many service accounts you can create in a google cloud project (typically 100) - but this hasn't been a problem for us as yet.<p>The gateway server is strictly optional. You can download service account JSON keys and use it to authenticate if you wish, but we dislike giving keys to employees. A gateway server simplifies the workflow significantly for non-tech users.<p>Try it out, and hopefully it is of use to others.<p>P.S. This complements gog and gws, does not replace it. Neither of those tools has a workflow to perform in-place complex edits in a declarative manner.</p>
<hr>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=47263271">https://news.ycombinator.com/item?id=47263271</a></p>
<p>Points: 1</p>
<p># Comments: 0</p>
]]></description><pubDate>Thu, 05 Mar 2026 16:01:52 +0000</pubDate><link>https://github.com/think41/extrasuite</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=47263271</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47263271</guid></item><item><title><![CDATA[New comment by ksri in "Google Workspace CLI"]]></title><description><![CDATA[
<p>I have been working on extrasuite (<a href="https://github.com/think41/extrasuite" rel="nofollow">https://github.com/think41/extrasuite</a>). This is like terraform, but for google drive files.<p>It provides a git like pull/push workflow to edit sheets/docs/slides. `pull` converts the google file into a local folder with agent friendly files. For example, a google sheet becomes a folder with a .tsv, a formula.json and so on. The agent simply edits these files and `push`es the changes. Similarly, a google doc becomes an XML file that is pure content. The agent edits it and calls push - the tool figures out the right batchUpdate API calls to bring the document in sync.<p>None of the existing tools allow you to edit documents. Invoking batchUpdate directly is error prone and token inefficient. Extrasuite solves these issues.<p>In addition, Extrasuite also uses a unique service token that is 1:1 mapped to the user. This means that edits show up as "Alice's agent" in google drive version history. This is secure - agents can only access the specific files or folders you explicitly share with the agent.<p>This is still very much alpha - but we have been using this internally for our 100 member team. Google sheets, docs, forms and app scripts work great - all using the same pull/push metaphor. Google slides needs some work.</p>
]]></description><pubDate>Thu, 05 Mar 2026 08:18:24 +0000</pubDate><link>https://news.ycombinator.com/item?id=47259037</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=47259037</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47259037</guid></item><item><title><![CDATA[New comment by ksri in "How and where will agents ship software?"]]></title><description><![CDATA[
<p>Claude code now has an /export command for this use case. You can run it from within a session.</p>
]]></description><pubDate>Thu, 17 Jul 2025 01:34:15 +0000</pubDate><link>https://news.ycombinator.com/item?id=44588823</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=44588823</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44588823</guid></item><item><title><![CDATA[New comment by ksri in "Writing Code Was Never the Bottleneck"]]></title><description><![CDATA[
<p>Struggling with the same issues with junior developers. I've been asking for an implementation plan and iterating on it. Typical workflow is to commit the implementation plan and review it as part of a pr. It takes 2-3 iterations to get right. Then the developer asks claude code to implement the based on the markdown. I've seen good results with this.<p>Another thing I do is ask for the claude session log file. The inputs and thought they provided to claude give me a lot more insight than the output of claude. Quite often I am able to correct the thought process when I know how they are thinking. I've found junior developers treat claude like a sms - small ambiguous messages with very little context, hoping it would perform magic. By reviewing the claude session file, I try to fix this superficial prompting behaviour.<p>And third, I've realized claude works best of the code itself is structured well and has tests, tools to debug and documentation. So I spend more time on tooling so that claude can use these tools to investigate issues, write tests and iterate faster.<p>Still a far way to go, but this seems promising right now.</p>
]]></description><pubDate>Thu, 03 Jul 2025 15:50:13 +0000</pubDate><link>https://news.ycombinator.com/item?id=44456272</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=44456272</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44456272</guid></item><item><title><![CDATA[New comment by ksri in "SmolLM2"]]></title><description><![CDATA[
<p>Is there a way to run this in the browser as yet? Transformers js doesn't seem to support this. Is there another way to run this in the browser?</p>
]]></description><pubDate>Sat, 02 Nov 2024 09:00:12 +0000</pubDate><link>https://news.ycombinator.com/item?id=42025025</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=42025025</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42025025</guid></item><item><title><![CDATA[New comment by ksri in "Simple SQL in Python"]]></title><description><![CDATA[
<p>Take a look at JinjaSQL (<a href="https://github.com/hashedin/jinjasql" rel="nofollow">https://github.com/hashedin/jinjasql</a>). Supports conditional where clauses as well as in statements. It uses Jinja templates, so you get a complete template language to create the queries.</p>
]]></description><pubDate>Fri, 14 Aug 2020 02:31:42 +0000</pubDate><link>https://news.ycombinator.com/item?id=24152541</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=24152541</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=24152541</guid></item><item><title><![CDATA[New comment by ksri in "A REST View of GraphQL"]]></title><description><![CDATA[
<p>Yes, following relationships is a key feature of Squealy. Here is an example for a recent-questions API - <a href="https://github.com/hashedin/squealy/blob/master/squealy-app/squealy-home/dba.se.com.yml" rel="nofollow">https://github.com/hashedin/squealy/blob/master/squealy-app/...</a>.<p>In short, with 1 GET API call that uses 3 SQL queries, you are getting a list of questions, related answers and related comments.<p>You should parse that example as follows - 
1. The first SQL query fetches all the questions, filtered by API parameters
2. The second SQL query fetches all comments for the questions selected in the first query. See the `WHERE c.postid in {{ questions.id | inclause }}` part - questions.id is coming from the output of the first query
3. The output of the first and second query is merged together on the basis of the questionid that is present in both the query output. 
4. Similar approach is used for all the answers</p>
]]></description><pubDate>Wed, 08 Jul 2020 15:46:24 +0000</pubDate><link>https://news.ycombinator.com/item?id=23771028</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=23771028</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=23771028</guid></item><item><title><![CDATA[New comment by ksri in "A REST View of GraphQL"]]></title><description><![CDATA[
<p>I have been working on an idea to leverage SQL + REST APIs instead of GraphQL to solve the similar problems, and I would love to get some feedback on it.<p>GraphQL is great during development, but in production you often use "persisted queries" to prevent abuse. Persisted queries are also a way to use HTTP GET instead of POST, and thereby leverage HTTP caching. As such, if you swap out graphql and use sql during the development phase, you perhaps can get similar benefits.<p>My solution (<a href="https://github.com/hashedin/squealy" rel="nofollow">https://github.com/hashedin/squealy</a>) uses SQL queries to generate the API response. Squealy uses a template language for the sql queries, so you can directly embed where clause from the API parameters. The library internally binds the parameters, and is free from SQL injection.<p>Handling many-to-many relation, or many one-to-many relations is done in-memory after fetching data from the relational database. This provides the same flexibility as GraphQL, but of course requires you to know SQL.<p>Here is an example that builds various StackOverflow APIs using just a YAML+SQL based DSL - <a href="https://github.com/hashedin/squealy/blob/master/squealy-app/squealy-home/dba.se.com.yml" rel="nofollow">https://github.com/hashedin/squealy/blob/master/squealy-app/...</a><p>Squealy is still work in progress, so don't use it in production. But I would love to get some feedback!</p>
]]></description><pubDate>Wed, 08 Jul 2020 15:07:25 +0000</pubDate><link>https://news.ycombinator.com/item?id=23770607</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=23770607</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=23770607</guid></item><item><title><![CDATA[New comment by ksri in "Modularizing SQL? (2007)"]]></title><description><![CDATA[
<p>I have been working JinjaSQL[1] for a while to simplify complex SQL Queries.<p>JinjaSQL is a templating language, so you can use interpolation, conditionals, macros, includes and so on. It automatically identifies bind parameters, so you don't have you to keep track of them.<p>1. <a href="https://github.com" rel="nofollow">https://github.com</a> /hashedin/jinjasql</p>
]]></description><pubDate>Thu, 18 Jun 2020 10:39:45 +0000</pubDate><link>https://news.ycombinator.com/item?id=23561782</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=23561782</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=23561782</guid></item><item><title><![CDATA[JinjaSQL – Template Language for SQL]]></title><description><![CDATA[
<p>Article URL: <a href="https://github.com/hashedin/jinjasql">https://github.com/hashedin/jinjasql</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=23411505">https://news.ycombinator.com/item?id=23411505</a></p>
<p>Points: 3</p>
<p># Comments: 0</p>
]]></description><pubDate>Thu, 04 Jun 2020 02:01:48 +0000</pubDate><link>https://github.com/hashedin/jinjasql</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=23411505</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=23411505</guid></item><item><title><![CDATA[Show HN: JinjaSQL – Template Language for SQL]]></title><description><![CDATA[
<p>Article URL: <a href="https://github.com/hashedin/jinjasql">https://github.com/hashedin/jinjasql</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=23389601">https://news.ycombinator.com/item?id=23389601</a></p>
<p>Points: 3</p>
<p># Comments: 0</p>
]]></description><pubDate>Tue, 02 Jun 2020 10:45:37 +0000</pubDate><link>https://github.com/hashedin/jinjasql</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=23389601</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=23389601</guid></item><item><title><![CDATA[Cypress now supports Firefox and edge]]></title><description><![CDATA[
<p>Article URL: <a href="https://www.cypress.io/blog/2020/02/06/introducing-firefox-and-edge-support-in-cypress-4-0/">https://www.cypress.io/blog/2020/02/06/introducing-firefox-and-edge-support-in-cypress-4-0/</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=22326599">https://news.ycombinator.com/item?id=22326599</a></p>
<p>Points: 1</p>
<p># Comments: 0</p>
]]></description><pubDate>Fri, 14 Feb 2020 14:06:21 +0000</pubDate><link>https://www.cypress.io/blog/2020/02/06/introducing-firefox-and-edge-support-in-cypress-4-0/</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=22326599</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=22326599</guid></item><item><title><![CDATA[A Cloud-Native Experience for Apache Kafka in Confluent Cloud]]></title><description><![CDATA[
<p>Article URL: <a href="https://www.confluent.io/blog/introducing-cloud-native-experience-for-apache-kafka-in-confluent-cloud">https://www.confluent.io/blog/introducing-cloud-native-experience-for-apache-kafka-in-confluent-cloud</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=19900406">https://news.ycombinator.com/item?id=19900406</a></p>
<p>Points: 3</p>
<p># Comments: 0</p>
]]></description><pubDate>Mon, 13 May 2019 15:43:24 +0000</pubDate><link>https://www.confluent.io/blog/introducing-cloud-native-experience-for-apache-kafka-in-confluent-cloud</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=19900406</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=19900406</guid></item><item><title><![CDATA[New comment by ksri in "TablePlus – Native GUI tool for relational databases (2018)"]]></title><description><![CDATA[
<p>What tool are you using for Redis Management? Is there one that you'd recommend?</p>
]]></description><pubDate>Thu, 14 Feb 2019 14:56:42 +0000</pubDate><link>https://news.ycombinator.com/item?id=19162273</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=19162273</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=19162273</guid></item><item><title><![CDATA[Show HN: RedisOverflow – Redis and Node.js Playground]]></title><description><![CDATA[
<p>Article URL: <a href="https://rdbtools.com/redisoverflow/#/module/0/?questionId=0">https://rdbtools.com/redisoverflow/#/module/0/?questionId=0</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=18333588">https://news.ycombinator.com/item?id=18333588</a></p>
<p>Points: 2</p>
<p># Comments: 0</p>
]]></description><pubDate>Tue, 30 Oct 2018 02:21:52 +0000</pubDate><link>https://rdbtools.com/redisoverflow/#/module/0/?questionId=0</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=18333588</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=18333588</guid></item><item><title><![CDATA[New comment by ksri in "Writing system software: code comments"]]></title><description><![CDATA[
<p>Great categorization!<p>Re. Guide comments - I usually try to make a smaller function with an appropriate name and then call the function. So long function become a series of invocations to smaller functions. This eliminates most guide comments IMO.</p>
]]></description><pubDate>Sun, 07 Oct 2018 09:39:13 +0000</pubDate><link>https://news.ycombinator.com/item?id=18159714</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=18159714</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=18159714</guid></item><item><title><![CDATA[New comment by ksri in "LOLWUT: a piece of art inside a database command"]]></title><description><![CDATA[
<p>Absolutely. First was the Apache commons clause license, and responding to random folks who assumed Redis was going closed source. Then the current issue of changing master slave termibology,and having to hear negative things from both the camps.<p>Lolwut is the perfect break from madness.</p>
]]></description><pubDate>Wed, 12 Sep 2018 16:05:13 +0000</pubDate><link>https://news.ycombinator.com/item?id=17970163</link><dc:creator>ksri</dc:creator><comments>https://news.ycombinator.com/item?id=17970163</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=17970163</guid></item></channel></rss>