今日已更新 248 条资讯 | 累计 38105 条内容
关于我们

标签:#tor

找到 1099 篇相关文章

AI 资讯

Cron Job Monitoring Tools Compared: From DIY to Fully Managed

Cron's biggest problem isn't scheduling — it's silence. A cron job can fail every night for a month, and unless you're manually checking logs on the server, you won't know. No alert, no dashboard, no audit trail. Just a backup that doesn't exist when you need it, or a data sync that quietly stopped three weeks ago. Monitoring fixes this. But "cron job monitoring" means different things depending on the tool. Some watch for missing heartbeats. Some track full execution history. Some just page you when something breaks. This article compares six approaches — from writing your own monitoring scripts to using a fully managed scheduler with built-in observability — so you can pick the right one for your workload. Heartbeat Monitoring vs. Execution Monitoring Before comparing tools, understand the two fundamentally different approaches. Heartbeat monitoring (dead man's switch) is passive. Your cron job pings a monitoring URL after each run. If the ping doesn't arrive on schedule, you get an alert. This tells you whether a job ran — but not what happened . If the job runs but returns bad data, the ping still fires and the monitor stays green. Execution monitoring is active. The scheduler fires the job, captures the response, records the outcome, and alerts on failure. You get the full picture: status code, response body, duration, retry count, and a timeline of every execution. When to use each: Heartbeat monitoring makes sense when you're stuck with system cron. Execution monitoring makes sense when you're choosing a scheduler — you get monitoring, retries, and logging as part of the platform. Comparison at a Glance Tool Type Alerts Execution Logs Retries Free Tier DIY scripts Custom ⚠️ Whatever you build ⚠️ Whatever you build ⚠️ Whatever you build ✅ Free (your time) Healthchecks.io Heartbeat ✅ Email, Slack, webhooks ❌ No ❌ No ✅ 20 checks Cronitor Heartbeat + telemetry ✅ Email, Slack, PagerDuty ⚠️ Basic (duration, exit code) ❌ No ⚠️ 5 monitors Better Stack Uptime + heartb

2026-06-09 原文 →
AI 资讯

OpenTelemetry Observability Guide: How to Optimize Metrics, Logs, and Traces at Scale

Introduction Modern cloud-native systems generate an enormous amount of telemetry data every second. Applications, containers, Kubernetes clusters, APIs, databases, and infrastructure components continuously emit metrics, logs, and traces to help engineering teams understand system behavior and troubleshoot issues. While observability has become essential for operating distributed systems reliably, it has also introduced a new challenge: managing the scale, cost, and quality of telemetry. OpenTelemetry (OTel) has emerged as the industry standard for collecting and processing observability data. It provides a vendor-neutral framework for instrumenting applications and exporting telemetry to different observability backends. However, simply adopting OpenTelemetry is not enough. Without proper optimization strategies, organizations often face excessive telemetry ingestion costs, noisy dashboards, high-cardinality metrics, trace overload, and inefficient debugging workflows. This article explores practical approaches for optimizing observability using OpenTelemetry. It focuses on metrics, logs, and traces individually while also discussing broader optimization strategies across the telemetry pipeline. Understanding the OpenTelemetry observability pipeline OpenTelemetry provides a unified framework for generating, collecting, processing, and exporting telemetry data. At its core, the OTel ecosystem consists of SDKs, instrumentation libraries, collectors, processors, and exporters. Applications generate telemetry using OpenTelemetry SDKs or auto-instrumentation agents. This telemetry is then sent to the OpenTelemetry Collector, which acts as a centralized telemetry processing layer. The collector can receive telemetry from multiple sources, enrich it with metadata, apply filtering or sampling, and export it to one or more observability backends. The observability pipeline typically follows this flow: Application → OTel SDK → OTel Collector → Observability Backend The Open

2026-06-09 原文 →
AI 资讯

Building a production TypeScript CLI in 2026: oclif vs commander vs custom.

Building a production TypeScript CLI in 2026: oclif vs commander vs custom. I shipped my first Node CLI in 2019 with a 12-line arg slicer and process.argv . It worked until it needed a second command and then collapsed into spaghetti. The other extreme is grabbing a full framework for a tool that runs one command. In 2026 there are three reasonable paths between those extremes, and each one wins on a specific slice of the problem. This post covers @oclif/core v4, commander v14, and a zero-dependency parser that fits in 30 lines. Same "greet" command in all three. Same distribution steps at the end. Honest tradeoffs throughout. TL;DR oclif v4 commander v14 zero-dep npm install size ~8 MB ~220 kB 0 B Type inference on flags Full, generated Good, manual Manual Plugin ecosystem Yes (Heroku, Salesforce) No No Learning curve High (day 1) Low (hour 1) None Best for Multi-team, multi-command CLIs Most real-world tools One-shot scripts 1. The decision: framework vs no framework Reach for a framework when the tool needs subcommands, a plugin system, or auto-generated help text. The second engineer who touches the CLI should be able to find where things live without reading your code twice. Build your own when the tool does one thing, ships as a one-file script, or lives inside a monorepo where pulling in 8 MB of transitive deps is not welcome. A zero-dep parser also removes the surface area for supply-chain incidents, a real concern on tools that run in CI. Commander sits in the middle: a 220 kB install that covers most real tools without the scaffolding overhead of oclif. 2. Project skeleton Every path shares the same bin setup. Start with a package.json that declares the executable: { "name" : "greet-cli" , "version" : "1.0.0" , "bin" : { "greet" : "./dist/cli.js" }, "scripts" : { "build" : "tsc" , "dev" : "tsx src/cli.ts" }, "type" : "module" } The tsconfig.json for a CLI targets the Node release line you plan to support. Node 24 LTS handles ESM natively, so use "module":

2026-06-09 原文 →
开发者

Postman Variable ไม่คงอยู่ใน Runner: สาเหตุและวิธีแก้ไข

สรุปสาระสำคัญ (TL;DR) ตัวแปรที่ตั้งค่าระหว่างการรันคำขอแบบแมนนวลใน Postman อาจ “หายไป” เมื่อรันผ่าน Collection Runner เพราะขอบเขตตัวแปรและพฤติกรรมการคงค่าระหว่างการรันไม่เหมือนกัน จุดที่ต้องตรวจสอบคือ pm.environment.set , การเลือก Environment, ค่า Initial/Current Value, ตัวเลือก “Keep variable values” และการเลือกใช้ Collection Variables ให้เหมาะกับสถานะภายในรันเดียวกัน ลองใช้ Apidog วันนี้ บทนำ คุณอาจเคยเจอสถานการณ์นี้: รันคำขอ Login ใน Postman แบบแมนนวล Post-response script ดึง access_token ตั้งค่า token ด้วย pm.environment.set คำขอถัดไปใช้ {{token}} ได้ตามปกติ แต่เมื่อกด Run Collection คำขอ Login ผ่าน แต่คำขอถัดไปได้ 401 Unauthorized ตัวอย่างสคริปต์ที่มักเป็นต้นเหตุ: pm . environment . set ( ' token ' , pm . response . json (). access_token ); สคริปต์นี้ไม่ได้ผิดเสมอไป แต่จะมีปัญหาเมื่อ: ไม่ได้เลือก Environment ใน Runner Runner รีเซ็ตค่าหลังรันเสร็จ ใช้ Environment Variables ทั้งที่ต้องการแค่ state ภายใน Collection Run ตั้งค่าเฉพาะ Current Value แต่ไม่ได้ตั้ง Initial Value บทความนี้สรุปวิธีดีบักและแก้ไขแบบลงมือทำได้ทันที ลำดับชั้นขอบเขตตัวแปรของ Postman Postman แก้ค่า {{variable}} ตามลำดับความสำคัญดังนี้: Local variables — ใช้เฉพาะในสคริปต์ที่กำลังรัน Data variables — มาจากไฟล์ CSV/JSON สำหรับ data-driven test Collection variables — ใช้ภายในคอลเล็กชัน Environment variables — ใช้ใน Environment ที่เลือก Global variables — ใช้ได้ข้ามคอลเล็กชันและ Environment ถ้ามีตัวแปรชื่อเดียวกันหลายขอบเขต เช่น token Postman จะใช้ค่าจากขอบเขตที่มี priority สูงกว่าก่อน ตัวอย่าง: pm . collectionVariables . set ( ' token ' , ' collection-token ' ); pm . environment . set ( ' token ' , ' environment-token ' ); console . log ( pm . variables . get ( ' token ' )); pm.variables.get('token') จะคืนค่าตามลำดับ priority ไม่ได้หมายความว่าจะอ่านจาก Environment เสมอไป ทำไมตัวแปรจึงหายไปใน Collection Runner 1. Current Value และ Initial Value ไม่เหมือนกัน ตัวแปรใน Postman มี 2 ค่า: Initial value : ค่าที่ซิงค์และแชร์กับทีม Current value : ค่า local ในเครื่องของคุณ เมื่อใช้: pm . environment . set (

2026-06-09 原文 →
AI 资讯

Cách khôi phục Collections Postman khi bị khóa tài khoản

Tóm tắt Nếu thay đổi gói miễn phí của Postman khiến bạn mất quyền truy cập vào workspace được chia sẻ, dữ liệu của bạn chưa chắc đã bị xóa. Việc cần làm là phục hồi càng sớm càng tốt trước khi cache cục bộ, quyền API hoặc bản sao lưu còn sót lại không còn dùng được. Bài viết này hướng dẫn các cách lấy lại collection/environment từ Postman và nhập chúng sang Apidog để giảm rủi ro bị khóa dữ liệu trong tương lai. Dùng thử Apidog ngay hôm nay Bối cảnh Sau bản cập nhật gói miễn phí Quý 1 năm 2026 của Postman, nhiều developer dùng workspace chia sẻ với đồng nghiệp phát hiện rằng họ không còn truy cập được dữ liệu nhóm. Các collection nằm trong workspace team, thay vì workspace cá nhân, đột nhiên bị khóa sau paywall. Một developer mô tả trên Reddit: “Tôi đến làm việc vào thứ Hai và toàn bộ không gian làm việc của nhóm tôi đã biến mất. Ba tháng với các bộ sưu tập, môi trường được sắp xếp gọn gàng, tất cả đều biến mất. Chỉ còn cách trả tiền thì mới có lại.” Điểm quan trọng: dữ liệu thường không bị xóa ngay. Postman lưu dữ liệu workspace phía server, còn việc bạn không nhìn thấy collection là hạn chế quyền truy cập. Vì vậy, hãy xử lý theo thứ tự dưới đây, ưu tiên các nguồn có khả năng còn dữ liệu đầy đủ nhất. 1. Kiểm tra cache trong ứng dụng Postman desktop Trước tiên, mở Postman desktop app nếu bạn đã từng dùng nó. Không mở bản web tại app.getpostman.com . Ứng dụng desktop có thể còn cache cục bộ của collection và environment bạn truy cập gần đây. Cache này thường chỉ tồn tại trong thời gian ngắn, tùy hệ thống và cơ chế invalidation của Postman, nên hãy xuất dữ liệu ngay nếu còn nhìn thấy. Các bước thực hiện: Mở Postman desktop. Kiểm tra tab History để xem các request gần đây. Kiểm tra sidebar bên trái xem collection còn hiển thị không. Nếu collection còn hiển thị, xuất ngay từng collection. Cách export collection: Nhấp chuột phải vào collection hoặc bấm menu ba chấm. Chọn Export . Chọn định dạng Collection v2.1 . Lưu file .json ra thư mục an toàn. Nếu collection vẫn hiển t

2026-06-09 原文 →
AI 资讯

How to Recover Postman Collections After Being Locked Out

TL;DR If Postman’s 2026 Q1 free plan change blocked access to shared collections, your data may still be recoverable. Start with your Postman desktop cache, then check exports, admins, the Postman API, and logs. Once you recover the JSON files, import them into Apidog so your team has a safer workflow going forward. Try Apidog today Introduction After Postman’s 2026 Q1 free tier update, many developers found that shared workspaces were no longer accessible on the free plan. Collections that lived in team workspaces, instead of personal workspaces, became locked behind a paid plan. One developer described it on Reddit: “I came in on Monday and my whole team workspace was gone. Three months of organized collections, environments, all of it. Just gone unless we pay.” In most cases, the data is not immediately deleted. Postman stores workspace data server-side, and the issue is usually access restriction rather than deletion. That said, recovery is time-sensitive because local cache, API access, and workspace availability may not last. Use the steps below in order. 1. Check the Postman desktop app cache first Start with the Postman desktop app, not the web app. The desktop app may still have cached copies of recently opened collections and environments. Even if your server-side access is revoked, the local cache can sometimes keep enough data available to export. Steps Open the Postman desktop app. Do not use the web app at app.getpostman.com . Check the left sidebar for your collections. Open the History tab to confirm which endpoints you recently used. If collections are visible, export them immediately. To export a collection: Right-click the collection or open the three-dot menu. Select Export . Choose Collection v2.1 . Save the file locally. Repeat for every visible collection. If the collection appears but export fails, try working offline: Click your avatar in the top-right corner. Select Go Offline . Retry the export. Going offline can prevent the app from refre

2026-06-09 原文 →
AI 资讯

Variável Postman Não Persiste no Runner: Causa e Solução

Em resumo Variáveis definidas em scripts do Postman podem “sumir” quando você troca a execução manual pelo Collection Runner. Na prática, quase sempre é um problema de escopo: pm.environment.set escreve no ambiente ativo, variáveis de coleção têm outro ciclo de vida, e o runner pode descartar alterações ao final da execução. Experimente o Apidog hoje Neste guia, você vai ver como diagnosticar o problema, escolher o escopo correto e corrigir os casos mais comuns. Também verá como o Apidog lida com variáveis de forma mais explícita na interface. Introdução Você testa uma API manualmente no Postman: Executa a requisição de login. Um script salva o token. As próximas requisições usam {{token}} . Tudo funciona. Depois você clica em Run Collection . O login retorna sucesso, mas a próxima requisição falha com 401 Unauthorized . O token não foi encontrado. Esse comportamento é comum porque o modo manual e o Collection Runner não lidam com o estado das variáveis exatamente da mesma forma. A correção começa entendendo a hierarquia de escopos do Postman. Hierarquia de escopo de variáveis do Postman O Postman resolve variáveis seguindo uma ordem de prioridade. Da maior para a menor: Variáveis locais : existem apenas durante a execução do script atual. Variáveis de dados : vêm de arquivos CSV ou JSON usados em execuções orientadas por dados. Variáveis de coleção : pertencem à coleção e podem ser usadas por requisições dentro dela. Variáveis de ambiente : pertencem ao ambiente selecionado. Variáveis globais : ficam disponíveis para qualquer coleção e ambiente. Quando você usa: {{token}} o Postman procura token nessa ordem e usa o primeiro valor encontrado. Isso significa que o problema nem sempre é “a variável não existe”. Às vezes ela existe, mas em outro escopo, ou um escopo de maior prioridade está sobrescrevendo o valor esperado. Por que as variáveis desaparecem no Collection Runner 1. Valor inicial vs. valor atual Cada variável no Postman pode ter dois valores: Valor inicial

2026-06-09 原文 →
AI 资讯

⚙️ Terraform create AWS EC2 instance with Python environment

Terraform can provision an AWS EC2 instance and set up a Python virtual environment in a single, reproducible run — the whole workflow is declarative and version‑controlled. 📑 Table of Contents 💻 Terraform — How to Provision an EC2 Instance 🔧 AWS Provider — Configuring Credentials 🐍 Python Environment — Setting up a Virtualenv on the Instance 📦 Installing Python and venv 📦 Activating and Using the Environment 📦 User Data — Automating Installation with Terraform 🟩 Final Thoughts ❓ Frequently Asked Questions How do I store the Terraform state securely? Can I use a different Linux distribution for the EC2 instance? Is it possible to attach an Elastic IP to the instance? 📚 References & Further Reading 💻 Terraform — How to Provision an EC2 Instance A Terraform configuration file describes the desired state of AWS resources; applying it makes the real cloud match that state. First, install Terraform (version 1.5.0 or newer). The binary is a single executable, so the operating system loads it directly into memory and the process performs HTTP requests to AWS endpoints. $ terraform version Terraform v1.5.0 on linux_amd64 + provider registry.terraform.io/hashicorp/aws v5.12.0 Next, create a main.tf that declares an aws_instance resource. The provider block authenticates with AWS using either environment variables or a shared credentials file. # main.tf terraform { required_version = ">= 1.5.0" required_providers { aws = { source = "hashicorp/aws" version = "~> 5.12" } } } provider "aws" { region = "us-east-1" } resource "aws_instance" "app_server" { ami = "ami-0c02fb55956c7d316" # Amazon Linux 2 instance_type = "t3.micro" # User data will be defined later user_data = data.template_file.init.rendered tags = { Name = "terraform-ec2-python" } } Running terraform init contacts the provider registry, downloads the provider plugin, and stores it under .terraform . The generated .terraform.lock.hcl file records exact plugin checksums, guaranteeing that subsequent runs use the same

2026-06-09 原文 →
AI 资讯

How to Build a Polymarket BTC Momentum Trading Bot in Python (5-Minute Crypto Up/Down Market Strategy)

Introduction Crypto prediction markets move fast. One interesting pattern I noticed while trading on Polymarket is that short-term crypto markets often follow Bitcoin's direction, especially near market expiration. When Bitcoin shows strong directional momentum, assets such as Ethereum (ETH), Solana (SOL), and XRP frequently move in the same direction. This observation led me to build a simple momentum-based Polymarket trading bot. The core idea is straightforward: Monitor BTC Up/Down markets. Detect strong directional probability from the order book. Confirm that ETH, SOL, or XRP markets agree with Bitcoin. Enter positions when confidence is high. Hold until market settlement. Redeem winnings automatically. In this tutorial, you'll learn how to build a Python bot that: ✅ Fetches Polymarket market data ✅ Reads order book probabilities ✅ Detects BTC momentum signals ✅ Places automated buy orders ✅ Waits for settlement ✅ Redeems winning positions The goal is not to predict the future perfectly. The goal is to identify situations where multiple crypto prediction markets agree on direction and exploit that momentum. Why Bitcoin Momentum Matters Bitcoin is still the dominant asset in the cryptocurrency market. When BTC experiences a strong move: ETH often follows SOL often follows XRP often follows Other altcoins frequently move in the same direction This correlation is especially visible during short-duration prediction markets. For example: Market YES Probability BTC Up 0.95 ETH Up 0.93 SOL Up 0.92 When all three markets strongly agree on direction, there may be an opportunity to enter the same side before settlement. This is the basic principle behind the momentum bot. Strategy Overview The bot continuously watches several crypto markets. Step 1: Monitor BTC Market If BTC Up reaches: BTC Up > 0.90 or BTC Down > 0.90 the bot considers Bitcoin momentum strong. Step 2: Confirm Altcoin Agreement The bot then checks: ETH SOL XRP If at least one of these markets has the sam

2026-06-09 原文 →
开发者

Learning about Truthy and Falsy Values in JavaScript

In JavaScript, truthy and falsy values are concepts related to boolean evaluation. Every value in JavaScript has an inherent boolean "truthiness" or "falsiness," which means they can be implicitly evaluated to true or false in boolean contexts, such as in conditional statements or logical operations. What Are Truthy Values? Truthy values are values that are evaluated to be true when used in a Boolean context. Simply put, any value that is not explicitly falsy is considered truthy. These are some truthy values Non-zero numbers: 42, -1, 3.14 Non-empty strings: "hello", "0", " " Objects and arrays: {}, [] Functions: function() {} Dates: new Date() Symbols: Symbol() BigInt values other than 0n: 10n if ( 42 ) console . log ( " This is truthy! " ); if ( " hello " ) console . log ( " Non-empty strings are truthy! " ); if ({}) console . log ( " Objects are truthy! " ); Output This is truthy ! Non - empty strings are truthy ! Objects are truthy ! What Are Falsy Values? Falsy values are values that evaluate to false when used in a Boolean. JavaScript has a fixed list of falsy values false 0 (and -0) 0n (BigInt zero) "" (empty string) null undefined NaN document.all (used for backward compatibility) if (0) console.log("This won't run because 0 is falsy."); if ("") console.log("This won't run because an empty string is falsy."); if (null) console.log("This won't run because null is falsy."); Truthy vs. Falsy Evaluation in JavaScript Whenever JavaScript evaluates an expression in a Boolean (e.g., in an if statement, a logical operator, or a loop condition), it implicitly converts the value into true or false based on whether it is truthy or falsy. With if Statement let s = " JavaScript " ; ​ if ( s ) { console . log ( " Truthy! " ); } else { console . log ( " Falsy! " ); } Output Truthy ! Logical Operators with Truthy and Falsy Logical operators like && (AND) and || (OR) work with truthy and falsy values && (AND): Returns the first falsy operand or the last operand if all are tr

2026-06-09 原文 →
开发者

Conditional Statements in JavaScript

JAVASCRIPT CONDITIONAL STATEMENTS JavaScript conditional statements are used to make decisions in a program based on given conditions. They control the flow of execution by running different code blocks depending on whether a condition is true or false. Conditions are evaluated using comparison and logical operators. They help in building dynamic and interactive applications by responding to different inputs. Types of Conditional Statements 1. if Statement The if statement checks a condition written inside parentheses. If the condition evaluates to true, the code inside {} is executed; otherwise, it is skipped. Executes code only when a specified condition is true. Useful for making simple decisions in a program. Syntax : if ( condition ) { // code runs if condition is true } let x = 20 ; ​ if ( x % 2 === 0 ) { console . log ( " Even " ); } ​ if ( x % 2 !== 0 ) { console . log ( " Odd " ); }; Output Even 2. if-else Statement The if-else statement executes one block of code if a condition is true and another block if it is false. It ensures that exactly one of the two code blocks runs. Used when there are two possible outcomes. The else block runs when the if condition is not satisfied. let age = 25 ; ​ if ( age >= 18 ) { console . log ( " Adult " ) } else { console . log ( " Not an Adult " ) }; Output Adult 3. else if Statement The else if statement is used to test multiple conditions in sequence. It executes the first block whose condition evaluates to true. Allows checking more than two conditions. Evaluated from top to bottom until a true condition is found. const x = 0 ; ​ if ( x > 0 ) { console . log ( " Positive. " ); } else if ( x < 0 ) { console . log ( " Negative. " ); } else { console . log ( " Zero. " ); }; Output Zero . 4. Using Switch Statement (JavaScript Switch Case) The switch statement evaluates an expression and executes the matching case block based on its value. It provides a clean and readable way to handle multiple conditions for a single varia

2026-06-09 原文 →
AI 资讯

We Built a Universal Language for Synchrony — And It Might Be Too Ambitious

How SCPN Phase Orchestrator v0.8.0 turns Kuramoto dynamics into a domain-agnostic control compiler, why we verify math across five languages, and the honest truth about building a Boeing 747 when most people need a bicycle. The $5.2 Billion Blackout That Started This On August 14, 2003, a cascading failure in the US Northeast power grid left 55 million people without electricity. The final report cited something deceptively simple: synchrony loss . A generation unit in Ohio drifted out of phase. The protective relays, designed to prevent damage, tripped in sequence. One desynchronized oscillator triggered a cascade that propagated across 265 power plants in nine minutes. The grid had controllers. It had models. What it lacked was a shared, reviewable language for coherence — a way to ask, in real time: "Is this synchrony valuable or dangerous? And if I touch this knob, can I prove what will happen before the electrons move?" That question is why I built SCPN Phase Orchestrator . It is not a Kuramoto simulator. It is a coherence control compiler — a system that takes any cyclic process (power waves, cloud retries, neural spikes, traffic signals) and compiles it into a unified phase space where synchrony can be observed, classified, and modified with bounded, auditable, replayable actions. Version 0.8.0 just shipped. It includes something I have not seen in any other open-source oscillator library: cross-language mathematical parity verification and Lean proof obligations for safety-critical control chains. This post is the honest story of why we built it, how it works, and where we might have gone too far. The Fragmentation Problem If you work on synchrony in 2026, you live in silos. Power engineers use PSS/E or PowerFactory with swing-equation models. Cloud operators use Airflow, Kestra, or Temporal for workflow orchestration — none of which understand phase dynamics. Neuroscientists use FieldTrip or MNE-Python for EEG phase analysis, but the tools stop at visualiza

2026-06-08 原文 →
AI 资讯

A Practical Intro to Spec-Driven Development (SDD)

When we build something complex—whether it’s a skyscraper, a gourmet meal, or a piece of software—we usually start with a plan. In software development, however, it’s easy to skip that step. We often jump straight into implementation, focusing on how to write the code instead of the intent behind it. Over time, this leads to rework, confusion, and systems that don't quite match our original goals. Spec-Driven Development (SDD) is an approach that shifts the focus back to the plan. Instead of starting with code, you start with a Specification : a clear, structured description of what the software should do. You then use an AI coding agent as a high-speed collaborator to help turn that specification into working code. 🔍 What is a “Spec”? A Specification (or “Spec”) is a written contract between your intention and the final product. It isn't a 50-page manual; it's a living document that defines: What the system should do. How it should behave in different scenarios. Which constraints and rules it must follow. From Prompts to Specifications There is a massive difference between a vague prompt and a structured spec. Loose prompts often lead to inconsistent results and "hallucinations," whereas clear specifications give the AI a much better target to hit. Bad Prompt: > “Build me a login system.” Good Spec: A good spec provides the clarity an AI (or a human) needs to succeed. You don’t need a 10-page document to benefit from specs; you need clarity, not length. 🛠️ Example Spec: Login Endpoint Overview Allow users to log in using email and password. Endpoint POST /api/login Request { "email" : "user@example.com" , "password" : "string" } Behavior Success: If email and password are correct → return a token and user info. Invalid Credentials: If credentials don't match → return INVALID_CREDENTIALS . Invalid Input: If fields are empty or the email format is wrong → return INVALID_INPUT . Rules Passwords must be stored hashed (e.g., bcrypt). Token expires in 24 hours. Security:

2026-06-08 原文 →
AI 资讯

Game Jams no Browser: Você Não Precisa de Unity

Se você já fez algum front-end interativo, já tem 80% do que precisa pra fazer um jogo simples. Game jams como a June Solstice são desculpa perfeita pra testar isso — três semanas, tema aberto, e você descobre que canvas + requestAnimationFrame levam longe. Por Que Desenvolvedores Web Deviam Fazer Game Jams A maioria dos devs que conheço nunca tentou fazer um jogo porque acha que precisa aprender Unity ou Unreal. Mas se você já mexeu com animações CSS, state management ou physics simulators básicos pra UI, você já cruzou metade da ponte. Game jams forçam escopo pequeno — você não vai fazer Elden Ring em três semanas, vai fazer um Snake com twist. E isso cabe perfeitamente no que o browser oferece. Além disso, jogos web rodam em qualquer lugar. Sem instalador, sem App Store review, sem build pra cinco plataformas. Você manda um link e qualquer um joga. Pra um jam onde o pessoal precisa testar dezenas de jogos rápido, isso importa. Canvas API: Seu Motor Gráfico Embutido O <canvas> existe desde 2010 e faz exatamente o que você precisa: desenhar pixels, shapes e imagens num loop de 60fps. A estrutura básica de qualquer jogo 2D cabe em 30 linhas: const canvas = document . querySelector ( ' canvas ' ); const ctx = canvas . getContext ( ' 2d ' ); const gameState = { player : { x : 50 , y : 50 , speed : 2 }, enemies : [] }; function update ( deltaTime ) { // Input handling if ( keys [ ' ArrowRight ' ]) gameState . player . x += gameState . player . speed ; if ( keys [ ' ArrowLeft ' ]) gameState . player . x -= gameState . player . speed ; // Game logic gameState . enemies . forEach ( enemy => { enemy . x += Math . sin ( Date . now () / 1000 ) * 0.5 ; }); } function render () { ctx . clearRect ( 0 , 0 , canvas . width , canvas . height ); // Draw player ctx . fillStyle = ' #00ff00 ' ; ctx . fillRect ( gameState . player . x , gameState . player . y , 20 , 20 ); // Draw enemies gameState . enemies . forEach ( enemy => { ctx . fillStyle = ' #ff0000 ' ; ctx . fillRect ( enemy .

2026-06-08 原文 →