@ai-agent-tools/picgen 0.1.0-alpha.0 → 0.1.0-alpha.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 +15 -0
- package/dist/cli.js +141 -2
- package/docs/release-alpha.md +12 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,6 +44,7 @@ For first-user rollout, see [docs/release-alpha.md](./docs/release-alpha.md).
|
|
|
44
44
|
```bash
|
|
45
45
|
picgen setup
|
|
46
46
|
picgen quickstart
|
|
47
|
+
picgen update check
|
|
47
48
|
picgen doctor --json
|
|
48
49
|
picgen create --dry-run "一张产品发布会主视觉"
|
|
49
50
|
picgen create --yes "一张产品发布会主视觉"
|
|
@@ -103,3 +104,17 @@ Providers may optionally set `test_model` in `~/.picgen/config.yaml` when health
|
|
|
103
104
|
Providers expose capabilities such as `text-to-image` and `reference-image`. Old configs that omit capabilities are upgraded in memory from the provider protocol: Gemini supports both text and reference-image generation, while OpenAI-compatible `/v1/images/generations` supports text-to-image only.
|
|
104
105
|
|
|
105
106
|
Generated image data and provider-only fields such as base64 image payloads and Gemini thought signatures are redacted from metadata. PicGen keeps the generated assets as local image files and keeps stdout compact for agent workflows.
|
|
107
|
+
|
|
108
|
+
## Updates
|
|
109
|
+
|
|
110
|
+
Check npm for the latest PicGen version:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
picgen update check
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`picgen doctor` and `picgen quickstart` may show a lightweight update hint. PicGen caches update checks for 24 hours. Disable update checks with:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
PICGEN_DISABLE_UPDATE_CHECK=1 picgen doctor
|
|
120
|
+
```
|
package/dist/cli.js
CHANGED
|
@@ -992,6 +992,140 @@ function inspectProviders(config) {
|
|
|
992
992
|
});
|
|
993
993
|
}
|
|
994
994
|
|
|
995
|
+
// src/commands/update.ts
|
|
996
|
+
import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
|
|
997
|
+
import { dirname as dirname2, join as join4 } from "path";
|
|
998
|
+
import { homedir as homedir2 } from "os";
|
|
999
|
+
|
|
1000
|
+
// src/version.ts
|
|
1001
|
+
var PACKAGE_NAME = "@ai-agent-tools/picgen";
|
|
1002
|
+
var VERSION = "0.1.0-alpha.0";
|
|
1003
|
+
|
|
1004
|
+
// src/commands/update.ts
|
|
1005
|
+
var UPDATE_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
1006
|
+
async function runUpdateCheck(options = {}) {
|
|
1007
|
+
const result = await checkForUpdate({ force: true });
|
|
1008
|
+
if (options.json) {
|
|
1009
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1010
|
+
return;
|
|
1011
|
+
}
|
|
1012
|
+
const message = formatUpdateMessage(result);
|
|
1013
|
+
console.log(message ?? "PicGen is up to date.");
|
|
1014
|
+
}
|
|
1015
|
+
async function maybePrintUpdateHint() {
|
|
1016
|
+
const result = await checkForUpdate({ force: false });
|
|
1017
|
+
const message = formatUpdateMessage(result);
|
|
1018
|
+
if (message) {
|
|
1019
|
+
console.log("");
|
|
1020
|
+
console.log(message);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
async function checkForUpdate(options = {}) {
|
|
1024
|
+
if (process.env.PICGEN_DISABLE_UPDATE_CHECK === "1") {
|
|
1025
|
+
return {
|
|
1026
|
+
checked: false,
|
|
1027
|
+
disabled: true,
|
|
1028
|
+
current_version: VERSION,
|
|
1029
|
+
package_name: PACKAGE_NAME
|
|
1030
|
+
};
|
|
1031
|
+
}
|
|
1032
|
+
try {
|
|
1033
|
+
const cached = options.force ? void 0 : await readFreshCache();
|
|
1034
|
+
const latestVersion = cached?.latest_version ?? await fetchLatestVersion();
|
|
1035
|
+
const checkedAt = cached?.checked_at ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
1036
|
+
if (!cached) {
|
|
1037
|
+
await writeCache({
|
|
1038
|
+
checked_at: checkedAt,
|
|
1039
|
+
latest_version: latestVersion
|
|
1040
|
+
});
|
|
1041
|
+
}
|
|
1042
|
+
return {
|
|
1043
|
+
checked: true,
|
|
1044
|
+
current_version: VERSION,
|
|
1045
|
+
latest_version: latestVersion,
|
|
1046
|
+
update_available: isNewerVersion(latestVersion, VERSION),
|
|
1047
|
+
package_name: PACKAGE_NAME,
|
|
1048
|
+
checked_at: checkedAt
|
|
1049
|
+
};
|
|
1050
|
+
} catch (error) {
|
|
1051
|
+
return {
|
|
1052
|
+
checked: false,
|
|
1053
|
+
current_version: VERSION,
|
|
1054
|
+
package_name: PACKAGE_NAME,
|
|
1055
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
function formatUpdateMessage(result) {
|
|
1060
|
+
if (!result.checked || !result.update_available || !result.latest_version) {
|
|
1061
|
+
return void 0;
|
|
1062
|
+
}
|
|
1063
|
+
return [
|
|
1064
|
+
`PicGen update available: ${result.current_version} -> ${result.latest_version}`,
|
|
1065
|
+
"Upgrade with:",
|
|
1066
|
+
` npm install -g ${result.package_name}@latest`
|
|
1067
|
+
].join("\n");
|
|
1068
|
+
}
|
|
1069
|
+
function isNewerVersion(candidate, current) {
|
|
1070
|
+
const candidateParts = parseVersion(candidate);
|
|
1071
|
+
const currentParts = parseVersion(current);
|
|
1072
|
+
for (let index = 0; index < 3; index += 1) {
|
|
1073
|
+
if (candidateParts.numbers[index] > currentParts.numbers[index]) return true;
|
|
1074
|
+
if (candidateParts.numbers[index] < currentParts.numbers[index]) return false;
|
|
1075
|
+
}
|
|
1076
|
+
if (!candidateParts.prerelease && currentParts.prerelease) return true;
|
|
1077
|
+
if (candidateParts.prerelease && !currentParts.prerelease) return false;
|
|
1078
|
+
if (candidateParts.prerelease && currentParts.prerelease) {
|
|
1079
|
+
return candidateParts.prerelease.localeCompare(currentParts.prerelease) > 0;
|
|
1080
|
+
}
|
|
1081
|
+
return false;
|
|
1082
|
+
}
|
|
1083
|
+
async function fetchLatestVersion() {
|
|
1084
|
+
const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}`);
|
|
1085
|
+
if (!response.ok) {
|
|
1086
|
+
throw new Error(`npm registry returned ${response.status} ${response.statusText}`.trim());
|
|
1087
|
+
}
|
|
1088
|
+
const body = await response.json();
|
|
1089
|
+
const latest = body["dist-tags"]?.latest;
|
|
1090
|
+
if (typeof latest !== "string" || !latest) {
|
|
1091
|
+
throw new Error("npm registry response did not include dist-tags.latest.");
|
|
1092
|
+
}
|
|
1093
|
+
return latest;
|
|
1094
|
+
}
|
|
1095
|
+
async function readFreshCache() {
|
|
1096
|
+
try {
|
|
1097
|
+
const cache = JSON.parse(await readFile3(getUpdateCachePath(), "utf8"));
|
|
1098
|
+
const checkedAt = Date.parse(cache.checked_at);
|
|
1099
|
+
if (!Number.isFinite(checkedAt)) return void 0;
|
|
1100
|
+
if (Date.now() - checkedAt > UPDATE_CACHE_TTL_MS) return void 0;
|
|
1101
|
+
return cache;
|
|
1102
|
+
} catch (error) {
|
|
1103
|
+
if (error.code === "ENOENT") return void 0;
|
|
1104
|
+
return void 0;
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
async function writeCache(cache) {
|
|
1108
|
+
const path = getUpdateCachePath();
|
|
1109
|
+
await mkdir3(dirname2(path), { recursive: true });
|
|
1110
|
+
await writeFile3(path, JSON.stringify(cache, null, 2), "utf8");
|
|
1111
|
+
}
|
|
1112
|
+
function getUpdateCachePath() {
|
|
1113
|
+
if (process.env.PICGEN_UPDATE_CACHE_PATH) return process.env.PICGEN_UPDATE_CACHE_PATH;
|
|
1114
|
+
return join4(homedir2(), ".picgen", "update-check.json");
|
|
1115
|
+
}
|
|
1116
|
+
function parseVersion(version) {
|
|
1117
|
+
const [core, prerelease] = version.split("-", 2);
|
|
1118
|
+
const numbers = core.split(".").map((part) => Number.parseInt(part, 10));
|
|
1119
|
+
return {
|
|
1120
|
+
numbers: [
|
|
1121
|
+
Number.isFinite(numbers[0]) ? numbers[0] : 0,
|
|
1122
|
+
Number.isFinite(numbers[1]) ? numbers[1] : 0,
|
|
1123
|
+
Number.isFinite(numbers[2]) ? numbers[2] : 0
|
|
1124
|
+
],
|
|
1125
|
+
prerelease
|
|
1126
|
+
};
|
|
1127
|
+
}
|
|
1128
|
+
|
|
995
1129
|
// src/commands/doctor.ts
|
|
996
1130
|
async function runDoctor(options) {
|
|
997
1131
|
const config = await loadConfig();
|
|
@@ -1002,6 +1136,7 @@ async function runDoctor(options) {
|
|
|
1002
1136
|
JSON.stringify(
|
|
1003
1137
|
{
|
|
1004
1138
|
configured,
|
|
1139
|
+
version: VERSION,
|
|
1005
1140
|
config_path: getConfigPath(),
|
|
1006
1141
|
default_preset: config.default_preset,
|
|
1007
1142
|
default_mode: config.routing.default_mode,
|
|
@@ -1016,6 +1151,7 @@ async function runDoctor(options) {
|
|
|
1016
1151
|
return;
|
|
1017
1152
|
}
|
|
1018
1153
|
console.log(`Config: ${getConfigPath()}`);
|
|
1154
|
+
console.log(`Version: ${VERSION}`);
|
|
1019
1155
|
console.log(`Default preset: ${config.default_preset}`);
|
|
1020
1156
|
console.log(`Default mode: ${config.routing.default_mode}`);
|
|
1021
1157
|
console.log(`Default provider: ${config.routing.default_provider}`);
|
|
@@ -1031,6 +1167,7 @@ async function runDoctor(options) {
|
|
|
1031
1167
|
console.log("");
|
|
1032
1168
|
console.log("No usable provider found. Run `picgen setup` or set the API key env vars above.");
|
|
1033
1169
|
}
|
|
1170
|
+
await maybePrintUpdateHint();
|
|
1034
1171
|
}
|
|
1035
1172
|
|
|
1036
1173
|
// src/commands/provider.ts
|
|
@@ -1320,8 +1457,9 @@ async function preferPreset(name) {
|
|
|
1320
1457
|
}
|
|
1321
1458
|
|
|
1322
1459
|
// src/commands/quickstart.ts
|
|
1323
|
-
function runQuickstart() {
|
|
1460
|
+
async function runQuickstart() {
|
|
1324
1461
|
console.log(formatQuickstart());
|
|
1462
|
+
await maybePrintUpdateHint();
|
|
1325
1463
|
}
|
|
1326
1464
|
function formatQuickstart() {
|
|
1327
1465
|
return [
|
|
@@ -1572,7 +1710,7 @@ function modeLabel(modeName) {
|
|
|
1572
1710
|
|
|
1573
1711
|
// src/cli.ts
|
|
1574
1712
|
var program = new Command();
|
|
1575
|
-
program.name("picgen").description("Lightweight image generation connector for AI agents.").version(
|
|
1713
|
+
program.name("picgen").description("Lightweight image generation connector for AI agents.").version(VERSION);
|
|
1576
1714
|
program.command("setup").description("Run the interactive PicGen setup wizard.").action(runSetup);
|
|
1577
1715
|
program.command("quickstart").description("Print install and first-run guidance.").action(runQuickstart);
|
|
1578
1716
|
program.command("doctor").description("Inspect PicGen configuration and provider readiness.").option("--json", "Print machine-readable JSON.").action(runDoctor);
|
|
@@ -1593,6 +1731,7 @@ provider.command("disable").argument("<name>").description("Disable a provider."
|
|
|
1593
1731
|
provider.command("remove").argument("<name>").description("Remove a provider.").action(removeProvider);
|
|
1594
1732
|
program.command("mode").description("Manage generation mode preferences.").command("prefer").argument("<name>").description("Set the default mode preference.").action(preferMode);
|
|
1595
1733
|
program.command("preset").description("Manage generation preset preferences.").command("prefer").argument("<name>").description("Set the default preset preference.").action(preferPreset);
|
|
1734
|
+
program.command("update").description("Manage PicGen updates.").command("check").description("Check whether a newer PicGen version is available.").option("--json", "Print machine-readable JSON.").action(runUpdateCheck);
|
|
1596
1735
|
program.parseAsync().catch((error) => {
|
|
1597
1736
|
console.error(error instanceof Error ? error.message : String(error));
|
|
1598
1737
|
process.exitCode = 1;
|
package/docs/release-alpha.md
CHANGED
|
@@ -57,6 +57,12 @@ GEMINI_API_KEY=...
|
|
|
57
57
|
picgen doctor --json
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
+
6. Check whether a newer PicGen version is available:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
picgen update check
|
|
64
|
+
```
|
|
65
|
+
|
|
60
66
|
## Safe Preview
|
|
61
67
|
|
|
62
68
|
Always start with dry-run:
|
|
@@ -157,3 +163,9 @@ Publish when ready:
|
|
|
157
163
|
```bash
|
|
158
164
|
npm publish --otp <code>
|
|
159
165
|
```
|
|
166
|
+
|
|
167
|
+
After publishing, ask trial users to upgrade with:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
npm install -g @ai-agent-tools/picgen@latest
|
|
171
|
+
```
|