@voltro/cli 0.4.0 → 0.6.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/CHANGELOG.md +68 -0
- package/bin/voltro.mjs +54 -2
- package/dist/apiBuild-Bk4JBt-i.js +2 -0
- package/dist/{apiBuild-CvtQeBMs.js → apiBuild-BxY44VGj.js} +20 -20
- package/dist/bin.js +2 -2
- package/dist/{commands-DhyBIs1O.js → commands-My_YlUJV.js} +2823 -2265
- package/dist/{dev-CQxbrpDz.js → dev-Bjq-nIvH.js} +2650 -2230
- package/dist/dev-D6b74iXI.js +2 -0
- package/dist/devActivity-1WtIVyHc.js +153 -0
- package/dist/devActivity.d.ts +46 -0
- package/dist/devActivity.js +2 -0
- package/dist/index.js +1 -1
- package/dist/serveCommand-C-XQ89NJ.js +1110 -0
- package/dist/serveEntry.js +2 -2
- package/package.json +22 -17
- package/templates/AGENTS.core.md +119 -0
- package/templates/AGENTS.md +119 -0
- package/templates/agent-docs/_manifest.json +3 -3
- package/templates/agent-docs/ai.md +41 -5
- package/templates/agent-docs/authentication.md +238 -0
- package/templates/agent-docs/cli.md +142 -0
- package/templates/agent-docs/configuration.md +38 -0
- package/templates/agent-docs/data.md +718 -42
- package/templates/agent-docs/database/advancedqueries.md +21 -0
- package/templates/agent-docs/database/querying.md +166 -8
- package/templates/agent-docs/database/schema.md +6 -2
- package/templates/agent-docs/deployment.md +171 -0
- package/templates/agent-docs/internationalization.md +2 -0
- package/templates/agent-docs/plugins.md +4 -4
- package/templates/agent-docs/reference.md +90 -2
- package/templates/agent-docs/templates/apibackends.md +13 -2
- package/templates/agent-docs/testing.md +157 -3
- package/templates/agent-docs/workflows.md +11 -8
- package/templates/apps/api-ai/package.json +7 -7
- package/templates/apps/api-auth/app.config.ts +20 -13
- package/templates/apps/api-auth/package.json +8 -8
- package/templates/apps/api-backend/package.json +7 -7
- package/templates/apps/api-backend-deactivation/package.json +7 -7
- package/templates/apps/api-backend-mail/package.json +8 -8
- package/templates/apps/api-backend-mariadb/.env.example +10 -4
- package/templates/apps/api-backend-mariadb/package.json +9 -9
- package/templates/apps/api-backend-storage/package.json +8 -8
- package/templates/apps/api-data-advanced/app.config.ts +21 -8
- package/templates/apps/api-data-advanced/package.json +8 -8
- package/templates/apps/api-durable/package.json +8 -8
- package/templates/apps/api-feature-flags/package.json +9 -9
- package/templates/apps/api-governance/app.config.ts +15 -2
- package/templates/apps/api-governance/package.json +8 -8
- package/templates/apps/api-kv/package.json +8 -8
- package/templates/apps/api-moderation/package.json +8 -8
- package/templates/apps/api-observability/package.json +8 -8
- package/templates/apps/api-ratelimit/package.json +8 -8
- package/templates/apps/api-rbac/package.json +8 -8
- package/templates/apps/api-rest/package.json +7 -7
- package/templates/apps/api-saas/package.json +11 -11
- package/templates/apps/api-search/package.json +8 -8
- package/templates/apps/api-versioning/package.json +8 -8
- package/templates/apps/api-webhooks/app.config.ts +20 -1
- package/templates/apps/api-webhooks/package.json +8 -8
- package/templates/apps/changelog/package.json +6 -6
- package/templates/apps/edge-functions/package.json +2 -2
- package/templates/apps/frontend-admin/package.json +8 -8
- package/templates/apps/frontend-app/package.json +8 -8
- package/templates/apps/frontend-blank/package.json +7 -7
- package/templates/apps/frontend-contact/package.json +7 -7
- package/templates/apps/frontend-dashboard/package.json +7 -7
- package/templates/apps/frontend-docs/package.json +7 -7
- package/templates/apps/frontend-i18n/package.json +6 -6
- package/templates/apps/frontend-landing/package.json +7 -7
- package/templates/apps/frontend-spa/package.json +7 -7
- package/templates/apps/frontend-ssr/package.json +7 -7
- package/templates/apps/frontend-ssr-api/package.json +8 -8
- package/templates/apps/frontend-static-blog/package.json +6 -6
- package/templates/baselines/bare/.env.example +10 -3
- package/templates/baselines/compose/.env.example +10 -2
- package/templates/baselines/compose-mariadb/.env.example +10 -2
- package/templates/baselines/helm/.env.example +10 -3
- package/dist/apiBuild-DQBNqNZ8.js +0 -2
- package/dist/dev-DYjGqPGD.js +0 -2
- package/dist/serveCommand-BZzUJIyo.js +0 -1077
- package/templates/apps/api-auth/.env +0 -17
- package/templates/apps/api-data-advanced/.env +0 -17
- package/templates/apps/api-governance/.env +0 -4
- package/templates/apps/api-webhooks/.env +0 -6
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { dirname as e, join as t } from "node:path";
|
|
2
|
+
import { promises as n } from "node:fs";
|
|
3
|
+
import { homedir as r } from "node:os";
|
|
4
|
+
//#region src/cloudClient.ts
|
|
5
|
+
var i = () => process.env.VOLTRO_CREDENTIALS_PATH ?? t(r(), ".voltro", "credentials.json"), a = () => (process.env.VOLTRO_CLOUD_URL ?? "https://cloud.voltro.dev").replace(/\/+$/, ""), o = async () => {
|
|
6
|
+
try {
|
|
7
|
+
let e = await n.readFile(i(), "utf8"), t = JSON.parse(e);
|
|
8
|
+
return typeof t.token == "string" && t.token.length > 0 ? {
|
|
9
|
+
token: t.token,
|
|
10
|
+
url: t.url ?? a(),
|
|
11
|
+
savedAt: t.savedAt ?? ""
|
|
12
|
+
} : null;
|
|
13
|
+
} catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}, s = async (t) => {
|
|
17
|
+
let r = i();
|
|
18
|
+
await n.mkdir(e(r), { recursive: !0 }), await n.writeFile(r, JSON.stringify(t, null, 2), "utf8");
|
|
19
|
+
}, c = async (e, t) => {
|
|
20
|
+
let n = `${a()}${e.startsWith("/") ? e : `/${e}`}`, r = {};
|
|
21
|
+
t?.token !== void 0 && (r.authorization = `Bearer ${t.token}`);
|
|
22
|
+
let i = t?.body !== void 0;
|
|
23
|
+
i && (r["content-type"] = "application/json");
|
|
24
|
+
let o = t?.timeoutMs === void 0 ? void 0 : new AbortController(), s = o === void 0 ? void 0 : setTimeout(() => o.abort(), t.timeoutMs);
|
|
25
|
+
try {
|
|
26
|
+
let e = await fetch(n, {
|
|
27
|
+
method: t?.method ?? "GET",
|
|
28
|
+
headers: r,
|
|
29
|
+
...i ? { body: JSON.stringify(t.body) } : {},
|
|
30
|
+
...o === void 0 ? {} : { signal: o.signal }
|
|
31
|
+
}), a = await e.text(), s;
|
|
32
|
+
if (a.length > 0) try {
|
|
33
|
+
s = JSON.parse(a);
|
|
34
|
+
} catch {
|
|
35
|
+
s = a;
|
|
36
|
+
}
|
|
37
|
+
if (!e.ok) {
|
|
38
|
+
let t = typeof s == "object" && s && "error" in s ? String(s.error) : `HTTP ${e.status}`;
|
|
39
|
+
return {
|
|
40
|
+
kind: "err",
|
|
41
|
+
status: e.status,
|
|
42
|
+
error: t
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
kind: "ok",
|
|
47
|
+
status: e.status,
|
|
48
|
+
data: s
|
|
49
|
+
};
|
|
50
|
+
} catch (e) {
|
|
51
|
+
return {
|
|
52
|
+
kind: "err",
|
|
53
|
+
status: 0,
|
|
54
|
+
error: e.message || String(e)
|
|
55
|
+
};
|
|
56
|
+
} finally {
|
|
57
|
+
s !== void 0 && clearTimeout(s);
|
|
58
|
+
}
|
|
59
|
+
}, l = () => process.env.VOLTRO_DEV_ACTIVITY_PATH ?? t(e(process.env.VOLTRO_CREDENTIALS_PATH ?? t(r(), ".voltro", "credentials.json")), "dev-activity.json"), u = (e = /* @__PURE__ */ new Date()) => e.toISOString().slice(0, 10), d = {
|
|
60
|
+
sent: {},
|
|
61
|
+
pending: []
|
|
62
|
+
}, f = async () => {
|
|
63
|
+
try {
|
|
64
|
+
let e = JSON.parse(await n.readFile(l(), "utf8"));
|
|
65
|
+
return {
|
|
66
|
+
sent: typeof e.sent == "object" && e.sent !== null ? e.sent : {},
|
|
67
|
+
pending: Array.isArray(e.pending) ? e.pending.slice(-30) : []
|
|
68
|
+
};
|
|
69
|
+
} catch {
|
|
70
|
+
return d;
|
|
71
|
+
}
|
|
72
|
+
}, p = async (t) => {
|
|
73
|
+
try {
|
|
74
|
+
let r = l();
|
|
75
|
+
await n.mkdir(e(r), { recursive: !0 }), await n.writeFile(r, JSON.stringify(t, null, 2), "utf8");
|
|
76
|
+
} catch {}
|
|
77
|
+
}, m = async (e, t, n) => {
|
|
78
|
+
let r = await c("/dev-activity", {
|
|
79
|
+
method: "POST",
|
|
80
|
+
body: t,
|
|
81
|
+
token: e,
|
|
82
|
+
timeoutMs: n
|
|
83
|
+
});
|
|
84
|
+
if (r.kind === "ok") {
|
|
85
|
+
let e = r.data?.seat;
|
|
86
|
+
return {
|
|
87
|
+
ok: !0,
|
|
88
|
+
seat: e === "claimed" || e === "refreshed" ? e : "unchanged"
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
ok: !1,
|
|
93
|
+
status: r.status,
|
|
94
|
+
error: r.error
|
|
95
|
+
};
|
|
96
|
+
}, h = async (e = {}) => {
|
|
97
|
+
try {
|
|
98
|
+
let t = await o();
|
|
99
|
+
if (t === null) return {
|
|
100
|
+
kind: "skipped",
|
|
101
|
+
reason: "no-credentials"
|
|
102
|
+
};
|
|
103
|
+
let n = e.project ?? "(unknown)", r = u(), i = await f();
|
|
104
|
+
if (!e.force && i.sent[n] === r && i.pending.length === 0) return {
|
|
105
|
+
kind: "skipped",
|
|
106
|
+
reason: "already-reported"
|
|
107
|
+
};
|
|
108
|
+
let a = await m(t.token, {
|
|
109
|
+
...e.project === void 0 ? {} : { project: e.project },
|
|
110
|
+
...e.cliVersion === void 0 ? {} : { cliVersion: e.cliVersion },
|
|
111
|
+
day: r
|
|
112
|
+
}, 3e3);
|
|
113
|
+
if (!a.ok) return a.status === 401 || a.status === 403 ? {
|
|
114
|
+
kind: "not-personal",
|
|
115
|
+
message: a.error
|
|
116
|
+
} : (await p({
|
|
117
|
+
sent: i.sent,
|
|
118
|
+
pending: [...i.pending, {
|
|
119
|
+
day: r,
|
|
120
|
+
project: n
|
|
121
|
+
}].slice(-30)
|
|
122
|
+
}), {
|
|
123
|
+
kind: "deferred",
|
|
124
|
+
error: a.error
|
|
125
|
+
});
|
|
126
|
+
let s = [];
|
|
127
|
+
for (let n of i.pending) {
|
|
128
|
+
let r = await m(t.token, {
|
|
129
|
+
project: n.project,
|
|
130
|
+
...e.cliVersion === void 0 ? {} : { cliVersion: e.cliVersion },
|
|
131
|
+
day: n.day
|
|
132
|
+
}, 3e3);
|
|
133
|
+
!r.ok && r.status !== 401 && r.status !== 403 && s.push(n);
|
|
134
|
+
}
|
|
135
|
+
return await p({
|
|
136
|
+
sent: {
|
|
137
|
+
...i.sent,
|
|
138
|
+
[n]: r
|
|
139
|
+
},
|
|
140
|
+
pending: s.slice(-30)
|
|
141
|
+
}), {
|
|
142
|
+
kind: "reported",
|
|
143
|
+
seat: a.seat
|
|
144
|
+
};
|
|
145
|
+
} catch (e) {
|
|
146
|
+
return {
|
|
147
|
+
kind: "deferred",
|
|
148
|
+
error: e.message || String(e)
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
//#endregion
|
|
153
|
+
export { c as a, s as c, a as i, l as n, i as o, h as r, o as s, u as t };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** UTC day bucket, `YYYY-MM-DD`. */
|
|
2
|
+
export declare const dayKey: (at?: Date) => string;
|
|
3
|
+
|
|
4
|
+
export declare type DevActivityOutcome =
|
|
5
|
+
/** Nothing to do: not logged in, or already reported today. */
|
|
6
|
+
{
|
|
7
|
+
readonly kind: 'skipped';
|
|
8
|
+
readonly reason: 'no-credentials' | 'already-reported';
|
|
9
|
+
}
|
|
10
|
+
/** Delivered. `seat` is what the ledger did. */
|
|
11
|
+
| {
|
|
12
|
+
readonly kind: 'reported';
|
|
13
|
+
readonly seat: 'claimed' | 'refreshed' | 'unchanged';
|
|
14
|
+
}
|
|
15
|
+
/** Could not reach the control plane; the day is queued for a later run. */
|
|
16
|
+
| {
|
|
17
|
+
readonly kind: 'deferred';
|
|
18
|
+
readonly error: string;
|
|
19
|
+
}
|
|
20
|
+
/** The credential belongs to no person — the caller must refuse to continue. */
|
|
21
|
+
| {
|
|
22
|
+
readonly kind: 'not-personal';
|
|
23
|
+
readonly message: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/** Where the debounce state lives. Beside the credentials, and overridable by
|
|
27
|
+
* the same env var pattern so tests never touch a real home directory. */
|
|
28
|
+
export declare const devActivityStatePath: () => string;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Report today's activity, flushing anything queued from earlier failures.
|
|
32
|
+
*
|
|
33
|
+
* Returns an outcome rather than throwing. Callers that want the hard gate
|
|
34
|
+
* (interactive development) act on `not-personal`; everything else is
|
|
35
|
+
* informational and safe to ignore entirely.
|
|
36
|
+
*/
|
|
37
|
+
export declare const reportDevActivity: (input?: ReportInput) => Promise<DevActivityOutcome>;
|
|
38
|
+
|
|
39
|
+
declare interface ReportInput {
|
|
40
|
+
readonly project?: string | undefined;
|
|
41
|
+
readonly cliVersion?: string | undefined;
|
|
42
|
+
/** Report even if today was already reported. Used by tests. */
|
|
43
|
+
readonly force?: boolean;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export { }
|
package/dist/index.js
CHANGED