flowviant 0.28.0 → 0.28.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/bin/lib/deploy.mjs +20 -5
- package/bin/lib/fleet.mjs +6 -1
- package/package.json +2 -2
package/bin/lib/deploy.mjs
CHANGED
|
@@ -60,14 +60,19 @@ export async function reportDeployConfig(repoRoot) {
|
|
|
60
60
|
const targets = readDeployConfig(repoRoot);
|
|
61
61
|
const json = JSON.stringify(targets);
|
|
62
62
|
if (json === lastConfigJson) return;
|
|
63
|
-
//
|
|
63
|
+
// Scrub command strings before the server sees them — a command line can embed
|
|
64
|
+
// an internal host or a synced secret. Only redacted metadata leaves the box.
|
|
65
|
+
const scrubCmds = (o) =>
|
|
66
|
+
o && typeof o === 'object'
|
|
67
|
+
? Object.fromEntries(Object.entries(o).map(([k, v]) => [k, scrub(String(v ?? ''))]))
|
|
68
|
+
: o;
|
|
64
69
|
const meta = targets.map((t) => ({
|
|
65
70
|
id: t.id,
|
|
66
71
|
label: t.label,
|
|
67
72
|
provider: t.provider || 'cloudflare',
|
|
68
|
-
command: t.command,
|
|
69
|
-
build: t.build,
|
|
70
|
-
commands: t.commands,
|
|
73
|
+
command: scrub(String(t.command ?? '')),
|
|
74
|
+
build: t.build ? scrub(String(t.build)) : t.build,
|
|
75
|
+
commands: scrubCmds(t.commands),
|
|
71
76
|
healthcheck: t.healthcheck,
|
|
72
77
|
healthStatus: t.healthStatus,
|
|
73
78
|
pushSecrets: t.pushSecrets,
|
|
@@ -100,6 +105,11 @@ function run(command, { cwd, env, input }) {
|
|
|
100
105
|
/* already gone */
|
|
101
106
|
}
|
|
102
107
|
}, 30 * 60_000);
|
|
108
|
+
// A broken pipe (child exits before draining stdin — e.g. a fast-failing
|
|
109
|
+
// `wrangler secret put`) surfaces as an ASYNC 'error' on the stdin stream,
|
|
110
|
+
// which the try/catch below can't catch. Without a listener it's an uncaught
|
|
111
|
+
// exception that kills the whole daemon. Swallow it.
|
|
112
|
+
child.stdin.on('error', () => {});
|
|
103
113
|
if (input != null) {
|
|
104
114
|
try {
|
|
105
115
|
child.stdin.write(input);
|
|
@@ -129,7 +139,7 @@ async function verifyHealth(url, status) {
|
|
|
129
139
|
for (let i = 0; i < 4; i++) {
|
|
130
140
|
try {
|
|
131
141
|
const res = await fetch(url, { signal: AbortSignal.timeout(10_000), redirect: 'manual' });
|
|
132
|
-
if (res.status === status) return true;
|
|
142
|
+
if (res.status === Number(status)) return true; // coerce — a string "200" in deploy.json must still match
|
|
133
143
|
} catch {
|
|
134
144
|
/* not up yet */
|
|
135
145
|
}
|
|
@@ -148,6 +158,10 @@ const claiming = new Set(); // in-flight guard (single-flight per daemon process
|
|
|
148
158
|
export function processDeployJobs(jobs, ctx) {
|
|
149
159
|
if (!Array.isArray(jobs) || !jobs.length) return;
|
|
150
160
|
for (const job of jobs) {
|
|
161
|
+
// Defend against a malformed roster element — `job.id` on a null would throw
|
|
162
|
+
// synchronously here (outside the per-job try below) and wedge the whole
|
|
163
|
+
// reconcile loop, since this runs unguarded from the fleet tick.
|
|
164
|
+
if (!job || typeof job.id !== 'string') continue;
|
|
151
165
|
if (claiming.has(job.id)) continue;
|
|
152
166
|
claiming.add(job.id);
|
|
153
167
|
void (async () => {
|
|
@@ -185,6 +199,7 @@ export function processDeployJobs(jobs, ctx) {
|
|
|
185
199
|
|
|
186
200
|
async function runDeploy(job, target, ctx) {
|
|
187
201
|
const env = { ...process.env, ...deployCreds() }; // inject infra creds; never a file
|
|
202
|
+
delete env.FLEET_TOKEN; // the deploy command has no business reading it; keep it out of a command that might echo its env
|
|
188
203
|
const logs = [];
|
|
189
204
|
// Rollback is a single wrangler command; deploy is build → secrets → deploy.
|
|
190
205
|
if (job.kind === 'rollback') {
|
package/bin/lib/fleet.mjs
CHANGED
|
@@ -295,6 +295,7 @@ export async function runFleetDaemon() {
|
|
|
295
295
|
};
|
|
296
296
|
const processMergeJobs = (jobs) => {
|
|
297
297
|
for (const job of jobs ?? []) {
|
|
298
|
+
if (!job || typeof job.id !== 'string') continue; // a null element would wedge the loop
|
|
298
299
|
if (merging.has(job.id)) continue;
|
|
299
300
|
merging.add(job.id);
|
|
300
301
|
(async () => {
|
|
@@ -374,6 +375,7 @@ export async function runFleetDaemon() {
|
|
|
374
375
|
const cleaning = new Set();
|
|
375
376
|
const processCleanupJobs = (jobs) => {
|
|
376
377
|
for (const job of jobs ?? []) {
|
|
378
|
+
if (!job || typeof job.id !== 'string') continue; // a null element would wedge the loop
|
|
377
379
|
if (cleaning.has(job.id)) continue;
|
|
378
380
|
cleaning.add(job.id);
|
|
379
381
|
(async () => {
|
|
@@ -889,7 +891,10 @@ export async function runFleetDaemon() {
|
|
|
889
891
|
// turn) until we report reground-done; the bare drain flushes anything
|
|
890
892
|
// whose earlier mint failed.
|
|
891
893
|
enqueueSweep(roster.codeMapJob);
|
|
892
|
-
for (const j of roster.regroundJobs ?? [])
|
|
894
|
+
for (const j of roster.regroundJobs ?? []) {
|
|
895
|
+
if (!j || typeof j.intentId !== 'string') continue; // a null element would throw + wedge the loop
|
|
896
|
+
enqueueReground(j.intentId, j.prUrl, j.title);
|
|
897
|
+
}
|
|
893
898
|
void drainWiki();
|
|
894
899
|
|
|
895
900
|
// Env sync tick: register/bootstrap/wrap/rotate/sync as the roster block
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flowviant",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.1",
|
|
4
4
|
"description": "Run your own Claude Code as headless build agents for Flowviant — on your own credentials. Claims dispatched work, opens PRs, captures review evidence, and routes questions back to you.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"homepage": "https://flowviant.com",
|
|
31
31
|
"repository": {
|
|
32
32
|
"type": "git",
|
|
33
|
-
"url": "https://github.com/flowviant/cli.git"
|
|
33
|
+
"url": "git+https://github.com/flowviant/cli.git"
|
|
34
34
|
},
|
|
35
35
|
"license": "MIT",
|
|
36
36
|
"bugs": {
|