phonton-cli 0.9.0 → 0.9.1
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 +4 -4
- package/npm/bin/phonton.js +48 -2
- package/npm/install.js +15 -0
- package/npm/test-wrapper.js +69 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<img src="assets/readme/phonton-cli-logo.png" width="112" alt="Phonton CLI logo">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
<h1 align="center">Phonton CLI · v0.9.
|
|
5
|
+
<h1 align="center">Phonton CLI · v0.9.1</h1>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<strong>Verified code changes with repo memory.</strong><br>
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<p align="center">
|
|
13
13
|
<a href="https://github.com/phonton-dev/phonton-cli/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/phonton-dev/phonton-cli/actions/workflows/ci.yml/badge.svg"></a>
|
|
14
14
|
<a href="https://github.com/phonton-dev/phonton-cli/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/phonton-dev/phonton-cli?style=flat&label=stars"></a>
|
|
15
|
-
<img alt="release" src="https://img.shields.io/badge/release-v0.9.
|
|
15
|
+
<img alt="release" src="https://img.shields.io/badge/release-v0.9.1-6c63ff">
|
|
16
16
|
<img alt="license" src="https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue">
|
|
17
17
|
<img alt="status" src="https://img.shields.io/badge/status-public_alpha-f97316">
|
|
18
18
|
</p>
|
|
@@ -135,7 +135,7 @@ Windows PowerShell:
|
|
|
135
135
|
Direct Cargo install:
|
|
136
136
|
|
|
137
137
|
```bash
|
|
138
|
-
cargo install --git https://github.com/phonton-dev/phonton-cli --tag v0.9.
|
|
138
|
+
cargo install --git https://github.com/phonton-dev/phonton-cli --tag v0.9.1 phonton-cli --locked --force
|
|
139
139
|
```
|
|
140
140
|
|
|
141
141
|
Check the install:
|
|
@@ -151,7 +151,7 @@ Phonton uses GitHub branches and releases as install channels:
|
|
|
151
151
|
|
|
152
152
|
| Channel | Install | Use when |
|
|
153
153
|
|---|---|---|
|
|
154
|
-
| Stable | `cargo install --git https://github.com/phonton-dev/phonton-cli --tag v0.9.
|
|
154
|
+
| Stable | `cargo install --git https://github.com/phonton-dev/phonton-cli --tag v0.9.1 phonton-cli --locked --force` | You want the best validated public alpha |
|
|
155
155
|
| Dev | `cargo install --git https://github.com/phonton-dev/phonton-cli --branch dev phonton-cli --locked --force` | You want next-release integration changes |
|
|
156
156
|
| Nightly | `cargo install --git https://github.com/phonton-dev/phonton-cli --branch nightly phonton-cli --locked --force` | You want daily snapshots and can tolerate breakage |
|
|
157
157
|
| Main | `cargo install --git https://github.com/phonton-dev/phonton-cli --branch main phonton-cli --locked --force` | You want the current release branch tip |
|
package/npm/bin/phonton.js
CHANGED
|
@@ -4,14 +4,18 @@ const fs = require("fs");
|
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const { spawn, spawnSync } = require("child_process");
|
|
6
6
|
|
|
7
|
+
const packageJson = require("../../package.json");
|
|
7
8
|
const binaryName = process.platform === "win32" ? "phonton.exe" : "phonton";
|
|
8
9
|
const configuredBinary = process.env.PHONTON_BINARY || process.env.PHONTON_CLI_BINARY;
|
|
9
10
|
const binaryPath = configuredBinary
|
|
10
11
|
? path.resolve(configuredBinary)
|
|
11
12
|
: path.join(__dirname, "..", "vendor", binaryName);
|
|
13
|
+
const vendorDir = path.join(__dirname, "..", "vendor");
|
|
14
|
+
const markerPath = path.join(vendorDir, "version.json");
|
|
12
15
|
|
|
13
16
|
function ensureBinary() {
|
|
14
|
-
if (fs.existsSync(binaryPath)) {
|
|
17
|
+
if (configuredBinary && fs.existsSync(binaryPath)) {
|
|
18
|
+
assertBinaryVersion(binaryPath);
|
|
15
19
|
return;
|
|
16
20
|
}
|
|
17
21
|
|
|
@@ -20,11 +24,53 @@ function ensureBinary() {
|
|
|
20
24
|
process.exit(1);
|
|
21
25
|
}
|
|
22
26
|
|
|
23
|
-
|
|
27
|
+
if (fs.existsSync(binaryPath) && vendorMatchesPackage() && binaryVersionMatches(binaryPath).ok) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
fs.rmSync(vendorDir, { recursive: true, force: true });
|
|
32
|
+
|
|
33
|
+
const installScript = process.env.PHONTON_INSTALL_SCRIPT || path.join(__dirname, "..", "install.js");
|
|
24
34
|
const result = spawnSync(process.execPath, [installScript], { stdio: "inherit" });
|
|
25
35
|
if (result.status !== 0 || !fs.existsSync(binaryPath)) {
|
|
26
36
|
process.exit(result.status || 1);
|
|
27
37
|
}
|
|
38
|
+
assertBinaryVersion(binaryPath);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function vendorMatchesPackage() {
|
|
42
|
+
try {
|
|
43
|
+
const marker = JSON.parse(fs.readFileSync(markerPath, "utf8"));
|
|
44
|
+
return (
|
|
45
|
+
marker.version === packageJson.version &&
|
|
46
|
+
marker.platform === process.platform &&
|
|
47
|
+
marker.arch === process.arch
|
|
48
|
+
);
|
|
49
|
+
} catch (_error) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function assertBinaryVersion(candidate) {
|
|
55
|
+
const check = binaryVersionMatches(candidate);
|
|
56
|
+
if (!check.ok) {
|
|
57
|
+
console.error(`Installed Phonton binary is stale or invalid: expected ${check.expected}, got ${check.output}`);
|
|
58
|
+
if (!configuredBinary) {
|
|
59
|
+
fs.rmSync(vendorDir, { recursive: true, force: true });
|
|
60
|
+
}
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function binaryVersionMatches(candidate) {
|
|
66
|
+
const result = spawnSync(candidate, ["version"], { encoding: "utf8" });
|
|
67
|
+
const output = `${result.stdout || ""}${result.stderr || ""}`.trim() || "no output";
|
|
68
|
+
const expected = `phonton ${packageJson.version}`;
|
|
69
|
+
return {
|
|
70
|
+
ok: result.status === 0 && output.includes(expected),
|
|
71
|
+
expected,
|
|
72
|
+
output,
|
|
73
|
+
};
|
|
28
74
|
}
|
|
29
75
|
|
|
30
76
|
ensureBinary();
|
package/npm/install.js
CHANGED
|
@@ -12,6 +12,7 @@ const repo = "phonton-dev/phonton-cli";
|
|
|
12
12
|
const version = packageJson.version;
|
|
13
13
|
const tag = process.env.PHONTON_RELEASE_TAG || (version.includes("nightly") ? "nightly" : `v${version}`);
|
|
14
14
|
const vendorDir = path.join(__dirname, "vendor");
|
|
15
|
+
const markerPath = path.join(vendorDir, "version.json");
|
|
15
16
|
|
|
16
17
|
const targets = {
|
|
17
18
|
"linux-x64": {
|
|
@@ -55,6 +56,20 @@ download(url, archivePath)
|
|
|
55
56
|
if (process.platform !== "win32") {
|
|
56
57
|
fs.chmodSync(binaryPath, 0o755);
|
|
57
58
|
}
|
|
59
|
+
fs.writeFileSync(
|
|
60
|
+
markerPath,
|
|
61
|
+
`${JSON.stringify(
|
|
62
|
+
{
|
|
63
|
+
version,
|
|
64
|
+
tag,
|
|
65
|
+
asset: target.asset,
|
|
66
|
+
platform: process.platform,
|
|
67
|
+
arch: process.arch,
|
|
68
|
+
},
|
|
69
|
+
null,
|
|
70
|
+
2,
|
|
71
|
+
)}\n`,
|
|
72
|
+
);
|
|
58
73
|
console.log(`Installed Phonton CLI ${tag} for ${process.platform}-${process.arch}`);
|
|
59
74
|
})
|
|
60
75
|
.catch((error) => {
|
package/npm/test-wrapper.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const fs = require("fs");
|
|
4
|
+
const os = require("os");
|
|
4
5
|
const path = require("path");
|
|
5
6
|
const { spawnSync } = require("child_process");
|
|
6
7
|
|
|
@@ -46,6 +47,8 @@ if (!versionOutput.includes(expected)) {
|
|
|
46
47
|
process.exit(1);
|
|
47
48
|
}
|
|
48
49
|
|
|
50
|
+
testStaleVendorReinstall();
|
|
51
|
+
|
|
49
52
|
const goal = "add input validation to config loading";
|
|
50
53
|
const planOutput = runWrapper(["plan", "--json", "--no-memory", goal]);
|
|
51
54
|
let planJson;
|
|
@@ -65,3 +68,69 @@ if (planJson.goal_contract.goal !== goal) {
|
|
|
65
68
|
console.error("Expected plan --json goal_contract.goal to match the requested goal.");
|
|
66
69
|
process.exit(1);
|
|
67
70
|
}
|
|
71
|
+
|
|
72
|
+
function testStaleVendorReinstall() {
|
|
73
|
+
const vendorDir = path.join(root, "npm", "vendor");
|
|
74
|
+
const vendorBinary = path.join(vendorDir, binaryName);
|
|
75
|
+
const markerPath = path.join(vendorDir, "version.json");
|
|
76
|
+
const installScript = path.join(os.tmpdir(), `phonton-test-install-${process.pid}.js`);
|
|
77
|
+
|
|
78
|
+
fs.rmSync(vendorDir, { recursive: true, force: true });
|
|
79
|
+
fs.mkdirSync(vendorDir, { recursive: true });
|
|
80
|
+
fs.copyFileSync(binary, vendorBinary);
|
|
81
|
+
if (process.platform !== "win32") {
|
|
82
|
+
fs.chmodSync(vendorBinary, 0o755);
|
|
83
|
+
}
|
|
84
|
+
fs.writeFileSync(
|
|
85
|
+
markerPath,
|
|
86
|
+
JSON.stringify({
|
|
87
|
+
version: "0.0.0-stale",
|
|
88
|
+
platform: process.platform,
|
|
89
|
+
arch: process.arch,
|
|
90
|
+
}),
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
fs.writeFileSync(
|
|
94
|
+
installScript,
|
|
95
|
+
`
|
|
96
|
+
const fs = require("fs");
|
|
97
|
+
const path = require("path");
|
|
98
|
+
const vendorDir = ${JSON.stringify(vendorDir)};
|
|
99
|
+
const binary = ${JSON.stringify(binary)};
|
|
100
|
+
const binaryName = ${JSON.stringify(binaryName)};
|
|
101
|
+
const version = ${JSON.stringify(packageJson.version)};
|
|
102
|
+
fs.mkdirSync(vendorDir, { recursive: true });
|
|
103
|
+
fs.copyFileSync(binary, path.join(vendorDir, binaryName));
|
|
104
|
+
if (process.platform !== "win32") fs.chmodSync(path.join(vendorDir, binaryName), 0o755);
|
|
105
|
+
fs.writeFileSync(path.join(vendorDir, "version.json"), JSON.stringify({
|
|
106
|
+
version,
|
|
107
|
+
platform: process.platform,
|
|
108
|
+
arch: process.arch,
|
|
109
|
+
}, null, 2));
|
|
110
|
+
`,
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
const result = spawnSync(process.execPath, [path.join(root, "npm", "bin", "phonton.js"), "version"], {
|
|
115
|
+
cwd: root,
|
|
116
|
+
encoding: "utf8",
|
|
117
|
+
env: {
|
|
118
|
+
...process.env,
|
|
119
|
+
PHONTON_INSTALL_SCRIPT: installScript,
|
|
120
|
+
PHONTON_BINARY: "",
|
|
121
|
+
PHONTON_CLI_BINARY: "",
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
process.stdout.write(result.stdout || "");
|
|
126
|
+
process.stderr.write(result.stderr || "");
|
|
127
|
+
|
|
128
|
+
if (result.status !== 0 || !result.stdout.includes(expected)) {
|
|
129
|
+
console.error("Expected npm wrapper to refresh stale vendor binary metadata.");
|
|
130
|
+
process.exit(result.status || 1);
|
|
131
|
+
}
|
|
132
|
+
} finally {
|
|
133
|
+
fs.rmSync(installScript, { force: true });
|
|
134
|
+
fs.rmSync(vendorDir, { recursive: true, force: true });
|
|
135
|
+
}
|
|
136
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "phonton-cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Local-first agentic development terminal with context packs, source handles, and verification gates.",
|
|
5
5
|
"license": "MIT OR Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/phonton-dev/phonton-cli#readme",
|