ndomo 0.1.0
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/.bun-version +1 -0
- package/.dockerignore +79 -0
- package/.editorconfig +18 -0
- package/.env.example +19 -0
- package/.github/CODEOWNERS +8 -0
- package/.github/ISSUE_TEMPLATE/bug_report.yml +62 -0
- package/.github/ISSUE_TEMPLATE/config.yml +2 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +34 -0
- package/.github/dependabot.yml +36 -0
- package/.github/pull_request_template.md +24 -0
- package/.github/release.yml +30 -0
- package/.github/workflows/gitleaks.yml +28 -0
- package/.github/workflows/release-please.yml +27 -0
- package/.github/workflows/smoke.yml +29 -0
- package/.husky/commit-msg +1 -0
- package/CHANGELOG.md +114 -0
- package/Dockerfile +32 -0
- package/README.es.md +174 -0
- package/README.md +187 -0
- package/agents/chronicler.md +98 -0
- package/agents/ci-smith.md +136 -0
- package/agents/craftsman.md +341 -0
- package/agents/deploy-smith.md +138 -0
- package/agents/foreman.md +377 -0
- package/agents/go-smith.md +164 -0
- package/agents/guild.md +188 -0
- package/agents/inspector.md +83 -0
- package/agents/js-smith.md +127 -0
- package/agents/ops-scout.md +173 -0
- package/agents/painter.md +200 -0
- package/agents/python-smith.md +120 -0
- package/agents/ranger.md +307 -0
- package/agents/release-smith.md +165 -0
- package/agents/rust-smith.md +159 -0
- package/agents/sage.md +178 -0
- package/agents/scout.md +144 -0
- package/agents/scribe.md +156 -0
- package/agents/smith.md +201 -0
- package/agents/vue-smith.md +155 -0
- package/agents/warden.md +216 -0
- package/agents/zig-smith.md +156 -0
- package/bin/ndomo-analyses.ts +4 -0
- package/bin/ndomo-status.ts +4 -0
- package/biome.json +57 -0
- package/bun.lock +514 -0
- package/commitlint.config.js +3 -0
- package/config/ndomo.config.json +258 -0
- package/config/ndomo.schema.json +166 -0
- package/docs/agents.md +375 -0
- package/docs/bugs/plan-create-orphan-fk.md +131 -0
- package/docs/bugs/task_create_batch-order-index-collision.md +158 -0
- package/docs/configuration.md +276 -0
- package/docs/database.md +364 -0
- package/docs/features/feature-flexible-builder-v1.md +724 -0
- package/docs/features/feature-flexible-builder-v2.md +882 -0
- package/docs/features/feature-flexible-builder.md +974 -0
- package/docs/http-server.md +244 -0
- package/docs/installation.md +259 -0
- package/docs/integrations.md +129 -0
- package/docs/operations/anti-pattern-sub-agent-verify-2026-06-21.md +32 -0
- package/docs/operations/audit-v1.md +417 -0
- package/docs/operations/audit-v2.md +197 -0
- package/docs/operations/audit-v3.md +306 -0
- package/docs/operations/db-optimize-foundations.md +123 -0
- package/docs/operations/verify-gate-architecture.md +82 -0
- package/docs/workflows.md +448 -0
- package/opencode.json +5 -0
- package/package.json +65 -0
- package/release-please-config.json +11 -0
- package/scripts/dev-bust-cache.sh +164 -0
- package/scripts/install.sh +688 -0
- package/scripts/smoke-e2e.ts +704 -0
- package/scripts/smoke-hot.ts +417 -0
- package/scripts/smoke-http.sh +228 -0
- package/scripts/smoke-v4.ts +256 -0
- package/scripts/smoke-v5.ts +397 -0
- package/scripts/smoke.sh +9 -0
- package/scripts/uninstall.sh +224 -0
- package/skills/api-security-best-practices/SKILL.md +915 -0
- package/skills/bash-scripting/SKILL.md +201 -0
- package/skills/bun/SKILL.md +313 -0
- package/skills/cavecrew/SKILL.md +82 -0
- package/skills/caveman/SKILL.md +74 -0
- package/skills/caveman-review/README.md +33 -0
- package/skills/caveman-review/SKILL.md +55 -0
- package/skills/find-skills/SKILL.md +142 -0
- package/skills/frontend-design/LICENSE.txt +177 -0
- package/skills/frontend-design/SKILL.md +55 -0
- package/skills/golang-patterns/SKILL.md +674 -0
- package/skills/golang-security/SKILL.md +185 -0
- package/skills/golang-security/evals/evals.json +595 -0
- package/skills/golang-security/references/architecture.md +268 -0
- package/skills/golang-security/references/checklist.md +80 -0
- package/skills/golang-security/references/cookies.md +200 -0
- package/skills/golang-security/references/cryptography.md +424 -0
- package/skills/golang-security/references/filesystem.md +285 -0
- package/skills/golang-security/references/injection.md +315 -0
- package/skills/golang-security/references/logging.md +163 -0
- package/skills/golang-security/references/memory-safety.md +241 -0
- package/skills/golang-security/references/network.md +253 -0
- package/skills/golang-security/references/secrets.md +189 -0
- package/skills/golang-security/references/third-party.md +159 -0
- package/skills/golang-security/references/threat-modeling.md +189 -0
- package/skills/golang-testing/SKILL.md +720 -0
- package/skills/grill-me/SKILL.md +7 -0
- package/skills/javascript-testing-patterns/SKILL.md +537 -0
- package/skills/javascript-testing-patterns/references/advanced-testing-patterns.md +513 -0
- package/skills/modern-javascript-patterns/SKILL.md +43 -0
- package/skills/modern-javascript-patterns/references/advanced-patterns.md +487 -0
- package/skills/modern-javascript-patterns/references/details.md +457 -0
- package/skills/python-anti-patterns/SKILL.md +349 -0
- package/skills/python-design-patterns/SKILL.md +85 -0
- package/skills/python-design-patterns/references/details.md +353 -0
- package/skills/python-error-handling/SKILL.md +193 -0
- package/skills/python-error-handling/references/details.md +171 -0
- package/skills/python-testing-patterns/SKILL.md +278 -0
- package/skills/python-testing-patterns/references/advanced-patterns.md +411 -0
- package/skills/python-testing-patterns/references/details.md +349 -0
- package/skills/rust-patterns/SKILL.md +500 -0
- package/skills/rust-testing/SKILL.md +501 -0
- package/skills/security-review/SKILL.md +504 -0
- package/skills/security-review/cloud-infrastructure-security.md +361 -0
- package/skills/vue-best-practices/SKILL.md +154 -0
- package/skills/vue-best-practices/references/animation-class-based-technique.md +254 -0
- package/skills/vue-best-practices/references/animation-state-driven-technique.md +291 -0
- package/skills/vue-best-practices/references/component-async.md +97 -0
- package/skills/vue-best-practices/references/component-data-flow.md +307 -0
- package/skills/vue-best-practices/references/component-fallthrough-attrs.md +174 -0
- package/skills/vue-best-practices/references/component-keep-alive.md +137 -0
- package/skills/vue-best-practices/references/component-slots.md +216 -0
- package/skills/vue-best-practices/references/component-suspense.md +228 -0
- package/skills/vue-best-practices/references/component-teleport.md +108 -0
- package/skills/vue-best-practices/references/component-transition-group.md +128 -0
- package/skills/vue-best-practices/references/component-transition.md +125 -0
- package/skills/vue-best-practices/references/composables.md +290 -0
- package/skills/vue-best-practices/references/directives.md +162 -0
- package/skills/vue-best-practices/references/perf-avoid-component-abstraction-in-lists.md +159 -0
- package/skills/vue-best-practices/references/perf-v-once-v-memo-directives.md +182 -0
- package/skills/vue-best-practices/references/perf-virtualize-large-lists.md +187 -0
- package/skills/vue-best-practices/references/plugins.md +166 -0
- package/skills/vue-best-practices/references/reactivity.md +344 -0
- package/skills/vue-best-practices/references/render-functions.md +201 -0
- package/skills/vue-best-practices/references/sfc.md +310 -0
- package/skills/vue-best-practices/references/state-management.md +135 -0
- package/skills/vue-best-practices/references/updated-hook-performance.md +187 -0
- package/skills/vue-pinia-best-practices/SKILL.md +21 -0
- package/skills/vue-pinia-best-practices/reference/pinia-no-active-pinia-error.md +248 -0
- package/skills/vue-pinia-best-practices/reference/pinia-setup-store-return-all-state.md +227 -0
- package/skills/vue-pinia-best-practices/reference/pinia-store-destructuring-breaks-reactivity.md +193 -0
- package/skills/vue-pinia-best-practices/reference/state-url-for-ephemeral-filters.md +238 -0
- package/skills/vue-pinia-best-practices/reference/state-use-pinia-for-large-apps.md +262 -0
- package/skills/vue-pinia-best-practices/reference/store-method-binding-parentheses.md +191 -0
- package/skills/zig-0.16/SKILL.md +840 -0
- package/skills/zig-0.16/scripts/check-zig-version.sh +21 -0
- package/src/cli/analyses.ts +280 -0
- package/src/cli/index.ts +108 -0
- package/src/cli/serve.ts +192 -0
- package/src/cli/smoke.ts +131 -0
- package/src/cli/status.test.ts +204 -0
- package/src/cli/status.ts +263 -0
- package/src/cli/vacuum.test.ts +82 -0
- package/src/cli/vacuum.ts +96 -0
- package/src/config/schema.test.ts +88 -0
- package/src/config/schema.ts +64 -0
- package/src/db/analyses-migration.test.ts +210 -0
- package/src/db/analyses.test.ts +466 -0
- package/src/db/analyses.ts +375 -0
- package/src/db/auto-checkpoint.ts +131 -0
- package/src/db/client.test.ts +129 -0
- package/src/db/client.ts +55 -0
- package/src/db/fts-escape.ts +20 -0
- package/src/db/incidents.test.ts +201 -0
- package/src/db/incidents.ts +93 -0
- package/src/db/index.ts +86 -0
- package/src/db/migrations-v13.test.ts +141 -0
- package/src/db/migrations-v8.test.ts +301 -0
- package/src/db/migrations.ts +147 -0
- package/src/db/plan-archive.test.ts +180 -0
- package/src/db/plan-archive.ts +274 -0
- package/src/db/plan-create.test.ts +276 -0
- package/src/db/plan-create.ts +78 -0
- package/src/db/plan-files.test.ts +289 -0
- package/src/db/plan-update-status.ts +287 -0
- package/src/db/plans.test.ts +490 -0
- package/src/db/plans.ts +534 -0
- package/src/db/resolve-project-dir.test.ts +143 -0
- package/src/db/resolve-project-dir.ts +75 -0
- package/src/db/rollbacks.test.ts +150 -0
- package/src/db/rollbacks.ts +67 -0
- package/src/db/schema.ts +907 -0
- package/src/db/sessions.test.ts +80 -0
- package/src/db/sessions.ts +135 -0
- package/src/db/shutdown.test.ts +147 -0
- package/src/db/shutdown.ts +45 -0
- package/src/db/tasks.test.ts +921 -0
- package/src/db/tasks.ts +747 -0
- package/src/db/types.ts +619 -0
- package/src/http/__tests__/auth.test.ts +196 -0
- package/src/http/__tests__/routes.test.ts +465 -0
- package/src/http/__tests__/sse.test.ts +317 -0
- package/src/http/auth.ts +72 -0
- package/src/http/middleware/cors.ts +53 -0
- package/src/http/middleware/security-headers.ts +21 -0
- package/src/http/routes/events.ts +112 -0
- package/src/http/routes/health.ts +51 -0
- package/src/http/routes/plans.ts +66 -0
- package/src/http/routes/sessions.ts +50 -0
- package/src/http/routes/tasks.ts +60 -0
- package/src/http/server.ts +95 -0
- package/src/http/sse.ts +116 -0
- package/src/index.ts +37 -0
- package/src/lib.ts +65 -0
- package/src/mem/scoped.ts +65 -0
- package/src/orchestrator/background.test.ts +268 -0
- package/src/orchestrator/background.ts +293 -0
- package/src/orchestrator/memory-hook.ts +182 -0
- package/src/orchestrator/reconciler.ts +123 -0
- package/src/orchestrator/scheduler.test.ts +300 -0
- package/src/orchestrator/scheduler.ts +243 -0
- package/src/plugin.test.ts +2574 -0
- package/src/plugin.ts +1690 -0
- package/src/sdk/client.ts +66 -0
- package/src/worktrees/manager.ts +236 -0
- package/src/worktrees/state.ts +87 -0
- package/tests/integration/ranger-flow.test.ts +257 -0
- package/tools/analysis_archive.ts +28 -0
- package/tools/analysis_create.ts +55 -0
- package/tools/analysis_get.ts +33 -0
- package/tools/analysis_link_plan.ts +44 -0
- package/tools/analysis_list.ts +48 -0
- package/tools/analysis_search.ts +36 -0
- package/tools/analysis_update.ts +44 -0
- package/tools/plan_approve.ts +31 -0
- package/tools/plan_create.ts +58 -0
- package/tools/plan_get.ts +40 -0
- package/tools/plan_list.ts +37 -0
- package/tools/plan_search.ts +34 -0
- package/tools/plan_update_status.ts +71 -0
- package/tools/session_checkpoint.ts +31 -0
- package/tools/session_end.ts +26 -0
- package/tools/session_start.ts +43 -0
- package/tools/task_create_batch.ts +70 -0
- package/tools/task_list.ts +35 -0
- package/tools/task_next_for_agent.ts +30 -0
- package/tools/task_search.ts +34 -0
- package/tools/task_update_status.ts +37 -0
- package/tsconfig.json +31 -0
|
@@ -0,0 +1,840 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: zig-0.16
|
|
3
|
+
description: Zig 0.16.0 API guidance and porting notes. Use this when writing or upgrading Zig code to the 0.16.0 stable release (std.Io era, @Type removal, @cImport deprecation).
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility:
|
|
6
|
+
- opencode
|
|
7
|
+
- claude-code
|
|
8
|
+
metadata:
|
|
9
|
+
version: "0.16.0"
|
|
10
|
+
language: "zig"
|
|
11
|
+
category: "programming-language"
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Zig 0.16.0 Programming Guide
|
|
15
|
+
|
|
16
|
+
> **Version Scope**: This skill is pinned to **Zig 0.16.0** (stable).
|
|
17
|
+
> **Release Notes**: https://ziglang.org/download/0.16.0/release-notes.html
|
|
18
|
+
|
|
19
|
+
Zig 0.16.0 is a major release introducing `std.Io` as the unified I/O interface, removing `@Type`, deprecating `@cImport`, and significantly reworking the build system package management.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Local Documentation First
|
|
24
|
+
|
|
25
|
+
Run `zig env` to discover installation paths — never hardcode them. Key fields: `.lib_dir`, `.std_dir`, `.version`.
|
|
26
|
+
|
|
27
|
+
- **Language Reference**: `<lib_dir>/../doc/langref.html`
|
|
28
|
+
- **Std Library Source**: read files under `.std_dir` for API verification.
|
|
29
|
+
- **Std Library Docs**: run `zig std` to start a local HTTP server.
|
|
30
|
+
|
|
31
|
+
Always check local docs before web search.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Quick Reference: Top Breaking Changes
|
|
36
|
+
|
|
37
|
+
| Old (0.15.x) | New (0.16.0) |
|
|
38
|
+
|--------------|--------------|
|
|
39
|
+
| `@Type(.Int(...))` | `@Int(.signed, bits)` |
|
|
40
|
+
| `@Type(.Struct(...))` | `@Struct(layout, BackingInt, field_names, field_types, field_defaults, field_is_comptime, field_alignments)` |
|
|
41
|
+
| `@Type(.Pointer(...))` | `@Pointer(size, attrs, Element, sentinel)` |
|
|
42
|
+
| `@Type(.Fn(...))` | `@Fn(param_types, param_attrs, ReturnType, attrs)` |
|
|
43
|
+
| `@Type(.Tuple(...))` | `@Tuple(field_types)` |
|
|
44
|
+
| `@cImport({...})` | `b.addTranslateC(...)` + `@import("c")` (deprecated) |
|
|
45
|
+
| `std.net` | `std.Io.net` |
|
|
46
|
+
| `std.ArrayList.init(allocator)` | `std.ArrayList.initCapacity(allocator, n)` |
|
|
47
|
+
| `std.crypto.random` | `std.Io.randomSecure(io, buf)` |
|
|
48
|
+
| `std.meta.intToEnum` | `std.enums.fromInt` |
|
|
49
|
+
| `std.fmt.FormatOptions` | `std.fmt.Options` |
|
|
50
|
+
| `std.fmt.bufPrintZ` | `std.fmt.bufPrintSentinel` |
|
|
51
|
+
| `std.io.fixedBufferStream` | `std.Io.Writer.fixed(buf)` |
|
|
52
|
+
| `error.RenameAcrossMountPoints` | `error.CrossDevice` |
|
|
53
|
+
| `error.NotSameFileSystem` | `error.CrossDevice` |
|
|
54
|
+
| `error.SharingViolation` | `error.FileBusy` |
|
|
55
|
+
| `error.EnvironmentVariableNotFound` | `error.EnvironmentVariableMissing` |
|
|
56
|
+
| `std.Build.Step.ConfigHeader` cmake handling | fixed leading whitespace |
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Language Changes
|
|
61
|
+
|
|
62
|
+
### @Type Removed — Use Individual Builtins
|
|
63
|
+
|
|
64
|
+
`@Type` is gone. Replace with these builtins:
|
|
65
|
+
|
|
66
|
+
```zig
|
|
67
|
+
// Integer type
|
|
68
|
+
const MyInt = @Int(.signed, 32);
|
|
69
|
+
|
|
70
|
+
// Struct type
|
|
71
|
+
const MyStruct = @Struct(
|
|
72
|
+
.auto, // layout
|
|
73
|
+
null, // BackingInt (for packed)
|
|
74
|
+
&.{"x", "y"}, // field_names
|
|
75
|
+
&.{ i32, i32 }, // field_types
|
|
76
|
+
&.{ null, null },// field_defaults
|
|
77
|
+
&.{ false, false }, // field_is_comptime
|
|
78
|
+
&.{ null, null },// field_alignments
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// Pointer type
|
|
82
|
+
const MyPtr = @Pointer(.one, .{
|
|
83
|
+
.alignment = 8,
|
|
84
|
+
.address_space = .generic,
|
|
85
|
+
.is_const = false,
|
|
86
|
+
.is_volatile = false,
|
|
87
|
+
}, u8, null);
|
|
88
|
+
|
|
89
|
+
// Function type
|
|
90
|
+
const MyFn = @Fn(&.{i32, i32}, &.{.{}, .{}}, i32, .{});
|
|
91
|
+
|
|
92
|
+
// Tuple type
|
|
93
|
+
const MyTuple = @Tuple(&.{ i32, bool });
|
|
94
|
+
|
|
95
|
+
// Enum literal type
|
|
96
|
+
const EnumLitType = @EnumLiteral();
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### @cImport Deprecated — Use Build System Translation
|
|
100
|
+
|
|
101
|
+
`@cImport` is deprecated. Use `addTranslateC` in `build.zig`:
|
|
102
|
+
|
|
103
|
+
```zig
|
|
104
|
+
// build.zig
|
|
105
|
+
const translate_c = b.addTranslateC(.{
|
|
106
|
+
.root_source_file = b.path("src/c.h"),
|
|
107
|
+
.target = target,
|
|
108
|
+
.optimize = optimize,
|
|
109
|
+
});
|
|
110
|
+
translate_c.linkSystemLibrary("glfw", .{});
|
|
111
|
+
|
|
112
|
+
const exe = b.addExecutable(.{
|
|
113
|
+
.name = "myapp",
|
|
114
|
+
.root_module = b.createModule(.{
|
|
115
|
+
.root_source_file = b.path("src/main.zig"),
|
|
116
|
+
.optimize = optimize,
|
|
117
|
+
.target = target,
|
|
118
|
+
.imports = &.{
|
|
119
|
+
.{ .name = "c", .module = translate_c.createModule() },
|
|
120
|
+
},
|
|
121
|
+
}),
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Then in Zig: `const c = @import("c");`
|
|
126
|
+
|
|
127
|
+
**Note**: The C translator is now backed by arocc instead of libclang.
|
|
128
|
+
|
|
129
|
+
### Switch Improvements
|
|
130
|
+
|
|
131
|
+
- `packed struct` and `packed union` may now be used as switch prong items (compared by backing integer).
|
|
132
|
+
- `decl literals` and result-type-dependent expressions (e.g. `@enumFromInt`) may now be used as switch prong items.
|
|
133
|
+
- Union tag captures are now allowed for all prongs, not just inline ones.
|
|
134
|
+
- Switch prong captures may no longer all be discarded.
|
|
135
|
+
- `.awake` atomic order removed; use `.monotonic` / `.seq_cst`.
|
|
136
|
+
|
|
137
|
+
### Other Language-Level Gotchas
|
|
138
|
+
|
|
139
|
+
- **Small integer types coerce to floats** — e.g. `u8` → `f32` is now allowed.
|
|
140
|
+
- **Runtime vector indexes forbidden** — vector indexing must be comptime-known.
|
|
141
|
+
- **Vectors and arrays no longer support in-memory coercion** — must explicitly cast element-wise.
|
|
142
|
+
- **Trivial local addresses cannot be returned from functions** — e.g. `return &local;` is rejected more consistently.
|
|
143
|
+
- **Packed unions must not have unused bits** — all bit patterns must be valid.
|
|
144
|
+
- **Pointers forbidden in packed structs/unions**.
|
|
145
|
+
- **Explicitly-aligned pointer types are now distinct** from naturally-aligned ones in type system.
|
|
146
|
+
- **Simplified dependency loop rules** — most code still works, but self-referential alignment queries now error.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Standard Library: std.Io
|
|
151
|
+
|
|
152
|
+
### Networking
|
|
153
|
+
|
|
154
|
+
- `std.net` is gone. Use `std.Io.net` (types: `IpAddress`, `Stream`, `Server`, `UnixAddress`).
|
|
155
|
+
- High-level helpers like `tcpConnectToHost`, `Address.parseIp`, `Stream.connect` removed. Use `Io` vtables: `io.vtable.netConnectIp`, `netRead`, `netWrite`, `netListenIp`, `netAccept`.
|
|
156
|
+
- Raw fd operations: use `std.os.linux.socket`, `accept4`, `connect`, `bind`, `listen`, `write`, `read`, `close`.
|
|
157
|
+
- `posix.socket`, `posix.bind`, `posix.accept`, `posix.shutdown`, `posix.writev`, `posix.listen`, `posix.pipe2`, `posix.getrandom`, `std.net.has_unix_sockets` removed.
|
|
158
|
+
- Epoll: `std.os.linux.epoll_create1/epoll_ctl/epoll_wait` directly.
|
|
159
|
+
- New: `std.Io.net.Socket.createPair` for socketpair usage in tests.
|
|
160
|
+
|
|
161
|
+
### I/O Readers/Writers
|
|
162
|
+
|
|
163
|
+
- Writer/reader interfaces live under `std.Io`. TLS expects `*std.Io.Reader` / `*std.Io.Writer` (struct fields `.interface`). Pass pointers to interfaces, not call `interface()` as a function.
|
|
164
|
+
- `std.time.sleep` removed; use `std.Io.sleep(io, Duration, Clock)`.
|
|
165
|
+
- `std.Io.GenericWriter`, `std.Io.AnyWriter`, `std.Io.null_writer`, `std.Io.CountingReader` removed.
|
|
166
|
+
|
|
167
|
+
### Time / Random / Env / Exit
|
|
168
|
+
|
|
169
|
+
- `std.time.milliTimestamp` removed. Use `std.time.Timer` or `std.Io.Clock.now(clock, io)` and compare `Timestamp.nanoseconds`.
|
|
170
|
+
- Random secure bytes: `std.Io.randomSecure(io, buf)`; no `std.crypto.random` or `std.posix.getrandom` convenience.
|
|
171
|
+
- `std.process.getEnvVarOwned` removed; use `std.c.getenv` and copy.
|
|
172
|
+
- `std.posix.exit` removed; use `std.process.exit`.
|
|
173
|
+
|
|
174
|
+
### TLS Client Options
|
|
175
|
+
|
|
176
|
+
- `std.crypto.tls.Client.Options` requires `entropy: *const [entropy_len]u8` and `realtime_now_seconds: i64`. Fill entropy with `std.Io.randomSecure`; compute seconds with `Io.Clock.now(.real, io)` / `ns_per_s`.
|
|
177
|
+
|
|
178
|
+
### MemoryPool API Changes
|
|
179
|
+
|
|
180
|
+
- `std.heap.MemoryPool(T).initCapacity(allocator, n)` returns the pool.
|
|
181
|
+
- `create`/`destroy` now require allocator. No bare `init()` or zero-arg `deinit()`.
|
|
182
|
+
|
|
183
|
+
### Format Options
|
|
184
|
+
|
|
185
|
+
- `std.fmt.Options` replaces `FormatOptions`.
|
|
186
|
+
- `std.fmt.format` helper removed; call `writer.print` directly (writers live in `std.Io.Writer`).
|
|
187
|
+
- `std.fmt.Formatter` renamed to `Alt`.
|
|
188
|
+
- `std.fmt.bufPrintZ` renamed to `std.fmt.bufPrintSentinel`.
|
|
189
|
+
|
|
190
|
+
### Randomness / Crypto
|
|
191
|
+
|
|
192
|
+
- `std.crypto.random` removed. Use an `std.Io` instance: `const io = std.Io.Threaded.global_single_threaded.ioBasic(); io.random(&buf);`.
|
|
193
|
+
- `Ed25519.KeyPair.generate` now requires an `io: std.Io` argument.
|
|
194
|
+
|
|
195
|
+
### Enum Conversion
|
|
196
|
+
|
|
197
|
+
- `std.meta.intToEnum` removed. Use `std.enums.fromInt(EnumType, value)` (returns `?EnumType`).
|
|
198
|
+
- `meta.declList` removed.
|
|
199
|
+
|
|
200
|
+
### Fixed-Buffer Writers in Tests
|
|
201
|
+
|
|
202
|
+
- `std.io.fixedBufferStream` removed. For in-memory writes use `var w = std.Io.Writer.fixed(buf);` and read bytes with `std.Io.Writer.buffered(&w)`.
|
|
203
|
+
- `std.ArrayList` no longer has `.init(allocator)` shorthand; use `.initCapacity(allocator, n)`.
|
|
204
|
+
|
|
205
|
+
### Collections
|
|
206
|
+
|
|
207
|
+
- `SegmentedList` removed.
|
|
208
|
+
- `BitSet`, `EnumSet`: replace `initEmpty`, `initFull` with decl literals (e.g. `.{}`, `.{ .a = true }`).
|
|
209
|
+
- New: `Io.Dir.renamePreserve` — rename without replacing destination.
|
|
210
|
+
- `std.Io.Dir.rename` returns `error.DirNotEmpty` rather than `error.PathAlreadyExists`.
|
|
211
|
+
|
|
212
|
+
### Error Set Renames
|
|
213
|
+
|
|
214
|
+
```zig
|
|
215
|
+
// Old -> New
|
|
216
|
+
error.RenameAcrossMountPoints -> error.CrossDevice
|
|
217
|
+
error.NotSameFileSystem -> error.CrossDevice
|
|
218
|
+
error.SharingViolation -> error.FileBusy
|
|
219
|
+
error.EnvironmentVariableNotFound -> error.EnvironmentVariableMissing
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Math
|
|
223
|
+
|
|
224
|
+
- `math.sign` now returns the smallest integer type that fits possible values.
|
|
225
|
+
|
|
226
|
+
### Threading
|
|
227
|
+
|
|
228
|
+
- `Thread.Mutex.Recursive` removed.
|
|
229
|
+
|
|
230
|
+
### Compression
|
|
231
|
+
|
|
232
|
+
- `lzma`, `lzma2`, `xz` updated to `Io.Reader` / `Io.Writer` interfaces.
|
|
233
|
+
|
|
234
|
+
### Dynamic Libraries
|
|
235
|
+
|
|
236
|
+
- `DynLib` removed Windows support. Use `LoadLibraryExW` and `GetProcAddress` directly.
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## New Execution Model: Juicy Main
|
|
241
|
+
|
|
242
|
+
Zig 0.16.0 introduces `std.process.Init` as the preferred `main` parameter. This is the biggest entrypoint change in this release.
|
|
243
|
+
|
|
244
|
+
### `main` signatures
|
|
245
|
+
|
|
246
|
+
```zig
|
|
247
|
+
// 1. Bare (no args/env available)
|
|
248
|
+
pub fn main() !void { }
|
|
249
|
+
|
|
250
|
+
// 2. Minimal (raw argv + environ only)
|
|
251
|
+
pub fn main(init: std.process.Init.Minimal) !void { }
|
|
252
|
+
|
|
253
|
+
// 3. Juicy Main (recommended)
|
|
254
|
+
pub fn main(init: std.process.Init) !void { }
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### `std.process.Init` contents
|
|
258
|
+
|
|
259
|
+
```zig
|
|
260
|
+
pub const Init = struct {
|
|
261
|
+
minimal: Minimal,
|
|
262
|
+
arena: *std.heap.ArenaAllocator, // process-lifetime arena, threadsafe
|
|
263
|
+
gpa: Allocator, // general-purpose allocator
|
|
264
|
+
io: Io, // default Io implementation
|
|
265
|
+
environ_map: *Environ.Map, // env vars (not threadsafe)
|
|
266
|
+
preopens: Preopens, // WASI-style preopened files
|
|
267
|
+
|
|
268
|
+
pub const Minimal = struct {
|
|
269
|
+
environ: Environ,
|
|
270
|
+
args: Args,
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Example
|
|
276
|
+
|
|
277
|
+
```zig
|
|
278
|
+
const std = @import("std");
|
|
279
|
+
|
|
280
|
+
pub fn main(init: std.process.Init) !void {
|
|
281
|
+
const gpa = init.gpa;
|
|
282
|
+
const io = init.io;
|
|
283
|
+
|
|
284
|
+
try std.Io.File.stdout().writeStreamingAll(io, "Hello, world!\n");
|
|
285
|
+
|
|
286
|
+
const args = try init.minimal.args.toSlice(init.arena.allocator());
|
|
287
|
+
for (args, 0..) |arg, i| {
|
|
288
|
+
std.log.info("arg[{d}] = {s}", .{ i, arg });
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
std.log.info("{d} env vars", .{init.environ_map.count()});
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**Rule of thumb**: if your program needs I/O, allocations, or environment variables, use `std.process.Init`.
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Environment Variables & Process Args Are Non-Global
|
|
300
|
+
|
|
301
|
+
`std.os.environ` and `std.process.args` as global state are gone. They are now only available through `main`'s `init` parameter.
|
|
302
|
+
|
|
303
|
+
### Environment variables
|
|
304
|
+
|
|
305
|
+
```zig
|
|
306
|
+
// Juicy Main
|
|
307
|
+
for (init.environ_map.keys(), init.environ_map.values()) |key, value| {
|
|
308
|
+
std.log.info("env: {s}={s}", .{ key, value });
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Minimal main
|
|
312
|
+
std.log.info("HOME: {?s}", .{init.environ.getPosix("HOME")});
|
|
313
|
+
std.log.info("EDITOR: {s}", .{ try init.environ.getAlloc(arena, "EDITOR") });
|
|
314
|
+
const map = try init.environ.createMap(arena);
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### CLI arguments
|
|
318
|
+
|
|
319
|
+
```zig
|
|
320
|
+
// Iterate lazily
|
|
321
|
+
var args = init.args.iterate();
|
|
322
|
+
while (args.next()) |arg| {
|
|
323
|
+
std.log.info("arg: {s}", .{arg});
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// To slice (needs allocator)
|
|
327
|
+
const args = try init.args.toSlice(arena);
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Any function that needs environment variables should accept `*const process.Environ.Map` or `process.Environ` as a parameter.
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## Thread.Pool Removed → Use std.Io
|
|
335
|
+
|
|
336
|
+
`std.Thread.Pool` is removed. Replace with `std.Io.Group`, `std.Io.async`, or `std.Io.concurrent`.
|
|
337
|
+
|
|
338
|
+
### Migration example
|
|
339
|
+
|
|
340
|
+
```zig
|
|
341
|
+
// OLD (0.15)
|
|
342
|
+
fn doAllTheWork(pool: *std.Thread.Pool) void {
|
|
343
|
+
var wg: std.Thread.WaitGroup = .{};
|
|
344
|
+
pool.spawnWg(wg, doSomeWork, .{ pool, &wg, first_work_item });
|
|
345
|
+
wg.wait();
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// NEW (0.16)
|
|
349
|
+
fn doAllTheWork(io: std.Io) void {
|
|
350
|
+
var g: std.Io.Group = .init;
|
|
351
|
+
errdefer g.cancel(io);
|
|
352
|
+
g.async(io, doSomeWork, .{ io, &g, first_work_item });
|
|
353
|
+
g.wait(io);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
fn doSomeWork(io: std.Io, g: *std.Io.Group, foo: Foo) void {
|
|
357
|
+
foo.doTheThing();
|
|
358
|
+
for (foo.new_work_items) |new| {
|
|
359
|
+
g.async(io, doSomeWork, .{ io, g, new });
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
**Important**: when migrating from `Thread.Pool` to `Io`, convert `Thread.Mutex`, `Thread.Condition`, `Thread.ResetEvent` to `Io.Mutex`, `Io.Condition`, `Io.Event`.
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## File I/O & fs API Changes
|
|
369
|
+
|
|
370
|
+
### readFileAlloc / readToEndAlloc
|
|
371
|
+
|
|
372
|
+
```zig
|
|
373
|
+
// OLD
|
|
374
|
+
const contents = try std.fs.cwd().readFileAlloc(allocator, file_name, 1234);
|
|
375
|
+
|
|
376
|
+
// NEW
|
|
377
|
+
const contents = try std.Io.Dir.cwd().readFileAlloc(io, file_name, allocator, .limited(1234));
|
|
378
|
+
// Note: FileTooBig -> StreamTooLong when limit reached.
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
```zig
|
|
382
|
+
// OLD
|
|
383
|
+
const contents = try file.readToEndAlloc(allocator, 1234);
|
|
384
|
+
|
|
385
|
+
// NEW
|
|
386
|
+
var file_reader = file.reader(&.{});
|
|
387
|
+
const contents = try file_reader.interface.allocRemaining(allocator, .limited(1234));
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### setTimestamps
|
|
391
|
+
|
|
392
|
+
```zig
|
|
393
|
+
// OLD
|
|
394
|
+
try atomic_file.file_writer.file.setTimestamps(io, src_stat.atime, src_stat.mtime);
|
|
395
|
+
|
|
396
|
+
// NEW
|
|
397
|
+
try atomic_file.file_writer.file.setTimestamps(io, .{
|
|
398
|
+
.access_timestamp = .init(src_stat.atime),
|
|
399
|
+
.modify_timestamp = .init(src_stat.mtime),
|
|
400
|
+
});
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
`Io.File.Stat.atime` is now `?Timestamp` (can be `null` on e.g. ZFS).
|
|
404
|
+
|
|
405
|
+
### Directory walking
|
|
406
|
+
|
|
407
|
+
- `std.Io.Dir.walk` still exists.
|
|
408
|
+
- New: `std.Io.Dir.walkSelectively` — opt-in recursion per directory, avoiding redundant open/close syscalls.
|
|
409
|
+
- Both `Walker` and `SelectiveWalker` gained `leave()` and `depth()`.
|
|
410
|
+
|
|
411
|
+
### fs.path.relative is now pure
|
|
412
|
+
|
|
413
|
+
```zig
|
|
414
|
+
// OLD
|
|
415
|
+
const relative = try std.fs.path.relative(gpa, from, to);
|
|
416
|
+
|
|
417
|
+
// NEW
|
|
418
|
+
const cwd_path = try std.process.currentPathAlloc(io, gpa);
|
|
419
|
+
const relative = try std.fs.path.relative(gpa, cwd_path, environ_map, from, to);
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### fs.path Windows changes
|
|
423
|
+
|
|
424
|
+
- `windowsParsePath`/`diskDesignator`/`diskDesignatorWindows` → `parsePath`, `parsePathWindows`, `parsePathPosix`
|
|
425
|
+
- Added `getWin32PathType`
|
|
426
|
+
- `componentIterator`/`ComponentIterator.init` can no longer fail
|
|
427
|
+
|
|
428
|
+
### Current Directory API renamed
|
|
429
|
+
|
|
430
|
+
```zig
|
|
431
|
+
// OLD
|
|
432
|
+
std.process.getCwd(buffer)
|
|
433
|
+
std.process.getCwdAlloc(allocator)
|
|
434
|
+
|
|
435
|
+
// NEW
|
|
436
|
+
std.process.currentPath(io, buffer)
|
|
437
|
+
std.process.currentPathAlloc(io, allocator)
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## Preopens & Atomic / Temporary Files
|
|
443
|
+
|
|
444
|
+
### Preopens
|
|
445
|
+
|
|
446
|
+
```zig
|
|
447
|
+
// OLD (WASI)
|
|
448
|
+
const wasi_preopens: std.fs.wasi.Preopens = try .preopensAlloc(arena);
|
|
449
|
+
|
|
450
|
+
// NEW
|
|
451
|
+
const preopens: std.process.Preopens = try .init(arena);
|
|
452
|
+
// Or simply use init.preopens from Juicy Main.
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
`Preopens` is `void` on non-WASI targets — zero-cost abstraction.
|
|
456
|
+
|
|
457
|
+
### Atomic / Temporary Files
|
|
458
|
+
|
|
459
|
+
`std.Io.File.Atomic` is the new API for atomic file writes and temporary files.
|
|
460
|
+
|
|
461
|
+
- Linux: integrates with `O_TMPFILE` when possible.
|
|
462
|
+
- New: `std.Io.File.hardLink`
|
|
463
|
+
- Temporary/random filenames are generated via the Io vtable instead of `std.crypto.random`.
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
## Memory & Allocator Changes
|
|
468
|
+
|
|
469
|
+
### ArenaAllocator is now lock-free and thread-safe
|
|
470
|
+
|
|
471
|
+
`std.heap.ArenaAllocator` no longer needs `ThreadSafeAllocator` wrapping. Performance is comparable single-threaded and faster under contention (~7 threads).
|
|
472
|
+
|
|
473
|
+
### ThreadSafe Allocator removed
|
|
474
|
+
|
|
475
|
+
`std.heap.ThreadSafe` is removed; use `ArenaAllocator` directly, or synchronize access manually.
|
|
476
|
+
|
|
477
|
+
### Memory Locking / Protection moved to `std.process`
|
|
478
|
+
|
|
479
|
+
```zig
|
|
480
|
+
// OLD
|
|
481
|
+
try std.posix.mlock();
|
|
482
|
+
try std.posix.mlock2(slice, std.posix.MLOCK_ONFAULT);
|
|
483
|
+
try std.posix.mlockall(slice, std.posix.MCL_CURRENT | std.posix.MCL_FUTURE);
|
|
484
|
+
|
|
485
|
+
// NEW
|
|
486
|
+
try std.process.lockMemory(slice, .{});
|
|
487
|
+
try std.process.lockMemory(slice, .{ .on_fault = true });
|
|
488
|
+
try std.process.lockMemoryAll(.{ .current = true, .future = true });
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
mmap/mprotect flags are now type-safe structs instead of bitwise OR:
|
|
492
|
+
|
|
493
|
+
```zig
|
|
494
|
+
// OLD
|
|
495
|
+
std.posix.PROT.READ | std.posix.PROT.WRITE
|
|
496
|
+
|
|
497
|
+
// NEW
|
|
498
|
+
.{ .READ = true, .WRITE = true }
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
### MemoryPool
|
|
502
|
+
|
|
503
|
+
- `std.heap.MemoryPool(T).initCapacity(allocator, n)` returns the pool.
|
|
504
|
+
- `create`/`destroy` now require allocator parameter.
|
|
505
|
+
- New unmanaged variants: `MemoryPoolUnmanaged`, `MemoryPoolAlignedUnmanaged`, `MemoryPoolExtraUnmanaged`.
|
|
506
|
+
|
|
507
|
+
### Io.Writer.Allocating alignment field
|
|
508
|
+
|
|
509
|
+
```zig
|
|
510
|
+
alignment: std.mem.Alignment, // new field
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
---
|
|
514
|
+
|
|
515
|
+
## Container & Collection Changes
|
|
516
|
+
|
|
517
|
+
### Migration to "Unmanaged"
|
|
518
|
+
|
|
519
|
+
Managed variants with embedded `Allocator` fields are being phased out.
|
|
520
|
+
|
|
521
|
+
- `ArrayHashMap`, `AutoArrayHashMap`, `StringArrayHashMap` **removed**.
|
|
522
|
+
- `AutoArrayHashMapUnmanaged` → `array_hash_map.Auto`
|
|
523
|
+
- `StringArrayHashMapUnmanaged` → `array_hash_map.String`
|
|
524
|
+
- `ArrayHashMapUnmanaged` → `array_hash_map.Custom`
|
|
525
|
+
|
|
526
|
+
### PriorityQueue
|
|
527
|
+
|
|
528
|
+
```zig
|
|
529
|
+
var queue = std.PriorityQueue(u32, void, lessThan).empty;
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
- `init` → `initContext`
|
|
533
|
+
- `add` → `push`
|
|
534
|
+
- `addSlice` → `pushSlice`
|
|
535
|
+
- `remove` / `removeOrNull` → `pop`
|
|
536
|
+
- `removeIndex` → `popIndex`
|
|
537
|
+
|
|
538
|
+
### PriorityDequeue
|
|
539
|
+
|
|
540
|
+
```zig
|
|
541
|
+
var dq = std.PriorityDequeue(u32, void, lessThan).empty;
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
- `init` → `.empty`
|
|
545
|
+
- `add` → `push`
|
|
546
|
+
- `removeMinOrNull` / `removeMin` → `popMin`
|
|
547
|
+
- `removeMaxOrNull` / `removeMax` → `popMax`
|
|
548
|
+
- `removeIndex` → `popIndex`
|
|
549
|
+
|
|
550
|
+
### BitSet / EnumSet
|
|
551
|
+
|
|
552
|
+
Use decl literals instead of `initEmpty` / `initFull`:
|
|
553
|
+
|
|
554
|
+
```zig
|
|
555
|
+
var set = std.EnumSet(MyEnum).empty;
|
|
556
|
+
var full = std.EnumSet(MyEnum).full;
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
### SegmentedList
|
|
560
|
+
|
|
561
|
+
- `std.SegmentedList` removed.
|
|
562
|
+
|
|
563
|
+
---
|
|
564
|
+
|
|
565
|
+
## Removed APIs (Quick List)
|
|
566
|
+
|
|
567
|
+
| Removed API | Replacement |
|
|
568
|
+
|-------------|-------------|
|
|
569
|
+
| `std.Thread.Pool` | `std.Io.Group`, `Io.async`, `Io.concurrent` |
|
|
570
|
+
| `std.heap.ThreadSafe` | `std.heap.ArenaAllocator` (now thread-safe) |
|
|
571
|
+
| `std.io.fixedBufferStream` | `std.Io.Reader.fixed(data)` / `std.Io.Writer.fixed(buf)` |
|
|
572
|
+
| `std.Io.GenericReader` | `std.Io.Reader` |
|
|
573
|
+
| `std.Io.AnyReader` | `std.Io.Reader` |
|
|
574
|
+
| `std.Io.GenericWriter` | `std.Io.Writer` |
|
|
575
|
+
| `std.Io.AnyWriter` | `std.Io.Writer` |
|
|
576
|
+
| `std.Io.null_writer` | Use `std.Io.Writer` directly |
|
|
577
|
+
| `std.Io.CountingReader` | No direct replacement; track bytes manually |
|
|
578
|
+
| `std.SegmentedList` | None |
|
|
579
|
+
| `std.meta.declList` | None |
|
|
580
|
+
| `std.fs.getAppDataDir` | None |
|
|
581
|
+
| `std.posix.getCwd*` | `std.process.currentPath*` |
|
|
582
|
+
| `std.posix.mlock*` | `std.process.lockMemory*` |
|
|
583
|
+
| `std.posix.PROT_*` bitwise flags | Struct literal flags |
|
|
584
|
+
| `std.ArrayHashMap` | `array_hash_map.Auto` / `.String` / `.Custom` |
|
|
585
|
+
|
|
586
|
+
---
|
|
587
|
+
|
|
588
|
+
## Common Idioms in Zig 0.16.0
|
|
589
|
+
|
|
590
|
+
### ArrayList
|
|
591
|
+
|
|
592
|
+
```zig
|
|
593
|
+
const std = @import("std");
|
|
594
|
+
|
|
595
|
+
pub fn main(init: std.process.Init) !void {
|
|
596
|
+
const gpa = init.gpa;
|
|
597
|
+
|
|
598
|
+
var list = try std.ArrayList(u8).initCapacity(gpa, 16);
|
|
599
|
+
defer list.deinit(gpa);
|
|
600
|
+
|
|
601
|
+
try list.append(gpa, 'a');
|
|
602
|
+
try list.appendSlice(gpa, "hello");
|
|
603
|
+
try list.ensureTotalCapacity(gpa, 100);
|
|
604
|
+
|
|
605
|
+
const owned = try list.toOwnedSlice(gpa);
|
|
606
|
+
defer gpa.free(owned);
|
|
607
|
+
}
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
### HashMap (Default / Unmanaged Style)
|
|
611
|
+
|
|
612
|
+
```zig
|
|
613
|
+
var map = std.StringHashMap(u32).empty;
|
|
614
|
+
defer map.deinit(gpa);
|
|
615
|
+
|
|
616
|
+
try map.put(gpa, "key", 42);
|
|
617
|
+
const val = map.get("key") orelse 0;
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
### stdout / stderr with Juicy Main
|
|
621
|
+
|
|
622
|
+
```zig
|
|
623
|
+
pub fn main(init: std.process.Init) !void {
|
|
624
|
+
const io = init.io;
|
|
625
|
+
|
|
626
|
+
// Direct streaming write
|
|
627
|
+
try std.Io.File.stdout().writeStreamingAll(io, "Hello, world!\n");
|
|
628
|
+
|
|
629
|
+
// Or via writer interface
|
|
630
|
+
var stdout_writer = std.Io.File.stdout().writer(&.{});
|
|
631
|
+
try stdout_writer.interface.print("value: {d}\n", .{42});
|
|
632
|
+
}
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
### Fixed-Buffer Reader / Writer
|
|
636
|
+
|
|
637
|
+
```zig
|
|
638
|
+
// Reader from byte slice
|
|
639
|
+
var data = "line1\nline2\n";
|
|
640
|
+
var reader: std.Io.Reader = .fixed(data);
|
|
641
|
+
|
|
642
|
+
// Writer into a stack buffer
|
|
643
|
+
var buf: [256]u8 = undefined;
|
|
644
|
+
var writer: std.Io.Writer = .fixed(&buf);
|
|
645
|
+
try writer.interface.print("count: {d}", .{7});
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
### File I/O
|
|
649
|
+
|
|
650
|
+
```zig
|
|
651
|
+
// Read entire file
|
|
652
|
+
const contents = try std.Io.Dir.cwd().readFileAlloc(io, "input.txt", gpa, .limited(1024 * 1024));
|
|
653
|
+
defer gpa.free(contents);
|
|
654
|
+
|
|
655
|
+
// Write file atomically
|
|
656
|
+
var atomic = try std.Io.File.Atomic.init(io, gpa, "output.txt");
|
|
657
|
+
try atomic.file_writer.interface.print("data: {s}\n", .{"hello"});
|
|
658
|
+
try atomic.commit(io);
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
### JSON
|
|
662
|
+
|
|
663
|
+
```zig
|
|
664
|
+
const MyStruct = struct {
|
|
665
|
+
name: []const u8,
|
|
666
|
+
value: u32,
|
|
667
|
+
};
|
|
668
|
+
|
|
669
|
+
// Parsing
|
|
670
|
+
const json_str =
|
|
671
|
+
\\{"name": "test", "value": 42}
|
|
672
|
+
;
|
|
673
|
+
const parsed = try std.json.parseFromSlice(MyStruct, gpa, json_str, .{});
|
|
674
|
+
defer parsed.deinit();
|
|
675
|
+
|
|
676
|
+
// Serialization to string (via Io.Writer.Allocating)
|
|
677
|
+
var out: std.Io.Writer.Allocating = .init(gpa);
|
|
678
|
+
defer out.deinit();
|
|
679
|
+
var stringify: std.json.Stringify = .{
|
|
680
|
+
.writer = &out.writer,
|
|
681
|
+
.options = .{},
|
|
682
|
+
};
|
|
683
|
+
try stringify.write(parsed.value);
|
|
684
|
+
const json_output = out.written();
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
### Type Reflection (Comptime)
|
|
688
|
+
|
|
689
|
+
```zig
|
|
690
|
+
const info = @typeInfo(T);
|
|
691
|
+
if (info == .pointer) { ... }
|
|
692
|
+
if (info == .slice) { ... }
|
|
693
|
+
if (info == .@"struct") { ... }
|
|
694
|
+
if (info == .@"enum") { ... }
|
|
695
|
+
if (info == .@"union") { ... }
|
|
696
|
+
if (info == .optional) { ... }
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
### Testing
|
|
700
|
+
|
|
701
|
+
```zig
|
|
702
|
+
test "basic arithmetic" {
|
|
703
|
+
const std = @import("std");
|
|
704
|
+
try std.testing.expectEqual(4, 2 + 2);
|
|
705
|
+
try std.testing.expectError(error.OutOfMemory, mightFail());
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
test "no leaks" {
|
|
709
|
+
const std = @import("std");
|
|
710
|
+
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
711
|
+
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
|
712
|
+
const allocator = gpa.allocator();
|
|
713
|
+
|
|
714
|
+
const ptr = try allocator.create(u32);
|
|
715
|
+
defer allocator.destroy(ptr);
|
|
716
|
+
}
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
### Leb128 (Binary Format)
|
|
720
|
+
|
|
721
|
+
```zig
|
|
722
|
+
// OLD: std.leb.readUleb128(reader)
|
|
723
|
+
// NEW:
|
|
724
|
+
const value = try reader.takeLeb128(u64);
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
---
|
|
728
|
+
|
|
729
|
+
## Common Error Messages and Fixes (0.16)
|
|
730
|
+
|
|
731
|
+
| Error | Cause | Fix |
|
|
732
|
+
|-------|-------|-----|
|
|
733
|
+
| `no field named 'getStdOut'` | Using old `std.io.getStdOut()` | Use `std.Io.File.stdout()` |
|
|
734
|
+
| `expected 2 argument(s), found 1` | `ArrayList` method missing allocator | Add allocator as first argument |
|
|
735
|
+
| `no member named 'Pool' in 'Thread'` | `std.Thread.Pool` removed | Use `std.Io.Group` + `Io.async` |
|
|
736
|
+
| `expected type '*const process.Environ.Map'` | Function needs env map param | Pass it from `main(init)` |
|
|
737
|
+
| `no member named 'fixedBufferStream'` | Old stream API removed | Use `std.Io.Reader.fixed(...)` or `std.Io.Writer.fixed(...)` |
|
|
738
|
+
| `no field named 'getCwd' in 'process'` | Renamed | Use `std.process.currentPath*` |
|
|
739
|
+
| `fingerprint field missing` | Old `build.zig.zon` | Add `.fingerprint = 0x...` and change `.name = "x"` to `.name = .x` |
|
|
740
|
+
| `type depends on itself for alignment` | Self-referential alignment query | Remove `@alignOf(@This())` or restructure |
|
|
741
|
+
|
|
742
|
+
---
|
|
743
|
+
|
|
744
|
+
## Build System Changes
|
|
745
|
+
|
|
746
|
+
### Fingerprint Required in build.zig.zon
|
|
747
|
+
|
|
748
|
+
`build.zig.zon` now requires a `fingerprint` field, and `name` must be an enum literal, not a string:
|
|
749
|
+
|
|
750
|
+
```zig
|
|
751
|
+
.{
|
|
752
|
+
.name = .myproject, // enum literal, not "myproject"
|
|
753
|
+
.fingerprint = 0x123456789abcdef0,
|
|
754
|
+
.version = "0.1.0",
|
|
755
|
+
.dependencies = .{},
|
|
756
|
+
}
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
`zig build` will fail if these are missing.
|
|
760
|
+
|
|
761
|
+
### Local Package Overrides: --fork
|
|
762
|
+
|
|
763
|
+
New CLI flag for temporary local overrides:
|
|
764
|
+
|
|
765
|
+
```bash
|
|
766
|
+
zig build --fork=/path/to/local/fork
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
Any dependency with matching `name` + `fingerprint` will resolve to the local path instead of being fetched. This is ephemeral — remove the flag to revert.
|
|
770
|
+
|
|
771
|
+
### Packages Fetched to zig-pkg Directory
|
|
772
|
+
|
|
773
|
+
Dependencies are now fetched into a local `zig-pkg/` directory (next to `build.zig`) instead of the global cache. After filtering, they are recompressed into the global cache for future reuse.
|
|
774
|
+
|
|
775
|
+
### Unit Test Timeouts
|
|
776
|
+
|
|
777
|
+
Specify per-test timeouts:
|
|
778
|
+
|
|
779
|
+
```bash
|
|
780
|
+
zig build test --test-timeout 500ms
|
|
781
|
+
```
|
|
782
|
+
|
|
783
|
+
After the timeout, the test process is killed and restarted for the next test.
|
|
784
|
+
|
|
785
|
+
### ConfigHeader
|
|
786
|
+
|
|
787
|
+
- `std.Build.Step.ConfigHeader` now handles leading whitespace for cmake-style config headers correctly.
|
|
788
|
+
|
|
789
|
+
---
|
|
790
|
+
|
|
791
|
+
## Compiler / Toolchain
|
|
792
|
+
|
|
793
|
+
### C Translation
|
|
794
|
+
|
|
795
|
+
- `@cImport` still exists but is deprecated and now backed by arocc instead of libclang.
|
|
796
|
+
- For new code, always use `addTranslateC` in `build.zig`.
|
|
797
|
+
|
|
798
|
+
### Type Resolution
|
|
799
|
+
|
|
800
|
+
- Reworked internal type resolution. Most previously-working code still works, and some "dependency loop" errors are now resolved.
|
|
801
|
+
- Self-referential alignment queries (e.g. `align(@alignOf(@This()))`) now correctly error.
|
|
802
|
+
|
|
803
|
+
### LLVM Backend
|
|
804
|
+
|
|
805
|
+
- Experimental incremental compilation support.
|
|
806
|
+
- Error set types now lowered as enums in debug info, so error names are visible at runtime.
|
|
807
|
+
|
|
808
|
+
---
|
|
809
|
+
|
|
810
|
+
## Target Support
|
|
811
|
+
|
|
812
|
+
Notable additions:
|
|
813
|
+
- `aarch64-freebsd`, `aarch64-netbsd`, `loongarch64-linux`, `powerpc64le-linux`, `s390x-linux`, `x86_64-freebsd`, `x86_64-netbsd`, `x86_64-openbsd` now tested in CI.
|
|
814
|
+
- `aarch64-maccatalyst`, `x86_64-maccatalyst` cross-compilation added.
|
|
815
|
+
- Initial `loongarch32-linux` support (no libc yet).
|
|
816
|
+
- Basic support added for Alpha, KVX, MicroBlaze, OpenRISC, PA-RISC, SuperH.
|
|
817
|
+
- Solaris, AIX, z/OS support removed.
|
|
818
|
+
- Stack tracing improved across almost all major targets.
|
|
819
|
+
|
|
820
|
+
---
|
|
821
|
+
|
|
822
|
+
## Testing Adjustments
|
|
823
|
+
|
|
824
|
+
- For in-process client/server tests, use `std.Io.net.Socket.createPair` or raw `socketpair(AF.UNIX, SOCK.STREAM|CLOEXEC, 0, &fds)` to avoid relying on Io vtable network (Threaded nets return `NetworkDown` if not wired).
|
|
825
|
+
- Error sets tightened in many std.Io functions — remove unreachable branches accordingly.
|
|
826
|
+
|
|
827
|
+
---
|
|
828
|
+
|
|
829
|
+
## Porting Strategy (0.15 → 0.16)
|
|
830
|
+
|
|
831
|
+
1. **Replace `@Type` calls** with the specific new builtin functions.
|
|
832
|
+
2. **Replace `@cImport`** with `addTranslateC` in `build.zig`.
|
|
833
|
+
3. **Add `fingerprint` and fix `name`** in `build.zig.zon`.
|
|
834
|
+
4. **Thread `std.Io` through your app** — any function doing I/O, sleep, random, or time needs an `io` parameter.
|
|
835
|
+
5. **Update `std.net` usages** to `std.Io.net` or raw syscalls.
|
|
836
|
+
6. **Update `ArrayList` calls** to pass allocator explicitly and use `initCapacity`.
|
|
837
|
+
7. **Fix error set names** (CrossDevice, FileBusy, EnvironmentVariableMissing, DirNotEmpty).
|
|
838
|
+
8. **Run `zig build test --test-timeout 500ms`** to catch hanging tests early.
|
|
839
|
+
|
|
840
|
+
Use this skill when writing new Zig 0.16.0 code or upgrading from 0.15.x.
|