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.
- package/README.md +66 -12
- package/bin/cli.mjs +50 -17
- package/bin/lib/admission.mjs +7 -14
- 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 +83 -0
- package/bin/lib/agentPlan.mjs +134 -31
- package/bin/lib/agentPrerequisiteContract.mjs +43 -0
- package/bin/lib/agentPublish.mjs +12 -13
- package/bin/lib/agentTaskKinds.mjs +5 -8
- package/bin/lib/agySessions.mjs +3 -3
- package/bin/lib/artifactContracts.mjs +91 -20
- package/bin/lib/artifactIteration.mjs +182 -0
- package/bin/lib/artifactPreview.mjs +92 -18
- package/bin/lib/artifactRecovery.mjs +36 -0
- package/bin/lib/artifactReporter.mjs +194 -22
- package/bin/lib/artifacts.mjs +70 -63
- package/bin/lib/authproxy.mjs +2 -1
- package/bin/lib/childEnv.mjs +9 -4
- package/bin/lib/claude.mjs +10 -20
- package/bin/lib/claudeAuth.mjs +15 -5
- package/bin/lib/claudePersonal.mjs +71 -6
- package/bin/lib/claudePosture.mjs +227 -54
- package/bin/lib/claudeSessions.mjs +7 -7
- package/bin/lib/claudeStream.mjs +27 -13
- package/bin/lib/cliLimit.mjs +2 -2
- package/bin/lib/codexHome.mjs +17 -0
- package/bin/lib/codexPersonal.mjs +44 -3
- package/bin/lib/codexProjectRead.mjs +63 -0
- package/bin/lib/codexRelay.mjs +21 -5
- package/bin/lib/codexResearch.mjs +193 -0
- package/bin/lib/commandSpecs.mjs +6 -0
- package/bin/lib/config.mjs +37 -24
- package/bin/lib/conversationIds.mjs +51 -0
- package/bin/lib/credentials.mjs +2 -7
- package/bin/lib/daemonLocks.mjs +90 -0
- package/bin/lib/daemonState.mjs +5 -5
- package/bin/lib/deploy.mjs +6 -9
- package/bin/lib/deployCheckout.mjs +26 -22
- package/bin/lib/deployRunner.mjs +54 -18
- package/bin/lib/deployWire.mjs +32 -23
- package/bin/lib/desktopContract.mjs +6 -5
- package/bin/lib/discoveryContract.mjs +19 -0
- package/bin/lib/env.mjs +104 -35
- package/bin/lib/fleet.mjs +53 -13
- package/bin/lib/fleetPost.mjs +172 -25
- package/bin/lib/fleetReports.mjs +172 -171
- package/bin/lib/fleetStartup.mjs +6 -6
- package/bin/lib/fleetWire.mjs +42 -0
- package/bin/lib/git.mjs +111 -61
- package/bin/lib/gitMergeIdentity.mjs +2 -8
- package/bin/lib/grant.mjs +23 -7
- package/bin/lib/holder.mjs +108 -81
- package/bin/lib/hooks/mcpAllow.mjs +60 -0
- package/bin/lib/hooks/readGuard.mjs +54 -11
- package/bin/lib/imageArtifact.mjs +74 -0
- package/bin/lib/install.mjs +80 -33
- package/bin/lib/instance.mjs +36 -83
- package/bin/lib/intakeDraft.mjs +4 -1
- package/bin/lib/knowledgeFileSync.mjs +31 -0
- package/bin/lib/knowledgeFiles.mjs +28 -83
- package/bin/lib/landed.mjs +22 -29
- package/bin/lib/launchCommand.mjs +91 -0
- package/bin/lib/listeners.mjs +0 -5
- package/bin/lib/localSessions.mjs +52 -39
- package/bin/lib/login.mjs +22 -12
- package/bin/lib/loginPath.mjs +22 -17
- package/bin/lib/machineListing.mjs +6 -3
- package/bin/lib/maintenance.mjs +47 -0
- package/bin/lib/maintenanceInventory.mjs +39 -0
- package/bin/lib/mcp-cli.mjs +9 -10
- package/bin/lib/mcpInstall.mjs +163 -0
- package/bin/lib/mcpInventory.mjs +119 -0
- package/bin/lib/noWindowEnv.mjs +23 -3
- package/bin/lib/ownedDirs.mjs +99 -0
- package/bin/lib/pinnedCapture.mjs +383 -0
- package/bin/lib/planDependencies.mjs +70 -0
- package/bin/lib/postureTools.mjs +85 -0
- package/bin/lib/prWorkflow.mjs +94 -17
- package/bin/lib/preflight.mjs +8 -25
- package/bin/lib/preview.mjs +19 -25
- package/bin/lib/previewGatePolicy.mjs +34 -9
- package/bin/lib/previewRegistry.mjs +4 -11
- package/bin/lib/printable.mjs +70 -7
- package/bin/lib/procRegistry.mjs +33 -13
- package/bin/lib/procScan.mjs +2 -3
- package/bin/lib/procStat.mjs +76 -0
- package/bin/lib/processGroup.mjs +48 -0
- package/bin/lib/processes.mjs +10 -24
- package/bin/lib/projectToolRuntimes.mjs +328 -19
- package/bin/lib/projectTools.mjs +109 -34
- package/bin/lib/prompts.mjs +205 -60
- package/bin/lib/repoPath.mjs +19 -0
- package/bin/lib/repoState.mjs +17 -19
- package/bin/lib/repositoryBaseline.mjs +68 -0
- package/bin/lib/runTurn.mjs +286 -209
- package/bin/lib/runtimeAntigravity.mjs +16 -5
- package/bin/lib/runtimeCapabilities.mjs +215 -21
- package/bin/lib/runtimeClaude.mjs +78 -10
- package/bin/lib/runtimeCodex.mjs +217 -209
- package/bin/lib/runtimeDetection.mjs +8 -2
- package/bin/lib/runtimeEvents.mjs +28 -11
- package/bin/lib/runtimeLimits.mjs +5 -6
- package/bin/lib/runtimeOfferings.mjs +99 -14
- package/bin/lib/runtimes.mjs +10 -0
- package/bin/lib/shipSweep.mjs +5 -3
- package/bin/lib/shot.mjs +91 -17
- package/bin/lib/sleep.mjs +11 -0
- package/bin/lib/startProject.mjs +5 -5
- package/bin/lib/statePaths.mjs +40 -0
- package/bin/lib/tty.mjs +25 -15
- package/bin/lib/turnDiagnostics.mjs +93 -0
- package/bin/lib/turnLock.mjs +7 -14
- package/bin/lib/turnProfile.mjs +16 -4
- package/bin/lib/ui.mjs +0 -3
- package/bin/lib/uninstall.mjs +30 -26
- package/bin/lib/update.mjs +79 -27
- package/bin/lib/uplinkScrub.mjs +296 -31
- package/bin/lib/vault.mjs +78 -10
- package/bin/lib/vaultDiff.mjs +5 -2
- package/bin/lib/views.mjs +37 -12
- package/bin/lib/wikiRunner.mjs +40 -61
- package/bin/lib/work.mjs +44 -13
- package/bin/lib/workAdoptCarry.mjs +2 -4
- package/bin/lib/workAgentBrief.mjs +92 -0
- package/bin/lib/workAgentBriefRunner.mjs +59 -0
- package/bin/lib/workAgentCheck.mjs +104 -57
- package/bin/lib/workAgentMerges.mjs +62 -57
- package/bin/lib/workAgentPlans.mjs +82 -199
- package/bin/lib/workAgentPrecheck.mjs +76 -138
- package/bin/lib/workAgentPublish.mjs +6 -8
- package/bin/lib/workAgentTurnBegun.mjs +15 -11
- package/bin/lib/workAgentTurnExecution.mjs +131 -67
- package/bin/lib/workAgentTurnOutcome.mjs +11 -2
- package/bin/lib/workAgentTurnReports.mjs +9 -37
- package/bin/lib/workAgentTurns.mjs +64 -7
- package/bin/lib/workArtifactReconcile.mjs +79 -0
- package/bin/lib/workAttachments.mjs +66 -11
- package/bin/lib/workBrain.mjs +9 -4
- package/bin/lib/workCappedTurn.mjs +119 -0
- package/bin/lib/workChildren.mjs +5 -5
- package/bin/lib/workCommandAudit.mjs +18 -2
- package/bin/lib/workDiffs.mjs +52 -6
- package/bin/lib/workIntake.mjs +35 -60
- package/bin/lib/workPlaceReports.mjs +7 -4
- package/bin/lib/workPlaces.mjs +113 -31
- package/bin/lib/workPreviews.mjs +47 -112
- package/bin/lib/workProcesses.mjs +8 -35
- package/bin/lib/workPullRequests.mjs +37 -56
- package/bin/lib/workReportQueue.mjs +100 -148
- package/bin/lib/workRetire.mjs +2 -1
- package/bin/lib/workSessionRuntime.mjs +38 -37
- package/bin/lib/workSessionTurns.mjs +256 -199
- package/bin/lib/workShip.mjs +43 -23
- package/bin/lib/workToolLog.mjs +70 -3
- package/bin/lib/workTurnShape.mjs +165 -0
- package/npm-shrinkwrap.json +69 -0
- package/package.json +9 -4
- package/bin/lib/fleetJobs.mjs +0 -120
- package/bin/lib/patchRevert.mjs +0 -60
package/bin/lib/repoState.mjs
CHANGED
|
@@ -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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
|
53
|
-
*
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
* `
|
|
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
|
+
}
|