@vzn/vx 0.0.650 → 0.0.652
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/README.md +7 -23
- package/package.json +5 -5
- package/schemas/last.json +15 -0
- package/schemas/show.json +14 -20
- package/src/bin.ts +21 -31
- package/src/cache/archive.ts +1 -1
- package/src/cache/cache.ts +221 -30
- package/src/cache/file-hashes.ts +3 -0
- package/src/cache/git-inputs.ts +188 -39
- package/src/cache/history-stream.ts +134 -0
- package/src/cache/history-writer.ts +76 -0
- package/src/cache/index.ts +3 -0
- package/src/cache/inputs.ts +77 -14
- package/src/cache/layer.ts +17 -6
- package/src/cache/layered-cache.ts +4 -0
- package/src/cache/linked-inputs.ts +3 -0
- package/src/cache/lockfile-memo.ts +5 -3
- package/src/cache/output-index.ts +5 -2
- package/src/cache/remote-lane.ts +2 -1
- package/src/cache/run-history.ts +56 -17
- package/src/cache/schema.ts +15 -2
- package/src/cli/cache.ts +28 -18
- package/src/cli/completions.ts +4 -2
- package/src/cli/docs.ts +10 -11
- package/src/cli/help.ts +14 -25
- package/src/cli/index.ts +28 -9
- package/src/cli/info.ts +16 -8
- package/src/cli/init.ts +23 -15
- package/src/cli/last.ts +246 -204
- package/src/cli/lock.ts +55 -5
- package/src/cli/plan-format.ts +100 -118
- package/src/cli/plugin-commands.ts +8 -2
- package/src/cli/plugin-templates.ts +36 -45
- package/src/cli/run.ts +46 -27
- package/src/cli/select.ts +43 -5
- package/src/cli/show.ts +45 -52
- package/src/cli/task-verb.ts +22 -0
- package/src/cli/upgrade.ts +3 -1
- package/src/cli/watch-fs.ts +6 -1
- package/src/cli/watch-judge.ts +3 -2
- package/src/cli/watch-set.ts +4 -4
- package/src/cli/watch.ts +94 -52
- package/src/cli/why.ts +123 -89
- package/src/cli/workspace-config.ts +2 -1
- package/src/config.ts +47 -30
- package/src/exec/executor.ts +42 -2
- package/src/exec/index.ts +1 -0
- package/src/exec/kill-tree.ts +58 -5
- package/src/exec/local-executor.ts +1 -1
- package/src/exec/pipes.ts +152 -0
- package/src/exec/runner.ts +199 -182
- package/src/exec/sandbox-binds.ts +1 -1
- package/src/exec/sandbox-paths.ts +3 -1
- package/src/exec/sandbox-runtime.ts +317 -23
- package/src/exec/spawn-off.ts +154 -0
- package/src/exec/task-proxy.ts +93 -0
- package/src/exec/warm-shell.ts +146 -0
- package/src/graph/critical-path.ts +40 -28
- package/src/graph/definition.ts +16 -3
- package/src/graph/priorities.ts +98 -44
- package/src/graph/scheduler.ts +17 -11
- package/src/graph/task-graph.ts +51 -24
- package/src/handoff.ts +10 -7
- package/src/history/failure-mode.ts +24 -1
- package/src/history/history.ts +5 -0
- package/src/history/index.ts +1 -0
- package/src/history/metrics.ts +14 -6
- package/src/index.ts +7 -3
- package/src/orchestrator/admission.ts +1 -1
- package/src/orchestrator/command-windows.ts +1 -1
- package/src/orchestrator/deferred-outputs.ts +1 -1
- package/src/orchestrator/doctor.ts +1 -1
- package/src/orchestrator/download-policy.ts +5 -7
- package/src/orchestrator/excluded-keys.ts +1 -1
- package/src/orchestrator/execute-task.ts +67 -20
- package/src/orchestrator/graph-memo.ts +50 -1
- package/src/orchestrator/graph-stage.ts +6 -0
- package/src/orchestrator/hit-restore.ts +5 -6
- package/src/orchestrator/index.ts +3 -0
- package/src/orchestrator/keyed-projects.ts +28 -0
- package/src/orchestrator/live-usage.ts +16 -11
- package/src/orchestrator/local-shortcircuit.ts +2 -2
- package/src/orchestrator/locked-digests.ts +63 -0
- package/src/orchestrator/lockfile-claim.ts +108 -29
- package/src/orchestrator/miss-save.ts +58 -11
- package/src/orchestrator/persistent-task.ts +5 -1
- package/src/orchestrator/placement.ts +1 -1
- package/src/orchestrator/plan.ts +7 -3
- package/src/orchestrator/plugin-host.ts +67 -2
- package/src/orchestrator/plugin.ts +53 -2
- package/src/orchestrator/prepare.ts +16 -1
- package/src/orchestrator/projects.ts +4 -1
- package/src/orchestrator/remote-prefetch.ts +1 -1
- package/src/orchestrator/run-context.ts +29 -10
- package/src/orchestrator/run-failures.ts +62 -13
- package/src/orchestrator/run-keys.ts +1 -1
- package/src/orchestrator/run-records.ts +88 -59
- package/src/orchestrator/run-report.ts +1 -1
- package/src/orchestrator/run.ts +145 -41
- package/src/orchestrator/sandbox-request.ts +52 -9
- package/src/orchestrator/shell-verdict.ts +9 -0
- package/src/orchestrator/signals.ts +8 -5
- package/src/orchestrator/stable-keys.ts +17 -18
- package/src/orchestrator/task-artifacts.ts +1 -1
- package/src/orchestrator/task-hash.ts +21 -7
- package/src/orchestrator/telemetry.ts +5 -1
- package/src/report/events.ts +6 -14
- package/src/report/forecast.ts +10 -32
- package/src/report/framed-output.ts +283 -175
- package/src/report/index.ts +8 -3
- package/src/report/logger.ts +74 -39
- package/src/report/plain-output.ts +3 -1
- package/src/report/status-line.ts +49 -357
- package/src/report/summary.ts +105 -136
- package/src/settings.ts +8 -8
- package/src/ui/ansi.ts +48 -0
- package/src/ui/components.ts +506 -0
- package/src/ui/index.ts +79 -0
- package/src/ui/kit.ts +37 -0
- package/src/ui/live-region.ts +363 -0
- package/src/{util/refusal-notice.ts → ui/refusal.ts} +7 -5
- package/src/ui/terminal.ts +51 -0
- package/src/ui/theme.ts +224 -0
- package/src/ui/version-line.ts +28 -0
- package/src/util/config-frame.ts +191 -14
- package/src/util/edit-distance.ts +6 -1
- package/src/util/index.ts +2 -15
- package/src/util/paths.ts +21 -3
- package/src/util/secret-mask.ts +39 -3
- package/src/util/settle.ts +33 -1
- package/src/util/tail.ts +4 -1
- package/src/util/timing.ts +4 -16
- package/src/workspace/affected.ts +89 -30
- package/src/workspace/bracket-literal.ts +2 -2
- package/src/workspace/config-schema.ts +70 -63
- package/src/workspace/dependencies-lock.ts +191 -0
- package/src/workspace/filter.ts +36 -1
- package/src/workspace/index.ts +9 -0
- package/src/workspace/lockfile.ts +159 -6
- package/src/workspace/migration.ts +16 -9
- package/src/workspace/workspace.ts +3 -0
- package/src/util/colors.ts +0 -133
- package/src/util/report.ts +0 -44
- package/src/util/ui.ts +0 -258
- /package/src/{report/path-links.ts → ui/links.ts} +0 -0
- /package/src/{report → ui}/terminal-signals.ts +0 -0
package/README.md
CHANGED
|
@@ -47,9 +47,8 @@ export default defineProject({
|
|
|
47
47
|
exec: { command: 'tsc -b' },
|
|
48
48
|
dependsOn: ['^build'], // dependencies build first
|
|
49
49
|
inputs: { files: ['src/**', 'tsconfig.json'] },
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
},
|
|
50
|
+
outputs: { files: ['dist/**'] },
|
|
51
|
+
cache: true,
|
|
53
52
|
},
|
|
54
53
|
},
|
|
55
54
|
})
|
|
@@ -142,9 +141,8 @@ not a way to run the repo. The benchmark below uses native vx config.
|
|
|
142
141
|
| Plugin API | **Yes**: every pipeline stage | No | Yes (TS-tied) |
|
|
143
142
|
| Install | **Single binary**; no Bun, Node optional | npm + Node | npm + Node |
|
|
144
143
|
|
|
145
|
-
Every gap
|
|
146
|
-
[
|
|
147
|
-
[vx, Turborepo, Nx, Bazel](https://vznjs.github.io/vx/compare/).
|
|
144
|
+
Every gap: [comparison](packages/vx/docs/comparison.md) ·
|
|
145
|
+
every tool on one suite of cases: [conformance](https://vznjs.github.io/vx/conformance/).
|
|
148
146
|
|
|
149
147
|
## Fast, without trading correctness
|
|
150
148
|
|
|
@@ -152,23 +150,9 @@ Every gap, and when another tool is the better pick:
|
|
|
152
150
|
- **No source-file reads to hash:** on a clean tree, keys come from git's index; each project's `package.json` and the lockfile are still read.
|
|
153
151
|
- **One pass:** one git walk per run; each stat and lookup happens once.
|
|
154
152
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
| ---------------------------------------------------------- | ---------- | ---------- | ---------- | --------- |
|
|
159
|
-
| Nothing changed | **799 ms** | 927 ms | 24.15 s | 12.07 s |
|
|
160
|
-
| Nothing changed, outputs restored | **1.28 s** | 2.01 s | 24.45 s | 11.86 s |
|
|
161
|
-
| Cold build | **7.57 s** | 9.63 s | 3 min 6 s | 9.01 s |
|
|
162
|
-
| Cold build: CPU the runner burns | 36.64 s | 1 min 12 s | 5 min 34 s | 25.32 s |
|
|
163
|
-
|
|
164
|
-
Time each tool adds over the ideal run; lower is better.
|
|
165
|
-
|
|
166
|
-
Benchmark workload: a synthetic monorepo of 1,601 projects and 9,603 tasks in 30 dependency levels, five core libraries a quarter of the projects use; build 300 ms, test and typecheck 150 ms, lint 75 ms, publish 30 ms; real repos with uneven task times will differ.
|
|
167
|
-
Run 2026-10-25 on linux x64, 4 cores: vx at commit 9abdfb52c, Turborepo 2.11.10, Nx 24.0.1, Vite Task (vite-plus) 1.4.0.
|
|
168
|
-
|
|
169
|
-
Same graph, commands and concurrency: [how it is measured](https://vznjs.github.io/vx/benchmarks/).
|
|
170
|
-
|
|
171
|
-
<!-- bench:end -->
|
|
153
|
+
The head-to-head against Turborepo, Nx and Vite Task, each in its own
|
|
154
|
+
native config, is re-measured on every change to vx and published on the
|
|
155
|
+
site: [benchmarks](https://vznjs.github.io/vx/benchmarks/).
|
|
172
156
|
|
|
173
157
|
## Status
|
|
174
158
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vzn/vx",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.652",
|
|
4
4
|
"description": "Task orchestration you own: correct, sandboxed, extensible, with a content-addressed build cache.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
"node": ">=18"
|
|
22
22
|
},
|
|
23
23
|
"optionalDependencies": {
|
|
24
|
-
"@vzn/vx-linux-x64": "0.0.
|
|
25
|
-
"@vzn/vx-linux-arm64": "0.0.
|
|
26
|
-
"@vzn/vx-darwin-x64": "0.0.
|
|
27
|
-
"@vzn/vx-darwin-arm64": "0.0.
|
|
24
|
+
"@vzn/vx-linux-x64": "0.0.652",
|
|
25
|
+
"@vzn/vx-linux-arm64": "0.0.652",
|
|
26
|
+
"@vzn/vx-darwin-x64": "0.0.652",
|
|
27
|
+
"@vzn/vx-darwin-arm64": "0.0.652"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@anthropic-ai/sandbox-runtime": "^0.0.76"
|
package/schemas/last.json
CHANGED
|
@@ -242,7 +242,10 @@
|
|
|
242
242
|
"peakRssBytes",
|
|
243
243
|
"peakCores",
|
|
244
244
|
"avgRssBytes",
|
|
245
|
+
"queuedMs",
|
|
245
246
|
"placement",
|
|
247
|
+
"outputBytes",
|
|
248
|
+
"blocks",
|
|
246
249
|
"wallclockStartNs",
|
|
247
250
|
"wallclockEndNs",
|
|
248
251
|
"blockedBy",
|
|
@@ -288,10 +291,22 @@
|
|
|
288
291
|
"type": ["integer", "null"],
|
|
289
292
|
"description": "mean resident memory over the samples; null when nothing sampled"
|
|
290
293
|
},
|
|
294
|
+
"queuedMs": {
|
|
295
|
+
"type": ["integer", "null"],
|
|
296
|
+
"description": "milliseconds it waited, ready, for a slot; null when it never queued"
|
|
297
|
+
},
|
|
291
298
|
"placement": {
|
|
292
299
|
"type": ["string", "null"],
|
|
293
300
|
"description": "where an executor ran it (small#1); null when here"
|
|
294
301
|
},
|
|
302
|
+
"outputBytes": {
|
|
303
|
+
"type": ["integer", "null"],
|
|
304
|
+
"description": "bytes of its outputs: what its save stored, or its hit restored"
|
|
305
|
+
},
|
|
306
|
+
"blocks": {
|
|
307
|
+
"type": ["integer", "null"],
|
|
308
|
+
"description": "how many tasks were downstream of it"
|
|
309
|
+
},
|
|
295
310
|
"wallclockStartNs": {
|
|
296
311
|
"type": ["string", "null"],
|
|
297
312
|
"description": "decimal nanoseconds from the run's start"
|
package/schemas/show.json
CHANGED
|
@@ -109,25 +109,8 @@
|
|
|
109
109
|
"env": { "$ref": "#/$defs/stringList" },
|
|
110
110
|
"tasks": { "$ref": "#/$defs/stringList" },
|
|
111
111
|
"runtime": { "$ref": "#/$defs/stringList" },
|
|
112
|
-
"workspaceRuntime": { "$ref": "#/$defs/stringList" }
|
|
113
|
-
|
|
114
|
-
},
|
|
115
|
-
"cache": {
|
|
116
|
-
"type": "object",
|
|
117
|
-
"additionalProperties": false,
|
|
118
|
-
"required": ["outputs"],
|
|
119
|
-
"properties": {
|
|
120
|
-
"outputs": {
|
|
121
|
-
"type": "object",
|
|
122
|
-
"additionalProperties": false,
|
|
123
|
-
"required": ["files"],
|
|
124
|
-
"properties": {
|
|
125
|
-
"files": { "$ref": "#/$defs/stringList" },
|
|
126
|
-
"workspaceFiles": { "$ref": "#/$defs/stringList" },
|
|
127
|
-
"clean": { "type": "boolean" }
|
|
128
|
-
}
|
|
129
|
-
},
|
|
130
|
-
"inputStability": {
|
|
112
|
+
"workspaceRuntime": { "$ref": "#/$defs/stringList" },
|
|
113
|
+
"stability": {
|
|
131
114
|
"type": "object",
|
|
132
115
|
"additionalProperties": false,
|
|
133
116
|
"properties": {
|
|
@@ -136,7 +119,18 @@
|
|
|
136
119
|
}
|
|
137
120
|
}
|
|
138
121
|
}
|
|
139
|
-
}
|
|
122
|
+
},
|
|
123
|
+
"outputs": {
|
|
124
|
+
"type": "object",
|
|
125
|
+
"additionalProperties": false,
|
|
126
|
+
"required": ["files"],
|
|
127
|
+
"properties": {
|
|
128
|
+
"files": { "$ref": "#/$defs/stringList" },
|
|
129
|
+
"workspaceFiles": { "$ref": "#/$defs/stringList" },
|
|
130
|
+
"clean": { "type": "boolean" }
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
"cache": { "type": "boolean" }
|
|
140
134
|
}
|
|
141
135
|
}
|
|
142
136
|
}
|
package/src/bin.ts
CHANGED
|
@@ -21,32 +21,14 @@ async function main(): Promise<void> {
|
|
|
21
21
|
// `vx --version` needs one leaf module; the dispatcher and the util
|
|
22
22
|
// barrel it pulled in were 20 ms of its 28 (2026-10-01).
|
|
23
23
|
if (argv.length === 1 && (argv[0] === '--version' || argv[0] === 'version')) {
|
|
24
|
-
// `Bun.stdout`, not `process.stdout`: the Node stream's first touch is
|
|
25
|
-
// ~7 ms, half of this verb (2026-10-02). A reader gone (EPIPE) is no
|
|
26
|
-
// failure of the line.
|
|
27
24
|
// Handed off, it says which vx ran and which one handed it the call.
|
|
28
25
|
const from = process.env['VX_HANDED_OFF'] || undefined
|
|
29
26
|
const where = from === undefined ? '' : ` (${vxPath()}, handed off from ${from})`
|
|
30
|
-
|
|
31
|
-
// Decided here, not by util's `detectColors`: the util barrel was the
|
|
32
|
-
// 20 ms above, and `node:tty` 17 ms; fd 1 as a character device is the
|
|
33
|
-
// TTY answer. A CI's log is not painted for this one line.
|
|
34
|
-
const [{ VERSION }, { fstatSync }] = await Promise.all([
|
|
27
|
+
const [{ VERSION }, { printVersion }] = await Promise.all([
|
|
35
28
|
import('./version.js'),
|
|
36
|
-
import('
|
|
29
|
+
import('./ui/version-line.js'),
|
|
37
30
|
])
|
|
38
|
-
|
|
39
|
-
const on = env['NO_COLOR']
|
|
40
|
-
? false
|
|
41
|
-
: env['FORCE_COLOR'] !== undefined
|
|
42
|
-
? env['FORCE_COLOR'] !== '0' && env['FORCE_COLOR'] !== 'false'
|
|
43
|
-
: env['TERM'] !== 'dumb' && fstatSync(1).isCharacterDevice()
|
|
44
|
-
const sgr = (code: string, text: string): string =>
|
|
45
|
-
on ? `\x1b[${code}m${text}\x1b[0m` : text
|
|
46
|
-
await Bun.write(
|
|
47
|
-
Bun.stdout,
|
|
48
|
-
`${sgr('1', 'vx')} ${sgr('38;2;6;182;212', VERSION)}${where === '' ? '' : sgr('2', where)}\n`,
|
|
49
|
-
).catch(() => {})
|
|
31
|
+
await printVersion(VERSION, where)
|
|
50
32
|
settled = true
|
|
51
33
|
return
|
|
52
34
|
}
|
|
@@ -64,8 +46,9 @@ async function main(): Promise<void> {
|
|
|
64
46
|
// is set, and `exitOnceFlushed` exits after both streams have ended.
|
|
65
47
|
process.exitCode = code
|
|
66
48
|
} catch (err) {
|
|
49
|
+
const ui = await import('./ui/index.js')
|
|
50
|
+
const { refusalNotice } = ui
|
|
67
51
|
const {
|
|
68
|
-
detectColors,
|
|
69
52
|
errorCode,
|
|
70
53
|
errorDocument,
|
|
71
54
|
fsRefusalHint,
|
|
@@ -74,17 +57,12 @@ async function main(): Promise<void> {
|
|
|
74
57
|
isUserError,
|
|
75
58
|
maskedLine,
|
|
76
59
|
OUT_OF_FDS_HINT,
|
|
77
|
-
refusalNotice,
|
|
78
|
-
ui,
|
|
79
60
|
wantsJson,
|
|
80
61
|
} = await import('./util/index.js')
|
|
81
62
|
// A plugin's failure quotes what it was told (a remote's reply, a
|
|
82
63
|
// header), and a config's own throw is its author's text: a secret in
|
|
83
64
|
// either reached stderr whole (L-11).
|
|
84
|
-
const say = (line: string): void =>
|
|
85
|
-
void process.stderr.write(
|
|
86
|
-
`${ui.tagged('error', maskedLine(line), detectColors(process.stderr))}\n`,
|
|
87
|
-
)
|
|
65
|
+
const say = (line: string): void => ui.say('error', maskedLine(line))
|
|
88
66
|
// UserError (workspace not found, cycle, config invalid, ...) —
|
|
89
67
|
// print the message only; the stack is noise the user can't act
|
|
90
68
|
// on. Everything else gets the full stack so internal bugs are
|
|
@@ -100,7 +78,11 @@ async function main(): Promise<void> {
|
|
|
100
78
|
named === null ? err.message : err.message.slice(named[0].length),
|
|
101
79
|
err.parts,
|
|
102
80
|
)
|
|
103
|
-
|
|
81
|
+
ui.data('err', maskedLine(ui.render([block], ui.colorsOf('err'))))
|
|
82
|
+
} else if (cwdGone(err)) {
|
|
83
|
+
// Removed under the shell (a checkout of another branch, `rm -rf` in
|
|
84
|
+
// another): every verb starts from the cwd.
|
|
85
|
+
say('vx: the current directory no longer exists — cd into the workspace again and re-run\n')
|
|
104
86
|
} else if (isOutOfFds(err)) {
|
|
105
87
|
say(`vx: ${err.message} — ${OUT_OF_FDS_HINT}\n`)
|
|
106
88
|
} else if (isFsRefusal(err)) {
|
|
@@ -114,7 +96,7 @@ async function main(): Promise<void> {
|
|
|
114
96
|
// stdout got nothing to parse, and only prose on stderr to branch on.
|
|
115
97
|
if (wantsJson(argv)) {
|
|
116
98
|
const message = err instanceof Error ? err.message : String(err)
|
|
117
|
-
|
|
99
|
+
ui.data('out', errorDocument(errorCode(err), maskedLine(message)))
|
|
118
100
|
}
|
|
119
101
|
// Same reason as the success path above: a large stderr is truncated by
|
|
120
102
|
// `process.exit` too, and an error message cut in half is the one a
|
|
@@ -174,13 +156,21 @@ function withCauses(err: unknown): string {
|
|
|
174
156
|
process.on('beforeExit', () => {
|
|
175
157
|
if (settled) return
|
|
176
158
|
settled = true
|
|
177
|
-
;(require('./
|
|
159
|
+
;(require('./ui/index.js') as typeof import('./ui/index.js')).say(
|
|
178
160
|
'error',
|
|
179
161
|
'vx: the run stopped before it finished: something it awaited can never settle (a plugin hook?)',
|
|
180
162
|
)
|
|
181
163
|
process.exitCode = 1
|
|
182
164
|
})
|
|
183
165
|
|
|
166
|
+
/** `process.cwd()`'s refusal of a directory removed under the process. */
|
|
167
|
+
function cwdGone(err: unknown): boolean {
|
|
168
|
+
return (
|
|
169
|
+
(err as NodeJS.ErrnoException | null)?.code === 'ENOENT' &&
|
|
170
|
+
/\buv_cwd\b/.test((err as Error).message)
|
|
171
|
+
)
|
|
172
|
+
}
|
|
173
|
+
|
|
184
174
|
// A reader that leaves is not the run's failure. `vx run build | head -1`
|
|
185
175
|
// closes the pipe after one line; every later write gets EPIPE, which Bun
|
|
186
176
|
// raises as an `error` event on the stream, and an `error` nobody listens
|
package/src/cache/archive.ts
CHANGED
|
@@ -350,7 +350,7 @@ export async function planArtifact(args: PackArgs): Promise<ArtifactPlan> {
|
|
|
350
350
|
}
|
|
351
351
|
if (!st.isFile()) {
|
|
352
352
|
throw new UserError(
|
|
353
|
-
`${shown} is not a regular file: vx stores regular files and symlinks only — emit a file there, or narrow
|
|
353
|
+
`${shown} is not a regular file: vx stores regular files and symlinks only — emit a file there, or narrow outputs.files to the files the task produces, or take it back with a '!' entry`,
|
|
354
354
|
)
|
|
355
355
|
}
|
|
356
356
|
const mode = st.mode & 0o777
|