flowviant 0.117.0 → 0.124.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 +41 -0
- package/bin/cli.mjs +44 -0
- package/bin/lib/agentAsk.mjs +123 -0
- package/bin/lib/agentBrief.mjs +36 -0
- package/bin/lib/agentFootprint.mjs +76 -0
- package/bin/lib/agentInternalWait.mjs +4 -3
- package/bin/lib/agentPlan.mjs +86 -7
- package/bin/lib/agentPrerequisiteContract.mjs +43 -0
- package/bin/lib/agentRepositories.mjs +48 -0
- package/bin/lib/agentTaskKinds.mjs +1 -1
- package/bin/lib/artifactContracts.mjs +91 -20
- package/bin/lib/artifactIteration.mjs +182 -0
- package/bin/lib/artifactRecovery.mjs +36 -0
- package/bin/lib/artifactReporter.mjs +183 -19
- package/bin/lib/artifacts.mjs +6 -3
- package/bin/lib/checkoutIdentity.mjs +25 -0
- package/bin/lib/claudeAuth.mjs +15 -5
- package/bin/lib/claudeInput.mjs +32 -0
- package/bin/lib/claudePosture.mjs +110 -14
- package/bin/lib/claudeSessions.mjs +20 -0
- package/bin/lib/claudeStream.mjs +20 -2
- package/bin/lib/codexProjectRead.mjs +63 -0
- package/bin/lib/codexResearch.mjs +16 -3
- package/bin/lib/commandSpecs.mjs +6 -0
- package/bin/lib/credentials.mjs +52 -17
- package/bin/lib/daemonLocks.mjs +26 -6
- package/bin/lib/desktopContract.mjs +3 -0
- package/bin/lib/discoveryContract.mjs +19 -0
- package/bin/lib/fleet.mjs +65 -10
- package/bin/lib/fleetReports.mjs +44 -3
- package/bin/lib/fleetRoster.mjs +1 -89
- package/bin/lib/fleetStartup.mjs +11 -14
- package/bin/lib/holder.mjs +4 -37
- package/bin/lib/hooks/mcpAllow.mjs +60 -0
- package/bin/lib/hooks/readGuard.mjs +13 -4
- package/bin/lib/imageArtifact.mjs +74 -0
- package/bin/lib/instance.mjs +20 -7
- package/bin/lib/landed.mjs +2 -2
- package/bin/lib/login.mjs +39 -4
- package/bin/lib/maintenance.mjs +47 -0
- package/bin/lib/maintenanceInventory.mjs +39 -0
- package/bin/lib/mcpInstall.mjs +163 -0
- package/bin/lib/mcpInventory.mjs +119 -0
- package/bin/lib/placeLock.mjs +9 -7
- package/bin/lib/planDependencies.mjs +70 -0
- package/bin/lib/postureTools.mjs +85 -0
- package/bin/lib/prWorkflow.mjs +15 -0
- package/bin/lib/projectLanded.mjs +16 -0
- package/bin/lib/projectRepositories.mjs +60 -0
- package/bin/lib/projectToolRuntimes.mjs +227 -3
- package/bin/lib/projectTools.mjs +63 -5
- package/bin/lib/projectWorktreeHome.mjs +25 -0
- package/bin/lib/prompts.mjs +170 -42
- package/bin/lib/repositoryBaseline.mjs +68 -0
- package/bin/lib/repositoryDelivery.mjs +64 -0
- package/bin/lib/repositoryMerge.mjs +116 -0
- package/bin/lib/repositoryPlaces.mjs +179 -0
- package/bin/lib/repositorySetup.mjs +58 -0
- package/bin/lib/repositoryTool.mjs +71 -0
- package/bin/lib/runTurn.mjs +58 -18
- package/bin/lib/runtimeAntigravity.mjs +2 -1
- package/bin/lib/runtimeCapabilities.mjs +77 -3
- package/bin/lib/runtimeClaude.mjs +31 -10
- package/bin/lib/runtimeCodex.mjs +28 -59
- package/bin/lib/runtimeDetection.mjs +6 -0
- package/bin/lib/runtimeEvents.mjs +12 -1
- package/bin/lib/runtimeOfferings.mjs +75 -3
- package/bin/lib/shipMerge.mjs +5 -2
- package/bin/lib/startProject.mjs +4 -4
- package/bin/lib/trace.mjs +8 -3
- package/bin/lib/turnDeclaration.mjs +88 -0
- package/bin/lib/turnDiagnostics.mjs +93 -0
- package/bin/lib/turnLock.mjs +48 -8
- package/bin/lib/turnProfile.mjs +15 -3
- package/bin/lib/work.mjs +48 -29
- package/bin/lib/workAgentBrief.mjs +92 -0
- package/bin/lib/workAgentBriefRunner.mjs +59 -0
- package/bin/lib/workAgentCheck.mjs +6 -5
- package/bin/lib/workAgentMerges.mjs +19 -2
- package/bin/lib/workAgentPlans.mjs +21 -70
- package/bin/lib/workAgentPrecheck.mjs +10 -5
- package/bin/lib/workAgentPublish.mjs +18 -5
- package/bin/lib/workAgentRecovery.mjs +85 -0
- package/bin/lib/workAgentReview.mjs +5 -3
- package/bin/lib/workAgentTurnBegun.mjs +6 -4
- package/bin/lib/workAgentTurnExecution.mjs +167 -29
- package/bin/lib/workAgentTurnOutcome.mjs +20 -5
- package/bin/lib/workAgentTurns.mjs +92 -12
- package/bin/lib/workArtifactReconcile.mjs +79 -0
- package/bin/lib/workCappedTurn.mjs +10 -0
- package/bin/lib/workCommandAudit.mjs +8 -1
- package/bin/lib/workDelivery.mjs +21 -0
- package/bin/lib/workDiffs.mjs +18 -11
- package/bin/lib/workLiveMessages.mjs +129 -0
- package/bin/lib/workPlaceReports.mjs +5 -0
- package/bin/lib/workPlaces.mjs +24 -3
- package/bin/lib/workRetire.mjs +5 -0
- package/bin/lib/workSessionTurns.mjs +219 -52
- package/bin/lib/workShip.mjs +17 -16
- package/bin/lib/workToolLog.mjs +70 -3
- package/bin/lib/workTurnShape.mjs +6 -4
- package/package.json +7 -3
- package/npm-shrinkwrap.json +0 -59
package/bin/lib/workToolLog.mjs
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* the stream. Tested directly (workToolLog.test.mjs).
|
|
9
9
|
*/
|
|
10
10
|
import { toolEventOf } from './runtimeEvents.mjs';
|
|
11
|
-
import { scrub as envScrub } from './uplinkScrub.mjs';
|
|
11
|
+
import { scrubCut, scrub as envScrub } from './uplinkScrub.mjs';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* THE TURN'S TOOL LOG — the structured relay behind the transcript's
|
|
@@ -30,14 +30,74 @@ import { scrub as envScrub } from './uplinkScrub.mjs';
|
|
|
30
30
|
* because it is current state rather than scrollback.
|
|
31
31
|
*/
|
|
32
32
|
export function createToolLog(cwd) {
|
|
33
|
-
const toolLog = { ev: [], dropped: 0 };
|
|
34
|
-
|
|
33
|
+
const toolLog = { ev: [], dropped: 0, state: 'unknown' };
|
|
34
|
+
// IDs are correlation keys, never model-authored citations. Keep only bounded
|
|
35
|
+
// metadata; output supplies a fixed category and allowlisted reader diagnostic.
|
|
36
|
+
// Arbitrary output and file contents are discarded.
|
|
37
|
+
const correlated = new Map();
|
|
38
|
+
const refresh = () => {
|
|
39
|
+
toolLog.state = toolLog.state === 'partial' || toolLog.dropped || toolLog.recoveryDropped ? 'partial' :
|
|
40
|
+
toolLog.ev.length && toolLog.ev.every(e => e.outcome && e.outcome !== 'unknown') ? 'complete' : 'unknown';
|
|
41
|
+
const retained = new Set([...toolLog.ev, toolLog.firstFailure, ...(toolLog.recovery ?? [])]);
|
|
42
|
+
for (const [id, row] of correlated) if (!retained.has(row)) correlated.delete(id);
|
|
43
|
+
};
|
|
44
|
+
const observe = (e, meta) => {
|
|
45
|
+
const code = Number.isSafeInteger(meta.exitCode) ? meta.exitCode : undefined;
|
|
46
|
+
const failed = meta.isError === true || (code !== undefined && code !== 0);
|
|
47
|
+
e.outcome = !meta.result ? 'unknown' : failed ? 'failed' :
|
|
48
|
+
meta.runtime === 'codex' && code === undefined ? 'unknown' : 'success';
|
|
49
|
+
if (code !== undefined) e.exitCode = code;
|
|
50
|
+
if (failed) {
|
|
51
|
+
const output = scrubCut(meta.output ?? '', 16_384);
|
|
52
|
+
const guardAt = output.indexOf('flowviant: this turn is read-only, so ');
|
|
53
|
+
const guard = guardAt >= 0 ? output.slice(guardAt).split('\n', 1)[0] : undefined;
|
|
54
|
+
const diagnostic = guard ?? output.split('\n', 80).find(line => /^(?:[\w./ -]{1,160}: ){1,2}(?:No such file or directory|Permission denied|command not found)\.?$/.test(line) || (e.t === 'read' && /^(?:Error: )?(?:File does not exist|File not found|Permission denied)\.?(?: Note: your current working directory is [^\n]{1,400}\.)?$/.test(line)));
|
|
55
|
+
if (diagnostic) {
|
|
56
|
+
e.errorMessage = diagnostic.slice(0, 500);
|
|
57
|
+
if (diagnostic.length > 500) { e.errorTruncated = true; toolLog.state = 'partial'; }
|
|
58
|
+
}
|
|
59
|
+
e.errorCategory = guard && /a pipe|a glob|a redirect|a second command|an expansion|command substitution|brace expansion|a subshell/.test(guard) ? 'syntax_refusal' : /permission|denied|approval|not allowed|refus/i.test(output) ? 'denied' :
|
|
60
|
+
/command not found|not recognized|executable.*not found/i.test(output) ? 'unavailable_tool' :
|
|
61
|
+
/no such file|not found|does not exist|cannot find/i.test(output) ? 'missing_path' : 'tool_error';
|
|
62
|
+
if (!toolLog.firstFailure) {
|
|
63
|
+
toolLog.firstFailure = { ...e };
|
|
64
|
+
toolLog.recovery = [];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const pushToolEvent = (name, input, meta = {}) => {
|
|
69
|
+
const id = typeof meta.id === 'string' && meta.id && meta.id.length <= 160 ? meta.id : undefined;
|
|
70
|
+
const existing = id && correlated.get(id);
|
|
71
|
+
if (existing) {
|
|
72
|
+
if (meta.result) observe(existing, meta);
|
|
73
|
+
refresh();
|
|
74
|
+
return existing;
|
|
75
|
+
}
|
|
76
|
+
if (!name) {
|
|
77
|
+
toolLog.dropped = Math.min(1_000_000, toolLog.dropped + 1);
|
|
78
|
+
refresh();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
35
81
|
// envScrub rides INTO the builder, which scrubs over a bounded
|
|
36
82
|
// window BEFORE its caps — scrubbing after the cut both leaked a
|
|
37
83
|
// boundary-straddling secret's prefix and grew a capped field
|
|
38
84
|
// past the server's limits (review, 2026-09-01).
|
|
39
85
|
const e = toolEventOf(name, input, cwd, envScrub);
|
|
40
86
|
if (!e) return;
|
|
87
|
+
if (e.t !== 'plan') {
|
|
88
|
+
if (id) { e.id = scrubCut(id, 160); correlated.set(id, e); }
|
|
89
|
+
if (name === 'Read') for (const key of ['offset', 'limit']) {
|
|
90
|
+
if (Number.isSafeInteger(input?.[key]) && input[key] >= 0) e[key] = input[key];
|
|
91
|
+
}
|
|
92
|
+
if (toolLog.firstFailure) {
|
|
93
|
+
toolLog.recovery.push(e);
|
|
94
|
+
if (toolLog.recovery.length > 12) {
|
|
95
|
+
toolLog.recovery.shift();
|
|
96
|
+
toolLog.recoveryDropped = Math.min(1_000_000, (toolLog.recoveryDropped ?? 0) + 1);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
observe(e, meta);
|
|
100
|
+
}
|
|
41
101
|
if (e.t === 'plan') {
|
|
42
102
|
const i = toolLog.ev.findIndex((x) => x.t === 'plan');
|
|
43
103
|
if (i >= 0) toolLog.ev.splice(i, 1);
|
|
@@ -46,6 +106,11 @@ export function createToolLog(cwd) {
|
|
|
46
106
|
const last = toolLog.ev[toolLog.ev.length - 1];
|
|
47
107
|
const sameKey =
|
|
48
108
|
last &&
|
|
109
|
+
!id && !last.id &&
|
|
110
|
+
last.outcome === e.outcome &&
|
|
111
|
+
last.exitCode === e.exitCode &&
|
|
112
|
+
last.errorCategory === e.errorCategory &&
|
|
113
|
+
last.offset === e.offset && last.limit === e.limit &&
|
|
49
114
|
last.t === e.t &&
|
|
50
115
|
last.p === e.p &&
|
|
51
116
|
last.q === e.q &&
|
|
@@ -71,6 +136,8 @@ export function createToolLog(cwd) {
|
|
|
71
136
|
const [shed] = toolLog.ev.splice(i, 1);
|
|
72
137
|
toolLog.dropped = Math.min(1_000_000, toolLog.dropped + (shed?.n ?? 1));
|
|
73
138
|
}
|
|
139
|
+
refresh();
|
|
140
|
+
return e;
|
|
74
141
|
};
|
|
75
142
|
return { toolLog, pushToolEvent };
|
|
76
143
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { discoveryGuide } from './discoveryContract.mjs';
|
|
1
2
|
/**
|
|
2
3
|
* WHAT A TERMINAL TAB'S TURN IS — plain, plan, capture or build — decided
|
|
3
4
|
* once, as data (audit 2026-10-10, F159). Pure: no I/O, no state.
|
|
@@ -145,8 +146,8 @@ const SYSTEMS = { plain: SYSTEM_WORK_PLAIN, capture: SYSTEM_CAPTURE, work: SYSTE
|
|
|
145
146
|
/** The turn's opening message under its contract. The plain kickoff names no
|
|
146
147
|
* session id (WORK_TURN_KICKOFF_PLAIN takes none) — it has no tools to pass
|
|
147
148
|
* one to. */
|
|
148
|
-
export const sessionTurnKickoff = (shape, { sessionId, sessionName, message, askedByName }) =>
|
|
149
|
-
KICKOFFS[shape.kickoff]({ sessionId, sessionName, message, askedByName });
|
|
149
|
+
export const sessionTurnKickoff = (shape, { sessionId, sessionName, message, askedByName, interrupted = false }) =>
|
|
150
|
+
KICKOFFS[shape.kickoff]({ sessionId, sessionName, message, askedByName, interrupted });
|
|
150
151
|
|
|
151
152
|
/**
|
|
152
153
|
* The turn's system prompt: its contract with the project's knowledge
|
|
@@ -154,10 +155,11 @@ export const sessionTurnKickoff = (shape, { sessionId, sessionName, message, ask
|
|
|
154
155
|
* server can show one (`artifactsAccepted`, read by the lane at spawn), and a
|
|
155
156
|
* plan turn's sentence appended.
|
|
156
157
|
*/
|
|
157
|
-
export const sessionTurnSystem = (shape, { knowledgeDir, artifactsAccepted }) => {
|
|
158
|
+
export const sessionTurnSystem = (shape, { knowledgeDir, artifactsAccepted, runtime }) => {
|
|
158
159
|
const contract = withProjectContext(SYSTEMS[shape.systemBase], {
|
|
159
160
|
knowledgeDir,
|
|
160
161
|
artifacts: shape.artifacts && artifactsAccepted,
|
|
161
162
|
});
|
|
162
|
-
|
|
163
|
+
const discovery = shape.systemBase === 'capture' && runtime ? `\n\n${discoveryGuide(runtime, 'capture')}` : '';
|
|
164
|
+
return shape.planSentence ? `${contract}\n\n${PLAN_TURN_SENTENCE}` : contract + discovery;
|
|
163
165
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flowviant",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.124.1",
|
|
4
4
|
"description": "Run your own coding CLIs as build agents for Flowviant — Claude Code, Codex or Antigravity, on your own credentials. Holds your sessions, keeps a worktree per tab, and ships branches on your word.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -35,10 +35,14 @@
|
|
|
35
35
|
"homepage": "https://flowviant.com",
|
|
36
36
|
"repository": {
|
|
37
37
|
"type": "git",
|
|
38
|
-
"url": "git+https://github.com/flowviant
|
|
38
|
+
"url": "git+https://github.com/Flowviant/flowviant.git",
|
|
39
|
+
"directory": "cli"
|
|
39
40
|
},
|
|
40
41
|
"license": "MIT",
|
|
41
42
|
"bugs": {
|
|
42
|
-
"url": "https://github.com/flowviant/
|
|
43
|
+
"url": "https://github.com/Flowviant/flowviant/issues"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"three": "0.180.0"
|
|
43
47
|
}
|
|
44
48
|
}
|
package/npm-shrinkwrap.json
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "flowviant",
|
|
3
|
-
"version": "0.117.0",
|
|
4
|
-
"lockfileVersion": 3,
|
|
5
|
-
"requires": true,
|
|
6
|
-
"packages": {
|
|
7
|
-
"": {
|
|
8
|
-
"name": "flowviant",
|
|
9
|
-
"version": "0.117.0",
|
|
10
|
-
"license": "MIT",
|
|
11
|
-
"dependencies": {
|
|
12
|
-
"libsodium-wrappers-sumo": "^0.8.4",
|
|
13
|
-
"ws": "^8.18.0"
|
|
14
|
-
},
|
|
15
|
-
"bin": {
|
|
16
|
-
"flowviant": "bin/cli.mjs"
|
|
17
|
-
},
|
|
18
|
-
"engines": {
|
|
19
|
-
"node": ">=20"
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
"node_modules/libsodium-sumo": {
|
|
23
|
-
"version": "0.8.4",
|
|
24
|
-
"resolved": "https://registry.npmjs.org/libsodium-sumo/-/libsodium-sumo-0.8.4.tgz",
|
|
25
|
-
"integrity": "sha512-TMtHShQfVVsaxDygyapvUC3o7YsPgXa/hRWeIgzyFz6w5k/1hirGptCxp1U7XwW3rCskaTTYKgV10v86UiGgNw==",
|
|
26
|
-
"license": "ISC"
|
|
27
|
-
},
|
|
28
|
-
"node_modules/libsodium-wrappers-sumo": {
|
|
29
|
-
"version": "0.8.4",
|
|
30
|
-
"resolved": "https://registry.npmjs.org/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.8.4.tgz",
|
|
31
|
-
"integrity": "sha512-ql7hcgulKZ3ekfa2DGAogcCKsWU0diA/0nArz1CFzh93WQdb46/Kj18ka/Hifq6uA3Ush34Pc6vU/6HXeRwUkg==",
|
|
32
|
-
"license": "ISC",
|
|
33
|
-
"dependencies": {
|
|
34
|
-
"libsodium-sumo": "^0.8.0"
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
"node_modules/ws": {
|
|
38
|
-
"version": "8.21.1",
|
|
39
|
-
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz",
|
|
40
|
-
"integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==",
|
|
41
|
-
"license": "MIT",
|
|
42
|
-
"engines": {
|
|
43
|
-
"node": ">=10.0.0"
|
|
44
|
-
},
|
|
45
|
-
"peerDependencies": {
|
|
46
|
-
"bufferutil": "^4.0.1",
|
|
47
|
-
"utf-8-validate": ">=5.0.2"
|
|
48
|
-
},
|
|
49
|
-
"peerDependenciesMeta": {
|
|
50
|
-
"bufferutil": {
|
|
51
|
-
"optional": true
|
|
52
|
-
},
|
|
53
|
-
"utf-8-validate": {
|
|
54
|
-
"optional": true
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|