开发者
Ever had a renamed column quietly break a CSV export? csv-pipe makes it a compile error, reads and writes both ways, and parses several times faster than papaparse. Live playground in the post to try your own data.
csv-pipe: read and write CSV in TypeScript, several times faster than papaparse Myroslav Martsin Myroslav Martsin Myroslav Martsin Follow Jun 22 csv-pipe: read and write CSV in TypeScript, several times faster than papaparse # javascript # typescript # webdev # node 1 reaction Add Comment 2 min read
开发者
Sentry vs OpenTelemetry: You Don’t Need to Pick One
TL;DR — If your backend already uses OpenTelemetry, you can send traces and logs to Sentry by changing a few environment variables. No SDK swap, no instrumentation rewrite. Point your OTLP exporter at Sentry’s endpoint, add the Sentry SDK on the frontend for browser context, and you get one connected trace from click to backend span. You already instrumented the backend with OpenTelemetry. Your services emit spans. Your teams know the OTel APIs. Maybe you already run a Collector. So when you start evaluating Sentry, the obvious question is: Do you need to replace your OpenTelemetry setup with the Sentry SDK? No. The practical answer is usually: keep OpenTelemetry where it already works, add the Sentry SDK where it gives you more application context, and send OpenTelemetry Protocol (OTLP) events to Sentry. For a web app, that often means using the Sentry SDK on the frontend for browser tracing, errors, logs , Session Replay , and source maps, while keeping OpenTelemetry on the backend for existing service instrumentation. One scope note: OTLP can carry traces, logs, and metrics. At this moment, Sentry’s OTLP ingest supports logs and traces, not metrics. We’re considering adding support for them in the future. The important part is separating two decisions that often get lumped together: How traces stay connected across frontend and backend. How backend OTLP events are exported to Sentry. Once you separate those, the architecture gets a lot easier to reason about. Sentry vs OpenTelemetry is the wrong question The first decision is trace linking. If a user clicks a button in your React app and that click triggers a backend request, the frontend and backend need to agree on the same distributed trace context. In this example, the Sentry frontend SDK sends W3C traceparent headers (configurable through the propagateTraceparent option), and the OpenTelemetry backend continues the trace. That linking is handled by the frontend SDK configuration: Sentry . init ({ integration
开发者
10 Things Nobody Tells You About process.env
10 Things Nobody Tells You About process.env I've burned myself on most of these so you don't have to. Here's what I wish someone had told me early on. 1. Keys are case-sensitive on Linux, case-insensitive on Windows process . env . PORT = " 3000 " console . log ( process . env . port ) // undefined on Linux, "3000" on Windows This one got me during a "works on my machine" incident. My Windows dev box ran fine. The Linux CI server crashed because a teammate typed env.port instead of env.PORT . Your CI runs Linux. Your dev box probably runs macOS or Windows. Case-sensitivity differences will bite you. How to handle it : Use a validation layer that throws on missing keys. A simple getEnv("PORT") will catch typos at startup. 2. Values are always strings console . log ( typeof process . env . PORT ) // "string" even if you set PORT=3000 Number(process.env.PORT) can return NaN without throwing. Boolean values like "false" are truthy strings. How to handle it : Always parse. If you use a schema library like CtroEnv, it coerces types and throws on invalid input. 3. process.env is NOT the same as .env This confused me for way too long. process.env is whatever the shell gave the process. A .env file is just a text file dotenv reads to populate process.env . Node doesn't touch .env files on its own. // This won't read .env automatically console . log ( process . env . MY_VAR ) // undefined How to handle it : Call dotenv.config() at entry, or use @ctroenv/node which loads .env files automatically. 4. You can set env vars per-command PORT = 4000 node app.js This sets PORT only for that single process. It doesn't pollute your shell session. Super useful for one-off runs or testing different configurations without editing files. console . log ( process . env . PORT ) // "4000" 5. process.env is mutable at runtime process . env . DATABASE_URL = " postgres://hacker:gotme@evil.com/db " I've seen code that modifies process.env to "fix" config at runtime. Don't do this. If something i
AI 资讯
Two undocumented bugs in MCP Apps I found building a task panel for Claude
I spent a week building Wingman , an open source MCP server that renders a persistent task panel inline in Claude conversations using MCP Apps (SEP-1865). The spec is solid. The SDK is solid. But I hit two bugs that cost me most of a weekend each, and neither is documented anywhere I could find. Writing them up here in case they save someone else the time. Bug 1: resourceUri has two valid-looking locations, and only one works MCP Apps needs a way to tell the host "render this resource as a UI for this tool call." That pointer lives in _meta.ui.resourceUri . The question is: meta on what? I started with a parameterized resource template, ui://wingman/panel/{plan_name} , registered per plan. That was my first mistake. Parameterized templates get listed under resources/templates/list , not resources/list , and hosts do not prefetch or render anything from the templates list. The fix was straightforward once I found it: register one static resource, ui://wingman/panel , and pass the actual plan data through structuredContent on the tool result instead of baking it into the URI. That fix surfaced the real bug. My show_plan tool was returning a plain Python dict: return { " plan " : plan_data , " _meta " : { " ui " : { " resourceUri " : " ui://wingman/panel " }} } This looks correct. It is not. FastMCP's result conversion takes a returned dict and serializes the whole thing into structuredContent , verbatim, including any _meta key the dict happens to carry. So the actual wire result looked like this: result . structuredContent [ " _meta " ][ " ui " ][ " resourceUri " ] # == "ui://wingman/panel", but wrong place result . meta # None — this is what the host actually reads MCP Apps hosts read resourceUri off the top-level _meta on the CallToolResult , not off whatever ended up inside structuredContent . With that pointer effectively missing, the host had nowhere to bind the iframe. The visible symptom was strange: actions in the UI would update on screen but nothing persist
开发者
Tufte
CDN and Node package to generate ASCII graphs inline Discussion | Link
开发者
Valve describes just how brutal RAM negotiations are in 2026
Valve's Steam Machine finally has a price: a whopping $1,049 for the 512GB configuration or $1,349 for the 2TB version. And those are without bundled controllers, which drive up the cost more. The prices are so high in part because Valve isn't subsidizing the hardware, and the company has already indicated that the component crisis […]
产品设计
Man used massage gun on his tired eyeballs. It went as well as you'd expect.
He had retinal tears and bruises from squishing his eyeballs with the gun.
科技前沿
iOS 27 beta 2 is out now, here's what's new
Spoiler: It's more Siri stuff.
产品设计
Stripe.Directory
New way for you & agents to search for businesses on Stripe Discussion | Link
AI 资讯
AI chipmaker Groq confirms $650M raise, re-staffs after Nvidia’s $20B not-acqui-hire deal
What does an AI company do after one of those not-acqui-hire deals? Groq raised money, is leaning into its neocloud business, and is hiring new execs.
科技前沿
Polymarket's viral videos showed people winning big, but the bets were fake
"Winning" bets were made on cloned website and would have lost money, WSJ finds.
AI 资讯
Mindstone Rebel
AI workspace for agents that know your work and ask first Discussion | Link
开发者
Microsoft's Secret 90s Weapon That Made Windows Fast
submitted by /u/dukey [link] [留言]
产品设计
Customer Relationship Agents by Clarify
The M in CRM shouldn't be you Discussion | Link
AI 资讯
Tata Electronics, a major tech supplier to Apple and Tesla, confirms data breach
The incident comes as Tata Electronics expands its role in global technology supply chains.
AI 资讯
Valve's Steam Machine ships June 29 for $1,049, but you probably won't be able to buy one yet
Valve says it's using a randomized purchase queue to make the experience "less frustrating and more fair."
AI 资讯
Give your AI agent its own calendar to book meetings
An AI agent that can email but can't hold a calendar slot is only half useful. The moment a conversation turns into "let's meet Thursday at 2," the agent needs a real calendar — one that sends invitations people accept in Google Calendar or Outlook, receives invites at its own address, and RSVPs back so the organizer sees a real response next to everyone else's. Bolting a scheduling library onto a shared mailbox doesn't get you there; the agent needs a calendar identity of its own. An Agent Account ships with exactly that. Every account gets a primary calendar that hosts events, accepts invitations over standard iCalendar, and RSVPs with yes, no, or maybe. To a participant, the agent is just another attendee on the invite. This post walks through using that calendar from two angles: the HTTP API for your backend, and the Nylas CLI for the terminal. I work on the CLI, so the terminal commands below are the ones I reach for. The calendar an Agent Account comes with When Nylas provisions an Agent Account, it creates a primary calendar that belongs to the account. You reach it through the same Calendars and Events endpoints at /v3/grants/{grant_id}/... that any other grant uses, so calendar code you've written for a connected Google or Microsoft account works here unchanged. Each account gets: A primary calendar , provisioned automatically. It can't be deleted while other calendars exist on the account. Additional calendars , up to your plan's cap, for separating concerns — a sales-calls calendar and an internal one on the same agent. Free/busy queries , so the agent can check its own availability before proposing a time. Event webhooks — event.created , event.updated , and event.deleted fire on every change, whether it came from the agent or from someone responding to an invitation. List the calendars from the terminal with nylas calendar list , or over the API with GET /v3/grants/{grant_id}/calendars . Both return the primary calendar plus any you've added. List what'
AI 资讯
Land your AI agent's email in the inbox, not spam
You give your AI agent a real mailbox, it sends its first batch of email, and half of it lands in spam. The agent did nothing wrong. The domain did — it's new, it has no sending history, and mailbox providers treat an unknown domain that suddenly sends volume the same way they treat a spammer. Deliverability is the work of proving the mail is really yours, sending at a pace providers trust, and watching the signals that say whether recipients want it. An Agent Account sends from a domain you own, so its inbox placement is yours to manage like any other mail from your company. This post is a practical playbook for getting and keeping an agent in the inbox, from two angles: the HTTP API for your backend, and the Nylas CLI for the terminal. I work on the CLI, so the terminal commands below are the ones I reach for when I'm wiring up monitoring. The deliverability checklist Five things decide whether an Agent Account reaches the inbox, and you can act on all of them before sending at volume. Work them in order — authentication first, because nothing else matters if recipient servers can't confirm the mail is yours, then pace and monitoring once mail is flowing. Authenticate the domain with DKIM and SPF as part of domain verification. Set up DMARC so providers know how to treat mail that fails authentication. Warm up a new domain before sending at volume, over roughly four weeks. Monitor bounces and complaints through the deliverability webhooks. Stay under the bounce and complaint thresholds that pause sending. The rest of this post covers each one with the commands and request bodies to wire it up. Authenticate with DKIM and SPF Authentication is the foundation, and for an Agent Account it rides on two records you already publish during domain setup. DKIM adds a cryptographic signature proving the message wasn't altered and really came from your domain; SPF authorizes the sending infrastructure to send on your behalf. Both are verified before a custom domain can host a
AI 资讯
Filter what your AI email agent sends and receives
An AI agent with its own mailbox reacts to whatever lands in it. That's the point, until a spam blast, a mailer-daemon loop, or an auto-reply triggers the agent into answering noise. The same goes the other way: an agent composing mail on its own can address the wrong person, leak to a test domain that slipped into production, or email a competitor because nobody told it not to. A human would catch these. An agent needs guardrails encoded somewhere it can't skip. Agent Accounts ship three admin resources for exactly this: Policies bundle limits and spam settings, Rules match mail on the way in or out and run actions like block or assign_to_folder , and Lists are reusable collections of domains or addresses that rules reference. This post covers all three from two angles: the HTTP API for your backend, and the Nylas CLI for inspecting and managing policies and rules from the terminal. Lists, workspaces, and the rule-evaluations audit log are API-only for now. I work on the CLI, so the terminal commands below are the ones I reach for. How Policies, Rules, and Lists fit together The three resources form a chain, and a workspace ties it to your accounts. A List holds values like domains or addresses. A Rule references lists through the in_list operator and describes conditions and actions. A Policy bundles limits and spam settings. A workspace carries one policy_id plus an array of rule_ids , and every Agent Account in that workspace inherits both. What matters here: you don't attach a policy or rule to an individual grant. You set policy_id and rule_ids on a workspace , and they apply to every account in it. Each application has a default workspace that holds any account you haven't placed elsewhere, so configuring that one workspace covers all your unassigned accounts at once. All three resources are application-scoped — they carry no grant ID in the path, and your API key identifies the application. Resource What it owns How it's referenced List A typed collection of
AI 资讯
Keep your AI agent's email replies in the right thread
An AI agent sends an email, a reply lands three hours later, and the agent has to answer two questions before it can do anything useful: which conversation is this, and what did I last say? Get the first one wrong and the agent's reply shows up in the recipient's inbox as a brand-new message instead of slotting into the existing thread. To the person on the other end, that looks broken — like the agent forgot the conversation it started. Threading is the part of agent email that's easy to get almost right and quietly wrong. The fix lives in a few email headers most developers never touch, and in the Threads API that groups messages into conversations for you. This post walks through both, from two angles: the HTTP API for your backend, and the Nylas CLI for the terminal. I work on the CLI, so the terminal commands below are the ones I reach for when I'm testing a reply loop. The three headers that make threading work Threading runs on three email headers, not on subject lines. Every message carries a Message-ID — a globally unique identifier the sending server stamps on it. When someone replies, their mail client adds In-Reply-To (the Message-ID of the message being answered) and References (the full chain of Message-ID values, oldest to newest). Those two headers are how every mail client decides which messages belong together. Here's what the chain looks like across one exchange. The agent's first message gets a Message-ID ; the reply points back at it; the agent's follow-up references both: # The agent's outbound message Message-ID : <abc123@agents.yourcompany.com> Subject : Following up on your demo request # The recipient's reply Message-ID: <def456@gmail.com> In-Reply-To: <abc123@agents.yourcompany.com> References: <abc123@agents.yourcompany.com> Subject: Re: Following up on your demo request # The agent's follow-up Message-ID: <ghi789@agents.yourcompany.com> In-Reply-To: <def456@gmail.com> References: <abc123@agents.yourcompany.com> <def456@gmail.com> The Ref