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.
Files changed (103) hide show
  1. package/README.md +41 -0
  2. package/bin/cli.mjs +44 -0
  3. package/bin/lib/agentAsk.mjs +123 -0
  4. package/bin/lib/agentBrief.mjs +36 -0
  5. package/bin/lib/agentFootprint.mjs +76 -0
  6. package/bin/lib/agentInternalWait.mjs +4 -3
  7. package/bin/lib/agentPlan.mjs +86 -7
  8. package/bin/lib/agentPrerequisiteContract.mjs +43 -0
  9. package/bin/lib/agentRepositories.mjs +48 -0
  10. package/bin/lib/agentTaskKinds.mjs +1 -1
  11. package/bin/lib/artifactContracts.mjs +91 -20
  12. package/bin/lib/artifactIteration.mjs +182 -0
  13. package/bin/lib/artifactRecovery.mjs +36 -0
  14. package/bin/lib/artifactReporter.mjs +183 -19
  15. package/bin/lib/artifacts.mjs +6 -3
  16. package/bin/lib/checkoutIdentity.mjs +25 -0
  17. package/bin/lib/claudeAuth.mjs +15 -5
  18. package/bin/lib/claudeInput.mjs +32 -0
  19. package/bin/lib/claudePosture.mjs +110 -14
  20. package/bin/lib/claudeSessions.mjs +20 -0
  21. package/bin/lib/claudeStream.mjs +20 -2
  22. package/bin/lib/codexProjectRead.mjs +63 -0
  23. package/bin/lib/codexResearch.mjs +16 -3
  24. package/bin/lib/commandSpecs.mjs +6 -0
  25. package/bin/lib/credentials.mjs +52 -17
  26. package/bin/lib/daemonLocks.mjs +26 -6
  27. package/bin/lib/desktopContract.mjs +3 -0
  28. package/bin/lib/discoveryContract.mjs +19 -0
  29. package/bin/lib/fleet.mjs +65 -10
  30. package/bin/lib/fleetReports.mjs +44 -3
  31. package/bin/lib/fleetRoster.mjs +1 -89
  32. package/bin/lib/fleetStartup.mjs +11 -14
  33. package/bin/lib/holder.mjs +4 -37
  34. package/bin/lib/hooks/mcpAllow.mjs +60 -0
  35. package/bin/lib/hooks/readGuard.mjs +13 -4
  36. package/bin/lib/imageArtifact.mjs +74 -0
  37. package/bin/lib/instance.mjs +20 -7
  38. package/bin/lib/landed.mjs +2 -2
  39. package/bin/lib/login.mjs +39 -4
  40. package/bin/lib/maintenance.mjs +47 -0
  41. package/bin/lib/maintenanceInventory.mjs +39 -0
  42. package/bin/lib/mcpInstall.mjs +163 -0
  43. package/bin/lib/mcpInventory.mjs +119 -0
  44. package/bin/lib/placeLock.mjs +9 -7
  45. package/bin/lib/planDependencies.mjs +70 -0
  46. package/bin/lib/postureTools.mjs +85 -0
  47. package/bin/lib/prWorkflow.mjs +15 -0
  48. package/bin/lib/projectLanded.mjs +16 -0
  49. package/bin/lib/projectRepositories.mjs +60 -0
  50. package/bin/lib/projectToolRuntimes.mjs +227 -3
  51. package/bin/lib/projectTools.mjs +63 -5
  52. package/bin/lib/projectWorktreeHome.mjs +25 -0
  53. package/bin/lib/prompts.mjs +170 -42
  54. package/bin/lib/repositoryBaseline.mjs +68 -0
  55. package/bin/lib/repositoryDelivery.mjs +64 -0
  56. package/bin/lib/repositoryMerge.mjs +116 -0
  57. package/bin/lib/repositoryPlaces.mjs +179 -0
  58. package/bin/lib/repositorySetup.mjs +58 -0
  59. package/bin/lib/repositoryTool.mjs +71 -0
  60. package/bin/lib/runTurn.mjs +58 -18
  61. package/bin/lib/runtimeAntigravity.mjs +2 -1
  62. package/bin/lib/runtimeCapabilities.mjs +77 -3
  63. package/bin/lib/runtimeClaude.mjs +31 -10
  64. package/bin/lib/runtimeCodex.mjs +28 -59
  65. package/bin/lib/runtimeDetection.mjs +6 -0
  66. package/bin/lib/runtimeEvents.mjs +12 -1
  67. package/bin/lib/runtimeOfferings.mjs +75 -3
  68. package/bin/lib/shipMerge.mjs +5 -2
  69. package/bin/lib/startProject.mjs +4 -4
  70. package/bin/lib/trace.mjs +8 -3
  71. package/bin/lib/turnDeclaration.mjs +88 -0
  72. package/bin/lib/turnDiagnostics.mjs +93 -0
  73. package/bin/lib/turnLock.mjs +48 -8
  74. package/bin/lib/turnProfile.mjs +15 -3
  75. package/bin/lib/work.mjs +48 -29
  76. package/bin/lib/workAgentBrief.mjs +92 -0
  77. package/bin/lib/workAgentBriefRunner.mjs +59 -0
  78. package/bin/lib/workAgentCheck.mjs +6 -5
  79. package/bin/lib/workAgentMerges.mjs +19 -2
  80. package/bin/lib/workAgentPlans.mjs +21 -70
  81. package/bin/lib/workAgentPrecheck.mjs +10 -5
  82. package/bin/lib/workAgentPublish.mjs +18 -5
  83. package/bin/lib/workAgentRecovery.mjs +85 -0
  84. package/bin/lib/workAgentReview.mjs +5 -3
  85. package/bin/lib/workAgentTurnBegun.mjs +6 -4
  86. package/bin/lib/workAgentTurnExecution.mjs +167 -29
  87. package/bin/lib/workAgentTurnOutcome.mjs +20 -5
  88. package/bin/lib/workAgentTurns.mjs +92 -12
  89. package/bin/lib/workArtifactReconcile.mjs +79 -0
  90. package/bin/lib/workCappedTurn.mjs +10 -0
  91. package/bin/lib/workCommandAudit.mjs +8 -1
  92. package/bin/lib/workDelivery.mjs +21 -0
  93. package/bin/lib/workDiffs.mjs +18 -11
  94. package/bin/lib/workLiveMessages.mjs +129 -0
  95. package/bin/lib/workPlaceReports.mjs +5 -0
  96. package/bin/lib/workPlaces.mjs +24 -3
  97. package/bin/lib/workRetire.mjs +5 -0
  98. package/bin/lib/workSessionTurns.mjs +219 -52
  99. package/bin/lib/workShip.mjs +17 -16
  100. package/bin/lib/workToolLog.mjs +70 -3
  101. package/bin/lib/workTurnShape.mjs +6 -4
  102. package/package.json +7 -3
  103. package/npm-shrinkwrap.json +0 -59
@@ -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
- const pushToolEvent = (name, input) => {
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
- return shape.planSentence ? `${contract}\n\n${PLAN_TURN_SENTENCE}` : contract;
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.117.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/cli.git"
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/cli/issues"
43
+ "url": "https://github.com/Flowviant/flowviant/issues"
44
+ },
45
+ "devDependencies": {
46
+ "three": "0.180.0"
43
47
  }
44
48
  }
@@ -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
- }