flowviant 0.116.0 → 0.124.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.
Files changed (161) hide show
  1. package/README.md +66 -12
  2. package/bin/cli.mjs +50 -17
  3. package/bin/lib/admission.mjs +7 -14
  4. package/bin/lib/agentAsk.mjs +123 -0
  5. package/bin/lib/agentBrief.mjs +36 -0
  6. package/bin/lib/agentFootprint.mjs +76 -0
  7. package/bin/lib/agentInternalWait.mjs +83 -0
  8. package/bin/lib/agentPlan.mjs +134 -31
  9. package/bin/lib/agentPrerequisiteContract.mjs +43 -0
  10. package/bin/lib/agentPublish.mjs +12 -13
  11. package/bin/lib/agentTaskKinds.mjs +5 -8
  12. package/bin/lib/agySessions.mjs +3 -3
  13. package/bin/lib/artifactContracts.mjs +91 -20
  14. package/bin/lib/artifactIteration.mjs +182 -0
  15. package/bin/lib/artifactPreview.mjs +92 -18
  16. package/bin/lib/artifactRecovery.mjs +36 -0
  17. package/bin/lib/artifactReporter.mjs +194 -22
  18. package/bin/lib/artifacts.mjs +70 -63
  19. package/bin/lib/authproxy.mjs +2 -1
  20. package/bin/lib/childEnv.mjs +9 -4
  21. package/bin/lib/claude.mjs +10 -20
  22. package/bin/lib/claudeAuth.mjs +15 -5
  23. package/bin/lib/claudePersonal.mjs +71 -6
  24. package/bin/lib/claudePosture.mjs +227 -54
  25. package/bin/lib/claudeSessions.mjs +7 -7
  26. package/bin/lib/claudeStream.mjs +27 -13
  27. package/bin/lib/cliLimit.mjs +2 -2
  28. package/bin/lib/codexHome.mjs +17 -0
  29. package/bin/lib/codexPersonal.mjs +44 -3
  30. package/bin/lib/codexProjectRead.mjs +63 -0
  31. package/bin/lib/codexRelay.mjs +21 -5
  32. package/bin/lib/codexResearch.mjs +193 -0
  33. package/bin/lib/commandSpecs.mjs +6 -0
  34. package/bin/lib/config.mjs +37 -24
  35. package/bin/lib/conversationIds.mjs +51 -0
  36. package/bin/lib/credentials.mjs +2 -7
  37. package/bin/lib/daemonLocks.mjs +90 -0
  38. package/bin/lib/daemonState.mjs +5 -5
  39. package/bin/lib/deploy.mjs +6 -9
  40. package/bin/lib/deployCheckout.mjs +26 -22
  41. package/bin/lib/deployRunner.mjs +54 -18
  42. package/bin/lib/deployWire.mjs +32 -23
  43. package/bin/lib/desktopContract.mjs +6 -5
  44. package/bin/lib/discoveryContract.mjs +19 -0
  45. package/bin/lib/env.mjs +104 -35
  46. package/bin/lib/fleet.mjs +53 -13
  47. package/bin/lib/fleetPost.mjs +172 -25
  48. package/bin/lib/fleetReports.mjs +172 -171
  49. package/bin/lib/fleetStartup.mjs +6 -6
  50. package/bin/lib/fleetWire.mjs +42 -0
  51. package/bin/lib/git.mjs +111 -61
  52. package/bin/lib/gitMergeIdentity.mjs +2 -8
  53. package/bin/lib/grant.mjs +23 -7
  54. package/bin/lib/holder.mjs +108 -81
  55. package/bin/lib/hooks/mcpAllow.mjs +60 -0
  56. package/bin/lib/hooks/readGuard.mjs +54 -11
  57. package/bin/lib/imageArtifact.mjs +74 -0
  58. package/bin/lib/install.mjs +80 -33
  59. package/bin/lib/instance.mjs +36 -83
  60. package/bin/lib/intakeDraft.mjs +4 -1
  61. package/bin/lib/knowledgeFileSync.mjs +31 -0
  62. package/bin/lib/knowledgeFiles.mjs +28 -83
  63. package/bin/lib/landed.mjs +22 -29
  64. package/bin/lib/launchCommand.mjs +91 -0
  65. package/bin/lib/listeners.mjs +0 -5
  66. package/bin/lib/localSessions.mjs +52 -39
  67. package/bin/lib/login.mjs +22 -12
  68. package/bin/lib/loginPath.mjs +22 -17
  69. package/bin/lib/machineListing.mjs +6 -3
  70. package/bin/lib/maintenance.mjs +47 -0
  71. package/bin/lib/maintenanceInventory.mjs +39 -0
  72. package/bin/lib/mcp-cli.mjs +9 -10
  73. package/bin/lib/mcpInstall.mjs +163 -0
  74. package/bin/lib/mcpInventory.mjs +119 -0
  75. package/bin/lib/noWindowEnv.mjs +23 -3
  76. package/bin/lib/ownedDirs.mjs +99 -0
  77. package/bin/lib/pinnedCapture.mjs +383 -0
  78. package/bin/lib/planDependencies.mjs +70 -0
  79. package/bin/lib/postureTools.mjs +85 -0
  80. package/bin/lib/prWorkflow.mjs +94 -17
  81. package/bin/lib/preflight.mjs +8 -25
  82. package/bin/lib/preview.mjs +19 -25
  83. package/bin/lib/previewGatePolicy.mjs +34 -9
  84. package/bin/lib/previewRegistry.mjs +4 -11
  85. package/bin/lib/printable.mjs +70 -7
  86. package/bin/lib/procRegistry.mjs +33 -13
  87. package/bin/lib/procScan.mjs +2 -3
  88. package/bin/lib/procStat.mjs +76 -0
  89. package/bin/lib/processGroup.mjs +48 -0
  90. package/bin/lib/processes.mjs +10 -24
  91. package/bin/lib/projectToolRuntimes.mjs +328 -19
  92. package/bin/lib/projectTools.mjs +109 -34
  93. package/bin/lib/prompts.mjs +205 -60
  94. package/bin/lib/repoPath.mjs +19 -0
  95. package/bin/lib/repoState.mjs +17 -19
  96. package/bin/lib/repositoryBaseline.mjs +68 -0
  97. package/bin/lib/runTurn.mjs +286 -209
  98. package/bin/lib/runtimeAntigravity.mjs +16 -5
  99. package/bin/lib/runtimeCapabilities.mjs +215 -21
  100. package/bin/lib/runtimeClaude.mjs +78 -10
  101. package/bin/lib/runtimeCodex.mjs +217 -209
  102. package/bin/lib/runtimeDetection.mjs +8 -2
  103. package/bin/lib/runtimeEvents.mjs +28 -11
  104. package/bin/lib/runtimeLimits.mjs +5 -6
  105. package/bin/lib/runtimeOfferings.mjs +99 -14
  106. package/bin/lib/runtimes.mjs +10 -0
  107. package/bin/lib/shipSweep.mjs +5 -3
  108. package/bin/lib/shot.mjs +91 -17
  109. package/bin/lib/sleep.mjs +11 -0
  110. package/bin/lib/startProject.mjs +5 -5
  111. package/bin/lib/statePaths.mjs +40 -0
  112. package/bin/lib/tty.mjs +25 -15
  113. package/bin/lib/turnDiagnostics.mjs +93 -0
  114. package/bin/lib/turnLock.mjs +7 -14
  115. package/bin/lib/turnProfile.mjs +16 -4
  116. package/bin/lib/ui.mjs +0 -3
  117. package/bin/lib/uninstall.mjs +30 -26
  118. package/bin/lib/update.mjs +79 -27
  119. package/bin/lib/uplinkScrub.mjs +296 -31
  120. package/bin/lib/vault.mjs +78 -10
  121. package/bin/lib/vaultDiff.mjs +5 -2
  122. package/bin/lib/views.mjs +37 -12
  123. package/bin/lib/wikiRunner.mjs +40 -61
  124. package/bin/lib/work.mjs +44 -13
  125. package/bin/lib/workAdoptCarry.mjs +2 -4
  126. package/bin/lib/workAgentBrief.mjs +92 -0
  127. package/bin/lib/workAgentBriefRunner.mjs +59 -0
  128. package/bin/lib/workAgentCheck.mjs +104 -57
  129. package/bin/lib/workAgentMerges.mjs +62 -57
  130. package/bin/lib/workAgentPlans.mjs +82 -199
  131. package/bin/lib/workAgentPrecheck.mjs +76 -138
  132. package/bin/lib/workAgentPublish.mjs +6 -8
  133. package/bin/lib/workAgentTurnBegun.mjs +15 -11
  134. package/bin/lib/workAgentTurnExecution.mjs +131 -67
  135. package/bin/lib/workAgentTurnOutcome.mjs +11 -2
  136. package/bin/lib/workAgentTurnReports.mjs +9 -37
  137. package/bin/lib/workAgentTurns.mjs +64 -7
  138. package/bin/lib/workArtifactReconcile.mjs +79 -0
  139. package/bin/lib/workAttachments.mjs +66 -11
  140. package/bin/lib/workBrain.mjs +9 -4
  141. package/bin/lib/workCappedTurn.mjs +119 -0
  142. package/bin/lib/workChildren.mjs +5 -5
  143. package/bin/lib/workCommandAudit.mjs +18 -2
  144. package/bin/lib/workDiffs.mjs +52 -6
  145. package/bin/lib/workIntake.mjs +35 -60
  146. package/bin/lib/workPlaceReports.mjs +7 -4
  147. package/bin/lib/workPlaces.mjs +113 -31
  148. package/bin/lib/workPreviews.mjs +47 -112
  149. package/bin/lib/workProcesses.mjs +8 -35
  150. package/bin/lib/workPullRequests.mjs +37 -56
  151. package/bin/lib/workReportQueue.mjs +100 -148
  152. package/bin/lib/workRetire.mjs +2 -1
  153. package/bin/lib/workSessionRuntime.mjs +38 -37
  154. package/bin/lib/workSessionTurns.mjs +256 -199
  155. package/bin/lib/workShip.mjs +43 -23
  156. package/bin/lib/workToolLog.mjs +70 -3
  157. package/bin/lib/workTurnShape.mjs +165 -0
  158. package/npm-shrinkwrap.json +69 -0
  159. package/package.json +9 -4
  160. package/bin/lib/fleetJobs.mjs +0 -120
  161. package/bin/lib/patchRevert.mjs +0 -60
@@ -31,29 +31,26 @@
31
31
  * repo mid-rebase or an unborn HEAD is a field to omit, not an error to raise.
32
32
  */
33
33
 
34
- import { execFileSync } from 'node:child_process';
35
34
  import { measureListeners, listenersSupported } from './listeners.mjs';
35
+ import { git, GIT_WIDE_BUFFER, isSessionBranch } from './git.mjs';
36
36
 
37
37
  /** Same cap the session diffstat uses: enough to see the shape, small enough
38
38
  * that one machine cannot flood a row. */
39
39
  const MAX_BRANCHES = 60;
40
40
  const MAX_WORKTREES = 40;
41
41
 
42
- function git(args, cwd) {
43
- return execFileSync('git', args, {
44
- cwd,
45
- encoding: 'utf8',
46
- stdio: ['ignore', 'pipe', 'ignore'],
47
- timeout: 10_000,
48
- maxBuffer: 8 * 1024 * 1024,
49
- }).trim();
50
- }
42
+ /** Every read here is BOUNDED and QUIET: a best-effort report in the poll
43
+ * loop must neither hold the event loop on a wedged git nor print git's
44
+ * complaints about a repo mid-rebase onto the daemon's terminal. git.mjs's
45
+ * own `git()`, with those options (audit 2026-10-10, F107) — this module
46
+ * used to declare a private `function git` of the same name with different
47
+ * semantics, so a reader could not tell which one a call meant. */
48
+ const READ = Object.freeze({ timeout: 10_000, maxBuffer: GIT_WIDE_BUFFER, stdio: ['ignore', 'pipe', 'ignore'] });
51
49
 
52
- /** A ref Flowviant itself cut for a tab. The ONLY thing that makes a branch
53
- * "ours", and the distinction the whole report exists to draw. */
54
- export function isSessionBranch(name) {
55
- return /^session\//.test(name);
56
- }
50
+ /** A ref Flowviant itself cut for a tab — the distinction the whole report
51
+ * exists to draw. Defined beside the branch-name writer in git.mjs (audit
52
+ * 2026-10-10, F122) and re-exported here for this report's readers. */
53
+ export { isSessionBranch };
57
54
 
58
55
  /**
59
56
  * `git worktree list --porcelain` → rows. The porcelain form is parsed rather
@@ -63,7 +60,7 @@ export function isSessionBranch(name) {
63
60
  function readWorktrees(repoRoot) {
64
61
  let out;
65
62
  try {
66
- out = git(['worktree', 'list', '--porcelain'], repoRoot);
63
+ out = git(['worktree', 'list', '--porcelain'], repoRoot, READ);
67
64
  } catch {
68
65
  return null; // not a git repo, or git is unhappy — say nothing
69
66
  }
@@ -103,13 +100,14 @@ function readBranches(repoRoot, baseRef) {
103
100
  const fmt = '%(refname:short)%09%(committerdate:unix)%09%(ahead-behind:' + baseRef + ')';
104
101
  let out;
105
102
  try {
106
- out = git(['for-each-ref', '--sort=-committerdate', `--format=${fmt}`, 'refs/heads'], repoRoot);
103
+ out = git(['for-each-ref', '--sort=-committerdate', `--format=${fmt}`, 'refs/heads'], repoRoot, READ);
107
104
  } catch {
108
105
  // No ahead-behind on this git. Names and dates still answer most of it.
109
106
  try {
110
107
  out = git(
111
108
  ['for-each-ref', '--sort=-committerdate', '--format=%(refname:short)%09%(committerdate:unix)', 'refs/heads'],
112
- repoRoot
109
+ repoRoot,
110
+ READ
113
111
  );
114
112
  } catch {
115
113
  return null;
@@ -146,7 +144,7 @@ export function repoState(repoRoot, baseRef) {
146
144
  /**
147
145
  * WHAT IS LISTENING IN THE CHECKOUT ITSELF.
148
146
  *
149
- * `listenersIn` has always taken any directory, and had only ever been asked
147
+ * `measureListeners` has always taken any directory, and had only ever been asked
150
148
  * about SESSION WORKTREES — so somebody running `npm run dev` in their normal
151
149
  * checkout, which is what "just testing or playing around in dev" actually
152
150
  * looks like, was invisible to every surface in the product. The measurement
@@ -0,0 +1,68 @@
1
+ /** Point-in-time repository facts. Reads only; never refreshes a worktree. */
2
+ import { git } from './git.mjs';
3
+ import { scrubCut } from './uplinkScrub.mjs';
4
+
5
+ const sha = /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/;
6
+ export function measureRepositoryBaseline({ cwd, baseRef, knowledgeDir = null, readGit = git }) {
7
+ const opts = { timeout: 5000, maxBuffer: 128 * 1024, env: { ...process.env, GIT_OPTIONAL_LOCKS: '0' }, stdio: ['ignore', 'pipe', 'pipe'] };
8
+ const read = (args, convert, category = 'read_failed') => {
9
+ try { return { state: 'measured', value: convert(readGit(args, cwd, opts)) }; }
10
+ catch (e) { return { state: 'error', errorCategory: e?.code === 'ENOENT' ? 'git_unavailable' : e?.code === 'ENOBUFS' ? 'bounded' : category }; }
11
+ };
12
+ const commit = s => { if (!sha.test(s)) throw new Error('unresolved ref'); return s; };
13
+ let ref;
14
+ let refFailed = false;
15
+ try { ref = typeof baseRef === 'function' ? baseRef() : baseRef; } catch { refFailed = true; }
16
+ const head = read(['rev-parse', '--verify', 'HEAD'], commit, 'unresolved_ref');
17
+ const base = typeof ref === 'string' && ref ? read(['rev-parse', '--verify', '--end-of-options', `${ref}^{commit}`], commit, 'unresolved_ref') : refFailed ? { state: 'error', errorCategory: 'read_failed' } : { state: 'unknown' };
18
+ const dirty = read(['status', '--porcelain=v1', '-z', '--untracked-files=normal'], s => s.length > 0);
19
+ const shallow = read(['rev-parse', '--is-shallow-repository'], s => { if (s !== 'true' && s !== 'false') throw new Error('unknown'); return s === 'true'; });
20
+ let relation = 'unknown';
21
+ if (head.state === 'measured' && base.state === 'measured') {
22
+ if (head.value === base.value) relation = 'same';
23
+ else {
24
+ const ancestor = (a, b) => {
25
+ try { readGit(['merge-base', '--is-ancestor', a, b], cwd, opts); return true; }
26
+ catch (e) { return e?.status === 1 ? false : null; }
27
+ };
28
+ const behind = ancestor(head.value, base.value);
29
+ const ahead = ancestor(base.value, head.value);
30
+ relation = behind === true ? 'behind' : ahead === true ? 'ahead' : behind === false && ahead === false && shallow.state === 'measured' && shallow.value === false ? 'diverged' : 'unknown';
31
+ }
32
+ }
33
+ return {
34
+ measuredAt: new Date().toISOString(), cwd: scrubCut(cwd, 500),
35
+ head, base: { ref: typeof ref === 'string' ? scrubCut(ref, 300) : null, head: base }, dirty, relation,
36
+ shallow,
37
+ knowledgeDir: knowledgeDir ? scrubCut(knowledgeDir, 500) : null,
38
+ historyComparison: { state: 'unknown' }, deployment: { state: 'unknown' },
39
+ };
40
+ }
41
+
42
+ /** Revalidate the report, never splice arbitrary wire prose into a system prompt. */
43
+ export function repositoryBaselineOf(raw) {
44
+ if (!raw || typeof raw !== 'object' || typeof raw.cwd !== 'string' || typeof raw.measuredAt !== 'string') return null;
45
+ const field = (f, boolean = false) => {
46
+ if (f?.state === 'measured' && (boolean ? typeof f.value === 'boolean' : typeof f.value === 'string' && sha.test(f.value))) return { state: 'measured', value: f.value };
47
+ if (f?.state === 'error') return { state: 'error', errorCategory: ['git_unavailable', 'unresolved_ref', 'read_failed', 'bounded'].includes(f.errorCategory) ? f.errorCategory : 'read_failed' };
48
+ return { state: 'unknown' };
49
+ };
50
+ return {
51
+ cwd: scrubCut(raw.cwd, 500), measuredAt: scrubCut(raw.measuredAt, 40),
52
+ head: field(raw.head), base: { ref: typeof raw.base?.ref === 'string' ? scrubCut(raw.base.ref, 300) : null, head: field(raw.base?.head) },
53
+ dirty: field(raw.dirty, true), shallow: field(raw.shallow, true),
54
+ relation: ['same', 'behind', 'ahead', 'diverged'].includes(raw.relation) ? raw.relation : 'unknown',
55
+ knowledgeDir: typeof raw.knowledgeDir === 'string' ? scrubCut(raw.knowledgeDir, 500) : null,
56
+ historyComparison: { state: 'unknown' }, deployment: { state: 'unknown' },
57
+ };
58
+ }
59
+
60
+ export function compareRepositoryBaselines(planner, capture) {
61
+ const head = planner.head.state === 'measured' && capture?.head.state === 'measured'
62
+ ? planner.head.value === capture.head.value ? 'same' : 'different' : 'unknown';
63
+ const cwd = capture ? planner.cwd === capture.cwd ? 'same' : 'different' : 'unknown';
64
+ const dirty = planner.dirty.state === 'measured' && capture?.dirty.state === 'measured'
65
+ ? planner.dirty.value || capture.dirty.value ? 'dirty' : 'clean' : 'unknown';
66
+ return { head, cwd, dirty, execution: planner.relation,
67
+ reconciliation: head === 'different' || dirty === 'dirty' || ['behind', 'ahead', 'diverged'].includes(planner.relation) ? 'required' : head === 'unknown' || dirty === 'unknown' ? 'unverified' : 'aligned' };
68
+ }