@mrpatronz/nexusflow 2.7.0 → 2.8.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 +16 -14
- package/dist/agent/ClaudeSdkAdapter.d.ts.map +1 -1
- package/dist/agent/ClaudeSdkAdapter.js +31 -8
- package/dist/agent/ClaudeSdkAdapter.js.map +1 -1
- package/dist/agent/ClaudeSdkAdapter.test.js +18 -6
- package/dist/agent/ClaudeSdkAdapter.test.js.map +1 -1
- package/dist/agent/CodexCliAdapter.d.ts +1 -1
- package/dist/agent/CodexCliAdapter.d.ts.map +1 -1
- package/dist/agent/CodexCliAdapter.js +5 -4
- package/dist/agent/CodexCliAdapter.js.map +1 -1
- package/dist/agent/CodexCliAdapter.test.js +16 -1
- package/dist/agent/CodexCliAdapter.test.js.map +1 -1
- package/dist/agent/CodexSdkAdapter.d.ts.map +1 -1
- package/dist/agent/CodexSdkAdapter.js +6 -0
- package/dist/agent/CodexSdkAdapter.js.map +1 -1
- package/dist/agent/ProviderRegistry.d.ts +5 -0
- package/dist/agent/ProviderRegistry.d.ts.map +1 -1
- package/dist/agent/ProviderRegistry.js +15 -0
- package/dist/agent/ProviderRegistry.js.map +1 -1
- package/dist/agent/ProviderRegistry.test.js +19 -0
- package/dist/agent/ProviderRegistry.test.js.map +1 -1
- package/dist/agent/adapters.d.ts.map +1 -1
- package/dist/agent/adapters.js +5 -0
- package/dist/agent/adapters.js.map +1 -1
- package/dist/agent/mcp-config.d.ts +16 -0
- package/dist/agent/mcp-config.d.ts.map +1 -0
- package/dist/agent/mcp-config.js +28 -0
- package/dist/agent/mcp-config.js.map +1 -0
- package/dist/agent/mcp-config.test.d.ts +2 -0
- package/dist/agent/mcp-config.test.d.ts.map +1 -0
- package/dist/agent/mcp-config.test.js +22 -0
- package/dist/agent/mcp-config.test.js.map +1 -0
- package/dist/agent/models.d.ts +10 -0
- package/dist/agent/models.d.ts.map +1 -0
- package/dist/agent/models.js +35 -0
- package/dist/agent/models.js.map +1 -0
- package/dist/agent/models.test.d.ts +2 -0
- package/dist/agent/models.test.d.ts.map +1 -0
- package/dist/agent/models.test.js +40 -0
- package/dist/agent/models.test.js.map +1 -0
- package/dist/agent/orchestrator.d.ts +65 -0
- package/dist/agent/orchestrator.d.ts.map +1 -0
- package/dist/agent/orchestrator.js +260 -0
- package/dist/agent/orchestrator.js.map +1 -0
- package/dist/agent/orchestrator.test.d.ts +2 -0
- package/dist/agent/orchestrator.test.d.ts.map +1 -0
- package/dist/agent/orchestrator.test.js +284 -0
- package/dist/agent/orchestrator.test.js.map +1 -0
- package/dist/agent/session.d.ts +1 -0
- package/dist/agent/session.d.ts.map +1 -1
- package/dist/agent/session.js +3 -2
- package/dist/agent/session.js.map +1 -1
- package/dist/agent/session.test.js +9 -0
- package/dist/agent/session.test.js.map +1 -1
- package/dist/agent/smoke-chat.test.d.ts +2 -0
- package/dist/agent/smoke-chat.test.d.ts.map +1 -0
- package/dist/agent/smoke-chat.test.js +166 -0
- package/dist/agent/smoke-chat.test.js.map +1 -0
- package/dist/commands/commands.test.js +3 -0
- package/dist/commands/commands.test.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +2 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.d.ts +3 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +9 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/knowledge.d.ts +9 -0
- package/dist/commands/knowledge.d.ts.map +1 -1
- package/dist/commands/knowledge.js +59 -2
- package/dist/commands/knowledge.js.map +1 -1
- package/dist/commands/knowledge.test.js +14 -1
- package/dist/commands/knowledge.test.js.map +1 -1
- package/dist/commands/mcp.d.ts +7 -1
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +7 -2
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/progress.d.ts +4 -0
- package/dist/commands/progress.d.ts.map +1 -0
- package/dist/commands/progress.js +33 -0
- package/dist/commands/progress.js.map +1 -0
- package/dist/commands/refresh.d.ts +1 -0
- package/dist/commands/refresh.d.ts.map +1 -1
- package/dist/commands/refresh.js +17 -2
- package/dist/commands/refresh.js.map +1 -1
- package/dist/commands/remote.d.ts +4 -0
- package/dist/commands/remote.d.ts.map +1 -0
- package/dist/commands/remote.js +28 -0
- package/dist/commands/remote.js.map +1 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +14 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/status.test.d.ts +2 -0
- package/dist/commands/status.test.d.ts.map +1 -0
- package/dist/commands/status.test.js +31 -0
- package/dist/commands/status.test.js.map +1 -0
- package/dist/core/analysis-cache.d.ts +13 -3
- package/dist/core/analysis-cache.d.ts.map +1 -1
- package/dist/core/analysis-cache.js +41 -31
- package/dist/core/analysis-cache.js.map +1 -1
- package/dist/core/analysis-cache.test.js +50 -8
- package/dist/core/analysis-cache.test.js.map +1 -1
- package/dist/core/doctor.d.ts.map +1 -1
- package/dist/core/doctor.js +61 -0
- package/dist/core/doctor.js.map +1 -1
- package/dist/core/generation-lock.d.ts +58 -0
- package/dist/core/generation-lock.d.ts.map +1 -0
- package/dist/core/generation-lock.js +233 -0
- package/dist/core/generation-lock.js.map +1 -0
- package/dist/core/generation-lock.test.d.ts +2 -0
- package/dist/core/generation-lock.test.d.ts.map +1 -0
- package/dist/core/generation-lock.test.js +134 -0
- package/dist/core/generation-lock.test.js.map +1 -0
- package/dist/core/isolate.test.js +30 -0
- package/dist/core/isolate.test.js.map +1 -1
- package/dist/core/knowledge.d.ts +20 -0
- package/dist/core/knowledge.d.ts.map +1 -1
- package/dist/core/knowledge.js +184 -36
- package/dist/core/knowledge.js.map +1 -1
- package/dist/core/knowledge.test.js +93 -15
- package/dist/core/knowledge.test.js.map +1 -1
- package/dist/core/locks.d.ts +4 -2
- package/dist/core/locks.d.ts.map +1 -1
- package/dist/core/locks.js +55 -7
- package/dist/core/locks.js.map +1 -1
- package/dist/core/locks.test.js +48 -0
- package/dist/core/locks.test.js.map +1 -1
- package/dist/core/progress.d.ts +21 -0
- package/dist/core/progress.d.ts.map +1 -0
- package/dist/core/progress.js +40 -0
- package/dist/core/progress.js.map +1 -0
- package/dist/core/progress.test.d.ts +2 -0
- package/dist/core/progress.test.d.ts.map +1 -0
- package/dist/core/progress.test.js +52 -0
- package/dist/core/progress.test.js.map +1 -0
- package/dist/core/refresh.d.ts +5 -0
- package/dist/core/refresh.d.ts.map +1 -1
- package/dist/core/refresh.js +25 -0
- package/dist/core/refresh.js.map +1 -1
- package/dist/core/refresh.test.js +20 -0
- package/dist/core/refresh.test.js.map +1 -1
- package/dist/core/status.d.ts +2 -0
- package/dist/core/status.d.ts.map +1 -1
- package/dist/core/status.js +6 -1
- package/dist/core/status.js.map +1 -1
- package/dist/core/sync.d.ts.map +1 -1
- package/dist/core/sync.js +22 -1
- package/dist/core/sync.js.map +1 -1
- package/dist/core/sync.test.js +27 -0
- package/dist/core/sync.test.js.map +1 -1
- package/dist/core/workspace-git.d.ts +15 -0
- package/dist/core/workspace-git.d.ts.map +1 -0
- package/dist/core/workspace-git.js +131 -0
- package/dist/core/workspace-git.js.map +1 -0
- package/dist/core/workspace-git.test.d.ts +2 -0
- package/dist/core/workspace-git.test.d.ts.map +1 -0
- package/dist/core/workspace-git.test.js +52 -0
- package/dist/core/workspace-git.test.js.map +1 -0
- package/dist/core/workspace-skills-workflow.integration.test.js +15 -0
- package/dist/core/workspace-skills-workflow.integration.test.js.map +1 -1
- package/dist/core/workspace.create.test.js +5 -2
- package/dist/core/workspace.create.test.js.map +1 -1
- package/dist/core/workspace.d.ts.map +1 -1
- package/dist/core/workspace.js +11 -6
- package/dist/core/workspace.js.map +1 -1
- package/dist/generators/antigravity.d.ts.map +1 -1
- package/dist/generators/antigravity.js +2 -1
- package/dist/generators/antigravity.js.map +1 -1
- package/dist/generators/base.d.ts.map +1 -1
- package/dist/generators/base.js +5 -3
- package/dist/generators/base.js.map +1 -1
- package/dist/generators/claude.d.ts.map +1 -1
- package/dist/generators/claude.js +4 -1
- package/dist/generators/claude.js.map +1 -1
- package/dist/generators/codex.d.ts.map +1 -1
- package/dist/generators/codex.js +2 -1
- package/dist/generators/codex.js.map +1 -1
- package/dist/generators/copilot.d.ts.map +1 -1
- package/dist/generators/copilot.js +4 -3
- package/dist/generators/copilot.js.map +1 -1
- package/dist/generators/cursor.d.ts.map +1 -1
- package/dist/generators/cursor.js +6 -3
- package/dist/generators/cursor.js.map +1 -1
- package/dist/generators/index.d.ts +2 -0
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/index.js +79 -45
- package/dist/generators/index.js.map +1 -1
- package/dist/generators/knowledge-migration.test.d.ts +2 -0
- package/dist/generators/knowledge-migration.test.d.ts.map +1 -0
- package/dist/generators/knowledge-migration.test.js +22 -0
- package/dist/generators/knowledge-migration.test.js.map +1 -0
- package/dist/generators/plan-generator.d.ts.map +1 -1
- package/dist/generators/plan-generator.js +18 -9
- package/dist/generators/plan-generator.js.map +1 -1
- package/dist/generators/plan-generator.test.js +4 -1
- package/dist/generators/plan-generator.test.js.map +1 -1
- package/dist/gui/assets/AgentsPage-B4fx43rd.js +3 -0
- package/dist/gui/assets/{CSPContext-BG7no5S_.js → CSPContext-DBUu9tE0.js} +1 -1
- package/dist/gui/assets/{DashboardPage-ByGTwAQa.js → DashboardPage-DH52G8IG.js} +1 -1
- package/dist/gui/assets/{GettingStartedPage-Xjx3M3RH.js → GettingStartedPage-BlTrQhvi.js} +1 -1
- package/dist/gui/assets/ProjectsPage-BPVSLPXv.js +1 -0
- package/dist/gui/assets/ScaffoldRepoInline-ywcpq9PX.js +1 -0
- package/dist/gui/assets/{SettingsPage-B9iN6hsv.js → SettingsPage-RQr8SalV.js} +1 -1
- package/dist/gui/assets/SkillsPage-CYoSRrwx.js +6 -0
- package/dist/gui/assets/StartWorkPage-DBKK4lFi.js +1 -0
- package/dist/gui/assets/{StrategiesPage-DDu3jwJx.js → StrategiesPage-C36TZgDX.js} +1 -1
- package/dist/gui/assets/WorkspacesPage-DxEONvSq.js +6 -0
- package/dist/gui/assets/{alert-dialog-CdqVrvZl.js → alert-dialog-CQAX2yRx.js} +1 -1
- package/dist/gui/assets/index-BF6pre6G.css +2 -0
- package/dist/gui/assets/index-C_rwnBzF.js +52 -0
- package/dist/gui/assets/isElementDisabled-uy_EOitH.js +1 -0
- package/dist/gui/assets/textarea-ByfoCb54.js +1 -0
- package/dist/gui/assets/{useAriaLabelledBy-DfRdwH8a.js → useAriaLabelledBy-ClesgjMe.js} +1 -1
- package/dist/gui/assets/useValueChanged-DeYvGnKs.js +1 -0
- package/dist/gui/assets/{vsc-D6UPv2ii.js → vsc-DFh0-53h.js} +1 -1
- package/dist/gui/index.html +5 -7
- package/dist/harness/claude.d.ts +3 -1
- package/dist/harness/claude.d.ts.map +1 -1
- package/dist/harness/claude.js +4 -2
- package/dist/harness/claude.js.map +1 -1
- package/dist/harness/codex.d.ts +3 -1
- package/dist/harness/codex.d.ts.map +1 -1
- package/dist/harness/codex.js +64 -12
- package/dist/harness/codex.js.map +1 -1
- package/dist/harness/contract.test.d.ts +2 -0
- package/dist/harness/contract.test.d.ts.map +1 -0
- package/dist/harness/contract.test.js +426 -0
- package/dist/harness/contract.test.js.map +1 -0
- package/dist/harness/harness.test.js +16 -1
- package/dist/harness/harness.test.js.map +1 -1
- package/dist/harness/types.d.ts +7 -1
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/index.js +52 -5
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +8 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +11 -6
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts +6 -2
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +232 -14
- package/dist/mcp/tools.js.map +1 -1
- package/dist/mcp/tools.test.js +130 -6
- package/dist/mcp/tools.test.js.map +1 -1
- package/dist/resources/materializer.d.ts.map +1 -1
- package/dist/resources/materializer.js +11 -3
- package/dist/resources/materializer.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +37 -6
- package/dist/server.js.map +1 -1
- package/dist/server.test.js +37 -1
- package/dist/server.test.js.map +1 -1
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -1
- package/dist/gui/assets/AgentsPage-YyYRodOR.js +0 -3
- package/dist/gui/assets/ProjectsPage-BMdhqAGs.js +0 -1
- package/dist/gui/assets/ScaffoldRepoInline-gXyYSIz5.js +0 -1
- package/dist/gui/assets/SkillsPage-CxcsbIsQ.js +0 -6
- package/dist/gui/assets/StartWorkPage-DPVHcdy4.js +0 -1
- package/dist/gui/assets/WorkspacesPage-BWRmP0mY.js +0 -2
- package/dist/gui/assets/index-CZoZQkeC.css +0 -2
- package/dist/gui/assets/index-wy68EqfB.js +0 -50
- package/dist/gui/assets/isElementDisabled-D_fu2zfc.js +0 -1
- package/dist/gui/assets/store-D5DUHbxn.js +0 -3
- package/dist/gui/assets/styles-CVwNuFCx.js +0 -1
- package/dist/gui/assets/textarea-BNRuIXNs.js +0 -1
- package/dist/gui/assets/useValueChanged-CStSGSsD.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.test.d.ts","sourceRoot":"","sources":["../../src/core/progress.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { execa } from 'execa';
|
|
3
|
+
import { getWorkspaceProgress } from './progress.js';
|
|
4
|
+
import * as status from './status.js';
|
|
5
|
+
import * as pr from '../utils/pr.js';
|
|
6
|
+
vi.mock('./status.js');
|
|
7
|
+
vi.mock('../utils/pr.js');
|
|
8
|
+
vi.mock('execa');
|
|
9
|
+
describe('live workspace progress', () => {
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
vi.clearAllMocks();
|
|
12
|
+
vi.mocked(status.getWorkspaceStatusReport).mockResolvedValue({
|
|
13
|
+
workspacePath: '/ws', branchName: 'feat', allClean: true, allPushed: true,
|
|
14
|
+
repos: [{
|
|
15
|
+
name: 'api', path: '/ws/api', branch: 'feat', headSha: 'abc', expectedBranch: 'feat', onExpectedBranch: true,
|
|
16
|
+
dirty: false, changedFiles: [], ahead: 0, behind: 0, remoteUrl: 'https://github.com/acme/api.git', defaultBranch: 'main',
|
|
17
|
+
}],
|
|
18
|
+
});
|
|
19
|
+
vi.mocked(execa).mockResolvedValue({ exitCode: 0, stdout: '' });
|
|
20
|
+
});
|
|
21
|
+
it('derives branch, clean, and pushed state without inventing unavailable PR state', async () => {
|
|
22
|
+
vi.mocked(pr.detectGh).mockResolvedValue({ installed: false, authenticated: false });
|
|
23
|
+
const report = await getWorkspaceProgress('/ws');
|
|
24
|
+
expect(report.repos[0]).toMatchObject({ branchExists: true, onExpectedBranch: true, clean: true, pushed: true });
|
|
25
|
+
expect(report.repos[0]?.pullRequest).toBeUndefined();
|
|
26
|
+
});
|
|
27
|
+
it('includes PR state only when the authenticated forge adapter returns it', async () => {
|
|
28
|
+
vi.mocked(pr.detectGh).mockResolvedValue({ installed: true, authenticated: true });
|
|
29
|
+
vi.mocked(pr.parseRemoteUrl).mockReturnValue({ host: 'github.com', owner: 'acme', repo: 'api', kind: 'github' });
|
|
30
|
+
vi.mocked(execa).mockResolvedValue({ exitCode: 0, stdout: '{"state":"MERGED","url":"https://example.test/pr/1"}' });
|
|
31
|
+
const report = await getWorkspaceProgress('/ws');
|
|
32
|
+
expect(report.repos[0]?.pullRequest).toEqual({ state: 'merged', url: 'https://example.test/pr/1' });
|
|
33
|
+
});
|
|
34
|
+
it('does not claim pushed or PR progress while checked out on the wrong branch', async () => {
|
|
35
|
+
vi.mocked(status.getWorkspaceStatusReport).mockResolvedValue({
|
|
36
|
+
workspacePath: '/ws', branchName: 'feat', allClean: true, allPushed: false,
|
|
37
|
+
repos: [{
|
|
38
|
+
name: 'api', path: '/ws/api', branch: 'main', headSha: 'abc', expectedBranch: 'feat', onExpectedBranch: false,
|
|
39
|
+
dirty: false, changedFiles: [], ahead: 0, behind: 0, remoteUrl: 'https://github.com/acme/api.git', defaultBranch: 'main',
|
|
40
|
+
}],
|
|
41
|
+
});
|
|
42
|
+
vi.mocked(pr.detectGh).mockResolvedValue({ installed: true, authenticated: true });
|
|
43
|
+
vi.mocked(pr.parseRemoteUrl).mockReturnValue({ host: 'github.com', owner: 'acme', repo: 'api', kind: 'github' });
|
|
44
|
+
vi.mocked(execa).mockResolvedValue({ exitCode: 1, stdout: '' });
|
|
45
|
+
const report = await getWorkspaceProgress('/ws');
|
|
46
|
+
expect(report.repos[0]).toMatchObject({ branchExists: false, onExpectedBranch: false });
|
|
47
|
+
expect(report.repos[0]?.pushed).toBeUndefined();
|
|
48
|
+
expect(report.repos[0]?.pullRequest).toBeUndefined();
|
|
49
|
+
expect(execa).not.toHaveBeenCalledWith('gh', expect.anything(), expect.anything());
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
//# sourceMappingURL=progress.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.test.js","sourceRoot":"","sources":["../../src/core/progress.test.ts"],"names":[],"mappings":"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"}
|
package/dist/core/refresh.d.ts
CHANGED
|
@@ -7,10 +7,13 @@
|
|
|
7
7
|
* Every generated file describes the whole workspace, so a refresh is all or
|
|
8
8
|
* nothing; there is no per-repo or base-only subset to ask for.
|
|
9
9
|
*/
|
|
10
|
+
import { type GenerationCheck } from './generation-lock.js';
|
|
10
11
|
/** Options for a headless refresh run. */
|
|
11
12
|
export interface RefreshOptions {
|
|
12
13
|
/** Ignore the analysis cache and re-analyze every repo. */
|
|
13
14
|
force?: boolean;
|
|
15
|
+
/** Check provenance/output hashes without regenerating; stale docs receive a bounded warning banner. */
|
|
16
|
+
check?: boolean;
|
|
14
17
|
}
|
|
15
18
|
/** Outcome of a headless refresh run. */
|
|
16
19
|
export interface RefreshReport {
|
|
@@ -22,6 +25,8 @@ export interface RefreshReport {
|
|
|
22
25
|
reusedRepos: string[];
|
|
23
26
|
/** Whether the handoff bundle was refreshed too. */
|
|
24
27
|
refreshedHandoff: boolean;
|
|
28
|
+
/** Present for --check runs. */
|
|
29
|
+
check?: GenerationCheck;
|
|
25
30
|
}
|
|
26
31
|
/**
|
|
27
32
|
* Refreshes a workspace's context files and plan. Throws if the workspace
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../src/core/refresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../src/core/refresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGjF,0CAA0C;AAC1C,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wGAAwG;IACxG,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC5B,sCAAsC;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,uDAAuD;IACvD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,oDAAoD;IACpD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gCAAgC;IAChC,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,gBAAgB,CACpC,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAWxB"}
|
package/dist/core/refresh.js
CHANGED
|
@@ -13,6 +13,8 @@ import { loadFeatureConfig, resolveRepoInfos } from './workspace.js';
|
|
|
13
13
|
import { resolveFeatureRepoPath } from '../utils/feature.js';
|
|
14
14
|
import { analyzeAllReposCached } from '../analyzers/index.js';
|
|
15
15
|
import { generateContextFiles } from '../generators/index.js';
|
|
16
|
+
import { checkGenerationLock } from './generation-lock.js';
|
|
17
|
+
import { acquireLock } from './locks.js';
|
|
16
18
|
/**
|
|
17
19
|
* Refreshes a workspace's context files and plan. Throws if the workspace
|
|
18
20
|
* configuration cannot be loaded.
|
|
@@ -27,10 +29,33 @@ import { generateContextFiles } from '../generators/index.js';
|
|
|
27
29
|
* @returns A report of what was analyzed vs reused.
|
|
28
30
|
*/
|
|
29
31
|
export async function refreshWorkspace(workspacePath, options = {}) {
|
|
32
|
+
const release = await acquireLock(path.join(workspacePath, '.nexusflow', 'generation.lock'), {
|
|
33
|
+
staleMs: 5 * 60_000,
|
|
34
|
+
timeoutMs: 30_000,
|
|
35
|
+
timeoutMessage: 'Another NexusFlow generation or refresh is already updating this workspace.',
|
|
36
|
+
});
|
|
37
|
+
try {
|
|
38
|
+
return await refreshWorkspaceUnlocked(workspacePath, options);
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
await release();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async function refreshWorkspaceUnlocked(workspacePath, options) {
|
|
30
45
|
const feature = await loadFeatureConfig(workspacePath);
|
|
31
46
|
if (!feature) {
|
|
32
47
|
throw new Error(`Failed to load workspace configuration. Ensure nexusflow.json exists at ${workspacePath}.`);
|
|
33
48
|
}
|
|
49
|
+
if (options.check) {
|
|
50
|
+
const check = await checkGenerationLock(workspacePath, { markDocuments: true });
|
|
51
|
+
return {
|
|
52
|
+
workspacePath,
|
|
53
|
+
analyzedRepos: [],
|
|
54
|
+
reusedRepos: [],
|
|
55
|
+
refreshedHandoff: false,
|
|
56
|
+
check,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
34
59
|
const resolvedPaths = feature.repos.map((r) => resolveFeatureRepoPath(feature, workspacePath, r));
|
|
35
60
|
const allRepos = await resolveRepoInfos(resolvedPaths);
|
|
36
61
|
const { analysis, analyzed, reused } = await analyzeAllReposCached(allRepos, workspacePath, { force: options.force });
|
package/dist/core/refresh.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../src/core/refresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../src/core/refresh.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,11 +5,15 @@ import * as workspace from './workspace.js';
|
|
|
5
5
|
import * as analyzers from '../analyzers/index.js';
|
|
6
6
|
import * as generators from '../generators/index.js';
|
|
7
7
|
import * as handoff from '../commands/handoff.js';
|
|
8
|
+
import * as generationLock from './generation-lock.js';
|
|
9
|
+
import * as locks from './locks.js';
|
|
8
10
|
vi.mock('node:fs/promises');
|
|
9
11
|
vi.mock('./workspace.js');
|
|
10
12
|
vi.mock('../analyzers/index.js');
|
|
11
13
|
vi.mock('../generators/index.js');
|
|
12
14
|
vi.mock('../commands/handoff.js');
|
|
15
|
+
vi.mock('./generation-lock.js');
|
|
16
|
+
vi.mock('./locks.js');
|
|
13
17
|
const feature = {
|
|
14
18
|
id: 'feat',
|
|
15
19
|
branchName: 'feat',
|
|
@@ -30,6 +34,8 @@ describe('refreshWorkspace', () => {
|
|
|
30
34
|
vi.mocked(analyzers.analyzeAllReposCached).mockResolvedValue({ analysis: new Map(), analyzed: ['a'], reused: ['b'] });
|
|
31
35
|
vi.mocked(generators.generateContextFiles).mockResolvedValue(undefined);
|
|
32
36
|
vi.mocked(handoff.handoffCommand).mockResolvedValue(undefined);
|
|
37
|
+
vi.mocked(generationLock.checkGenerationLock).mockResolvedValue({ fresh: true, lock: null, drift: [] });
|
|
38
|
+
vi.mocked(locks.acquireLock).mockResolvedValue(vi.fn().mockResolvedValue(undefined));
|
|
33
39
|
// No handoff bundle by default.
|
|
34
40
|
vi.mocked(fs.access).mockRejectedValue(new Error('ENOENT'));
|
|
35
41
|
});
|
|
@@ -54,6 +60,20 @@ describe('refreshWorkspace', () => {
|
|
|
54
60
|
await refreshWorkspace('/ws', { force: true });
|
|
55
61
|
expect(analyzers.analyzeAllReposCached).toHaveBeenCalledWith(expect.any(Array), '/ws', { force: true });
|
|
56
62
|
});
|
|
63
|
+
it('serializes refresh and generated-file mutation with a workspace lock', async () => {
|
|
64
|
+
const release = vi.fn().mockResolvedValue(undefined);
|
|
65
|
+
vi.mocked(locks.acquireLock).mockResolvedValue(release);
|
|
66
|
+
await refreshWorkspace('/ws');
|
|
67
|
+
expect(locks.acquireLock).toHaveBeenCalledWith(expect.stringMatching(/[\\/]\.nexusflow[\\/]generation\.lock$/), expect.objectContaining({ timeoutMs: 30_000 }));
|
|
68
|
+
expect(release).toHaveBeenCalledOnce();
|
|
69
|
+
});
|
|
70
|
+
it('checks provenance without analyzing or regenerating', async () => {
|
|
71
|
+
const report = await refreshWorkspace('/ws', { check: true });
|
|
72
|
+
expect(report.check?.fresh).toBe(true);
|
|
73
|
+
expect(generationLock.checkGenerationLock).toHaveBeenCalledWith('/ws', { markDocuments: true });
|
|
74
|
+
expect(analyzers.analyzeAllReposCached).not.toHaveBeenCalled();
|
|
75
|
+
expect(generators.generateContextFiles).not.toHaveBeenCalled();
|
|
76
|
+
});
|
|
57
77
|
it('refreshes the handoff bundle when it exists', async () => {
|
|
58
78
|
vi.mocked(fs.access).mockResolvedValue(undefined); // handoff file exists
|
|
59
79
|
const report = await refreshWorkspace('/ws');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refresh.test.js","sourceRoot":"","sources":["../../src/core/refresh.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"refresh.test.js","sourceRoot":"","sources":["../../src/core/refresh.test.ts"],"names":[],"mappings":"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"}
|
package/dist/core/status.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export interface RepoStatusReport {
|
|
|
11
11
|
path: string;
|
|
12
12
|
/** Current branch, or `null` when the repo is in a detached-HEAD state. */
|
|
13
13
|
branch: string | null;
|
|
14
|
+
/** Live HEAD commit identity. */
|
|
15
|
+
headSha?: string | null;
|
|
14
16
|
/** The feature branch the workspace expects every repo to be on. */
|
|
15
17
|
expectedBranch: string;
|
|
16
18
|
onExpectedBranch: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/core/status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/core/status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,uBAAuB,CAAC;AAG/B,oDAAoD;AACpD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,oEAAoE;IACpE,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,2EAA2E;IAC3E,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,yEAAyE;IACzE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,kCAAkC;AAClC,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,kDAAkD;IAClD,QAAQ,EAAE,OAAO,CAAC;IAClB,gGAAgG;IAChG,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,qBAAqB,CAAC,CAsChC"}
|
package/dist/core/status.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* status route. Throws only if the workspace manifest cannot be read.
|
|
6
6
|
*/
|
|
7
7
|
import { getWorkspaceRepos, getRepoBranch, getRepoStatus, getAheadBehind, getRemoteUrl, } from '../utils/multi-git.js';
|
|
8
|
+
import { execa } from 'execa';
|
|
8
9
|
/**
|
|
9
10
|
* Gathers branch, dirtiness, ahead/behind, and remote info for every repo in
|
|
10
11
|
* the workspace.
|
|
@@ -16,16 +17,20 @@ import { getWorkspaceRepos, getRepoBranch, getRepoStatus, getAheadBehind, getRem
|
|
|
16
17
|
export async function getWorkspaceStatusReport(workspacePath) {
|
|
17
18
|
const repos = await getWorkspaceRepos(workspacePath);
|
|
18
19
|
const reports = await Promise.all(repos.map(async (repo) => {
|
|
19
|
-
const [branch, status, remoteUrl, aheadBehind] = await Promise.all([
|
|
20
|
+
const [branch, status, remoteUrl, aheadBehind, headSha] = await Promise.all([
|
|
20
21
|
getRepoBranch(repo.path),
|
|
21
22
|
getRepoStatus(repo.path),
|
|
22
23
|
getRemoteUrl(repo.path),
|
|
23
24
|
getAheadBehind(repo.path, repo.branchName),
|
|
25
|
+
execa('git', ['rev-parse', 'HEAD'], { cwd: repo.path })
|
|
26
|
+
.then((result) => result.stdout.trim())
|
|
27
|
+
.catch(() => null),
|
|
24
28
|
]);
|
|
25
29
|
return {
|
|
26
30
|
name: repo.name,
|
|
27
31
|
path: repo.path,
|
|
28
32
|
branch,
|
|
33
|
+
headSha,
|
|
29
34
|
expectedBranch: repo.branchName,
|
|
30
35
|
onExpectedBranch: branch === repo.branchName,
|
|
31
36
|
dirty: status.hasChanges,
|
package/dist/core/status.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/core/status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,cAAc,EACd,YAAY,GAEb,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/core/status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,cAAc,EACd,YAAY,GAEb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAkC9B;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,aAAqB;IAErB,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,aAAa,CAAC,CAAC;IAErD,MAAM,OAAO,GAAuB,MAAM,OAAO,CAAC,GAAG,CACnD,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAA6B,EAAE;QAClD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC1E,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;YACxB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;YACvB,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC;YAC1C,KAAK,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;iBACpD,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;iBACtC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;SACrB,CAAC,CAAC;QAEH,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM;YACN,OAAO;YACP,cAAc,EAAE,IAAI,CAAC,UAAU;YAC/B,gBAAgB,EAAE,MAAM,KAAK,IAAI,CAAC,UAAU;YAC5C,KAAK,EAAE,MAAM,CAAC,UAAU;YACxB,YAAY,EAAE,MAAM,CAAC,KAAK;YAC1B,KAAK,EAAE,WAAW,CAAC,KAAK;YACxB,MAAM,EAAE,WAAW,CAAC,MAAM;YAC1B,SAAS;YACT,aAAa,EAAE,IAAI,CAAC,aAAa;SAClC,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,UAAU,IAAI,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAChD,6EAA6E;IAC7E,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;IAEtD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AAC5E,CAAC"}
|
package/dist/core/sync.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/core/sync.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,OAAO,KAAK,EAAE,UAAU,EAAoB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/core/sync.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,OAAO,KAAK,EAAE,UAAU,EAAoB,MAAM,aAAa,CAAC;AAIhE,sCAAsC;AACtC,MAAM,WAAW,cAAc;IAC7B,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,MAAM,EAAE,UAAU,CAAC;IACnB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,wDAAwD;AACxD,MAAM,WAAW,UAAU;IACzB,sCAAsC;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,mFAAmF;IACnF,WAAW,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAC;IACtB,gFAAgF;IAChF,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAOD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA+H9E"}
|
package/dist/core/sync.js
CHANGED
|
@@ -12,6 +12,8 @@ import { recordRepoSync } from './workspace-state.js';
|
|
|
12
12
|
import { getWorkspaceRepos, rebaseRepo } from '../utils/multi-git.js';
|
|
13
13
|
import { analyzeAllReposCached } from '../analyzers/index.js';
|
|
14
14
|
import { generateContextFiles } from '../generators/index.js';
|
|
15
|
+
import { checkGenerationLock } from './generation-lock.js';
|
|
16
|
+
import { refreshWorkspace } from './refresh.js';
|
|
15
17
|
/** A sync status counts as "synced" when the rebase itself landed. */
|
|
16
18
|
function isSynced(status) {
|
|
17
19
|
return status === 'up-to-date' || status === 'rebased' || status === 'stash-conflict';
|
|
@@ -35,6 +37,12 @@ export async function syncWorkspace(workspacePath) {
|
|
|
35
37
|
// worktrees, only those isolated worktrees are synced against their base.
|
|
36
38
|
const hasIsolated = isInPlace(feature) && Boolean(feature.isolatedRepos && Object.keys(feature.isolatedRepos).length > 0);
|
|
37
39
|
if (isInPlace(feature) && !hasIsolated) {
|
|
40
|
+
const freshness = await checkGenerationLock(workspacePath);
|
|
41
|
+
let contextRefreshed = false;
|
|
42
|
+
if (!freshness.fresh) {
|
|
43
|
+
await refreshWorkspace(workspacePath);
|
|
44
|
+
contextRefreshed = true;
|
|
45
|
+
}
|
|
38
46
|
return {
|
|
39
47
|
workspacePath,
|
|
40
48
|
branchName: feature.branchName,
|
|
@@ -47,7 +55,7 @@ export async function syncWorkspace(workspacePath) {
|
|
|
47
55
|
syncedCount: 0,
|
|
48
56
|
conflictCount: 0,
|
|
49
57
|
errorCount: 0,
|
|
50
|
-
contextRefreshed
|
|
58
|
+
contextRefreshed,
|
|
51
59
|
};
|
|
52
60
|
}
|
|
53
61
|
const repos = await getWorkspaceRepos(workspacePath);
|
|
@@ -109,6 +117,19 @@ export async function syncWorkspace(workspacePath) {
|
|
|
109
117
|
// Best-effort regeneration; ignore failures.
|
|
110
118
|
}
|
|
111
119
|
}
|
|
120
|
+
if (!contextRefreshed) {
|
|
121
|
+
try {
|
|
122
|
+
const freshness = await checkGenerationLock(workspacePath);
|
|
123
|
+
if (!freshness.fresh) {
|
|
124
|
+
await refreshWorkspace(workspacePath);
|
|
125
|
+
contextRefreshed = true;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// Context reconciliation is best-effort too. A completed rebase must not
|
|
130
|
+
// be reported as a failed sync just because generation remains stale.
|
|
131
|
+
}
|
|
132
|
+
}
|
|
112
133
|
return {
|
|
113
134
|
workspacePath,
|
|
114
135
|
branchName: feature.branchName,
|
package/dist/core/sync.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/core/sync.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/core/sync.ts"],"names":[],"mappings":"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"}
|
package/dist/core/sync.test.js
CHANGED
|
@@ -5,11 +5,15 @@ import * as workspaceState from './workspace-state.js';
|
|
|
5
5
|
import * as multiGit from '../utils/multi-git.js';
|
|
6
6
|
import * as analyzers from '../analyzers/index.js';
|
|
7
7
|
import * as generators from '../generators/index.js';
|
|
8
|
+
import * as generationLock from './generation-lock.js';
|
|
9
|
+
import * as refresh from './refresh.js';
|
|
8
10
|
vi.mock('./workspace.js');
|
|
9
11
|
vi.mock('./workspace-state.js');
|
|
10
12
|
vi.mock('../utils/multi-git.js');
|
|
11
13
|
vi.mock('../analyzers/index.js');
|
|
12
14
|
vi.mock('../generators/index.js');
|
|
15
|
+
vi.mock('./generation-lock.js');
|
|
16
|
+
vi.mock('./refresh.js');
|
|
13
17
|
const feature = {
|
|
14
18
|
id: 'feat',
|
|
15
19
|
branchName: 'feat',
|
|
@@ -37,6 +41,8 @@ describe('syncWorkspace', () => {
|
|
|
37
41
|
vi.mocked(multiGit.getWorkspaceRepos).mockResolvedValue([wsRepo('a'), wsRepo('b')]);
|
|
38
42
|
vi.mocked(analyzers.analyzeAllReposCached).mockResolvedValue({ analysis: new Map(), analyzed: ['a'], reused: ['b'] });
|
|
39
43
|
vi.mocked(generators.generateContextFiles).mockResolvedValue(undefined);
|
|
44
|
+
vi.mocked(generationLock.checkGenerationLock).mockResolvedValue({ fresh: true, lock: null, drift: [] });
|
|
45
|
+
vi.mocked(refresh.refreshWorkspace).mockResolvedValue({ workspacePath: '/ws', analyzedRepos: [], reusedRepos: [], refreshedHandoff: false });
|
|
40
46
|
});
|
|
41
47
|
it('throws when the workspace manifest is missing', async () => {
|
|
42
48
|
vi.mocked(workspace.loadFeatureConfig).mockResolvedValue(null);
|
|
@@ -89,6 +95,13 @@ describe('syncWorkspace', () => {
|
|
|
89
95
|
expect(analyzers.analyzeAllReposCached).toHaveBeenCalled();
|
|
90
96
|
expect(generators.generateContextFiles).toHaveBeenCalled();
|
|
91
97
|
});
|
|
98
|
+
it('reconciles stale generated views even when repos are already current', async () => {
|
|
99
|
+
vi.mocked(multiGit.rebaseRepo).mockResolvedValue(rebase('up-to-date'));
|
|
100
|
+
vi.mocked(generationLock.checkGenerationLock).mockResolvedValue({ fresh: false, lock: null, drift: [{ kind: 'missing-lock', name: 'nexusflow.lock', message: 'missing' }] });
|
|
101
|
+
const report = await syncWorkspace('/ws');
|
|
102
|
+
expect(refresh.refreshWorkspace).toHaveBeenCalledWith('/ws');
|
|
103
|
+
expect(report.contextRefreshed).toBe(true);
|
|
104
|
+
});
|
|
92
105
|
it('tolerates a generator failure without failing the sync', async () => {
|
|
93
106
|
vi.mocked(multiGit.rebaseRepo).mockResolvedValue(rebase('rebased'));
|
|
94
107
|
vi.mocked(generators.generateContextFiles).mockRejectedValue(new Error('gen boom'));
|
|
@@ -97,5 +110,19 @@ describe('syncWorkspace', () => {
|
|
|
97
110
|
expect(report.contextRefreshed).toBe(false);
|
|
98
111
|
expect(report.syncedCount).toBe(2);
|
|
99
112
|
});
|
|
113
|
+
it('does not fail a completed rebase when stale-context reconciliation also fails', async () => {
|
|
114
|
+
vi.mocked(multiGit.rebaseRepo).mockResolvedValue(rebase('rebased'));
|
|
115
|
+
vi.mocked(generators.generateContextFiles).mockRejectedValue(new Error('gen boom'));
|
|
116
|
+
vi.mocked(generationLock.checkGenerationLock).mockResolvedValue({
|
|
117
|
+
fresh: false,
|
|
118
|
+
lock: null,
|
|
119
|
+
drift: [{ kind: 'missing-lock', name: 'nexusflow.lock', message: 'missing' }],
|
|
120
|
+
});
|
|
121
|
+
vi.mocked(refresh.refreshWorkspace).mockRejectedValue(new Error('refresh boom'));
|
|
122
|
+
const report = await syncWorkspace('/ws');
|
|
123
|
+
expect(report.contextRefreshed).toBe(false);
|
|
124
|
+
expect(report.syncedCount).toBe(2);
|
|
125
|
+
expect(refresh.refreshWorkspace).toHaveBeenCalledWith('/ws');
|
|
126
|
+
});
|
|
100
127
|
});
|
|
101
128
|
//# sourceMappingURL=sync.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.test.js","sourceRoot":"","sources":["../../src/core/sync.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,QAAQ,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.test.js","sourceRoot":"","sources":["../../src/core/sync.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Git history and optional remote synchronization for the workspace artifact repo. */
|
|
2
|
+
export declare function ensureWorkspaceGitRepository(workspacePath: string): Promise<void>;
|
|
3
|
+
export declare function managedWorkspaceArtifacts(workspacePath: string, extra?: string[]): Promise<string[]>;
|
|
4
|
+
export declare function commitWorkspaceArtifacts(workspacePath: string, message: string, extra?: string[]): Promise<{
|
|
5
|
+
committed: boolean;
|
|
6
|
+
sha?: string;
|
|
7
|
+
}>;
|
|
8
|
+
export declare function commitExactWorkspaceArtifacts(workspacePath: string, message: string, relativePaths: string[]): Promise<{
|
|
9
|
+
committed: boolean;
|
|
10
|
+
sha?: string;
|
|
11
|
+
}>;
|
|
12
|
+
export declare function addWorkspaceRemote(workspacePath: string, url: string): Promise<void>;
|
|
13
|
+
export declare function pushWorkspaceArtifacts(workspacePath: string): Promise<void>;
|
|
14
|
+
export declare function pullWorkspaceArtifacts(workspacePath: string): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=workspace-git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-git.d.ts","sourceRoot":"","sources":["../../src/core/workspace-git.ts"],"names":[],"mappings":"AAAA,uFAAuF;AAiCvF,wBAAsB,4BAA4B,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAavF;AAED,wBAAsB,yBAAyB,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAU9G;AAED,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,MAAM,EAAO,GACnB,OAAO,CAAC;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAmB/C;AAED,wBAAsB,6BAA6B,CACjD,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAoB/C;AAED,wBAAsB,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK1F;AASD,wBAAsB,sBAAsB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjF;AAED,wBAAsB,sBAAsB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMjF"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/** Git history and optional remote synchronization for the workspace artifact repo. */
|
|
2
|
+
import * as fs from 'node:fs/promises';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { execa } from 'execa';
|
|
5
|
+
import { readGenerationLock } from './generation-lock.js';
|
|
6
|
+
import { acquireLock } from './locks.js';
|
|
7
|
+
const CORE_ARTIFACTS = [
|
|
8
|
+
'.gitignore',
|
|
9
|
+
'AGENTS.md',
|
|
10
|
+
'CLAUDE.md',
|
|
11
|
+
'WORKSPACE.md',
|
|
12
|
+
'nexusflow.json',
|
|
13
|
+
'nexusflow.lock',
|
|
14
|
+
'nexusflow-knowledge.md',
|
|
15
|
+
'nexusflow-plan.md',
|
|
16
|
+
'.nexusflow/resources.json',
|
|
17
|
+
'.nexusflow/resources.lock.json',
|
|
18
|
+
'.vscode/settings.json',
|
|
19
|
+
'.cursor/mcp.json',
|
|
20
|
+
];
|
|
21
|
+
async function exists(workspacePath, relativePath) {
|
|
22
|
+
try {
|
|
23
|
+
await fs.access(path.join(workspacePath, relativePath));
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export async function ensureWorkspaceGitRepository(workspacePath) {
|
|
31
|
+
const probe = await execa('git', ['rev-parse', '--show-toplevel'], { cwd: workspacePath, reject: false });
|
|
32
|
+
if (probe.exitCode !== 0 || path.resolve(probe.stdout.trim()) !== path.resolve(workspacePath)) {
|
|
33
|
+
await execa('git', ['init'], { cwd: workspacePath });
|
|
34
|
+
}
|
|
35
|
+
const name = await execa('git', ['config', '--local', 'user.name'], { cwd: workspacePath, reject: false });
|
|
36
|
+
if (name.exitCode !== 0 || !name.stdout.trim()) {
|
|
37
|
+
await execa('git', ['config', '--local', 'user.name', 'NexusFlow'], { cwd: workspacePath });
|
|
38
|
+
}
|
|
39
|
+
const email = await execa('git', ['config', '--local', 'user.email'], { cwd: workspacePath, reject: false });
|
|
40
|
+
if (email.exitCode !== 0 || !email.stdout.trim()) {
|
|
41
|
+
await execa('git', ['config', '--local', 'user.email', 'nexusflow@local'], { cwd: workspacePath });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export async function managedWorkspaceArtifacts(workspacePath, extra = []) {
|
|
45
|
+
const lock = await readGenerationLock(workspacePath);
|
|
46
|
+
const workspaceFile = `${path.basename(workspacePath)}.code-workspace`;
|
|
47
|
+
const candidates = new Set([...CORE_ARTIFACTS, workspaceFile, ...Object.keys(lock?.outputs ?? {}), ...extra]);
|
|
48
|
+
const safe = [...candidates].filter((item) => item && !path.isAbsolute(item) && !item.replace(/\\/g, '/').split('/').includes('..'));
|
|
49
|
+
const present = [];
|
|
50
|
+
for (const item of safe)
|
|
51
|
+
if (await exists(workspacePath, item))
|
|
52
|
+
present.push(item.replace(/\\/g, '/'));
|
|
53
|
+
return present.sort();
|
|
54
|
+
}
|
|
55
|
+
export async function commitWorkspaceArtifacts(workspacePath, message, extra = []) {
|
|
56
|
+
const release = await acquireLock(path.join(workspacePath, '.nexusflow', 'workspace-git.lock'), {
|
|
57
|
+
staleMs: 60_000, timeoutMs: 30_000,
|
|
58
|
+
timeoutMessage: 'Another NexusFlow operation is updating the workspace artifact repository.',
|
|
59
|
+
});
|
|
60
|
+
try {
|
|
61
|
+
await ensureWorkspaceGitRepository(workspacePath);
|
|
62
|
+
const artifacts = await managedWorkspaceArtifacts(workspacePath, extra);
|
|
63
|
+
if (!artifacts.length)
|
|
64
|
+
return { committed: false };
|
|
65
|
+
await execa('git', ['add', '--', ...artifacts], { cwd: workspacePath });
|
|
66
|
+
const diff = await execa('git', ['diff', '--cached', '--quiet', '--', ...artifacts], { cwd: workspacePath, reject: false });
|
|
67
|
+
if (diff.exitCode === 0)
|
|
68
|
+
return { committed: false };
|
|
69
|
+
if (diff.exitCode !== 1)
|
|
70
|
+
throw new Error('Could not inspect staged workspace artifacts.');
|
|
71
|
+
await execa('git', ['commit', '-m', message, '--', ...artifacts], { cwd: workspacePath });
|
|
72
|
+
const { stdout } = await execa('git', ['rev-parse', 'HEAD'], { cwd: workspacePath });
|
|
73
|
+
return { committed: true, sha: stdout.trim() };
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
await release();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export async function commitExactWorkspaceArtifacts(workspacePath, message, relativePaths) {
|
|
80
|
+
const release = await acquireLock(path.join(workspacePath, '.nexusflow', 'workspace-git.lock'), {
|
|
81
|
+
staleMs: 60_000, timeoutMs: 30_000,
|
|
82
|
+
timeoutMessage: 'Another NexusFlow operation is updating the workspace artifact repository.',
|
|
83
|
+
});
|
|
84
|
+
try {
|
|
85
|
+
await ensureWorkspaceGitRepository(workspacePath);
|
|
86
|
+
const artifacts = (await managedWorkspaceArtifacts(workspacePath, relativePaths))
|
|
87
|
+
.filter((item) => relativePaths.map((candidate) => candidate.replace(/\\/g, '/')).includes(item));
|
|
88
|
+
if (!artifacts.length)
|
|
89
|
+
return { committed: false };
|
|
90
|
+
await execa('git', ['add', '--', ...artifacts], { cwd: workspacePath });
|
|
91
|
+
const diff = await execa('git', ['diff', '--cached', '--quiet', '--', ...artifacts], { cwd: workspacePath, reject: false });
|
|
92
|
+
if (diff.exitCode === 0)
|
|
93
|
+
return { committed: false };
|
|
94
|
+
if (diff.exitCode !== 1)
|
|
95
|
+
throw new Error('Could not inspect staged workspace artifacts.');
|
|
96
|
+
await execa('git', ['commit', '-m', message, '--', ...artifacts], { cwd: workspacePath });
|
|
97
|
+
const { stdout } = await execa('git', ['rev-parse', 'HEAD'], { cwd: workspacePath });
|
|
98
|
+
return { committed: true, sha: stdout.trim() };
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
await release();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
export async function addWorkspaceRemote(workspacePath, url) {
|
|
105
|
+
await ensureWorkspaceGitRepository(workspacePath);
|
|
106
|
+
const existing = await execa('git', ['remote', 'get-url', 'origin'], { cwd: workspacePath, reject: false });
|
|
107
|
+
if (existing.exitCode === 0)
|
|
108
|
+
throw new Error(`Workspace remote "origin" already exists (${existing.stdout.trim()}).`);
|
|
109
|
+
await execa('git', ['remote', 'add', 'origin', url], { cwd: workspacePath });
|
|
110
|
+
}
|
|
111
|
+
async function currentBranch(workspacePath) {
|
|
112
|
+
const { stdout } = await execa('git', ['branch', '--show-current'], { cwd: workspacePath });
|
|
113
|
+
const branch = stdout.trim();
|
|
114
|
+
if (!branch)
|
|
115
|
+
throw new Error('Workspace artifact repository is in detached HEAD state.');
|
|
116
|
+
return branch;
|
|
117
|
+
}
|
|
118
|
+
export async function pushWorkspaceArtifacts(workspacePath) {
|
|
119
|
+
await ensureWorkspaceGitRepository(workspacePath);
|
|
120
|
+
const branch = await currentBranch(workspacePath);
|
|
121
|
+
await execa('git', ['push', '-u', 'origin', branch], { cwd: workspacePath });
|
|
122
|
+
}
|
|
123
|
+
export async function pullWorkspaceArtifacts(workspacePath) {
|
|
124
|
+
await ensureWorkspaceGitRepository(workspacePath);
|
|
125
|
+
const dirty = await execa('git', ['status', '--porcelain'], { cwd: workspacePath });
|
|
126
|
+
if (dirty.stdout.trim())
|
|
127
|
+
throw new Error('Workspace artifact repository has uncommitted changes; commit them before pulling.');
|
|
128
|
+
const branch = await currentBranch(workspacePath);
|
|
129
|
+
await execa('git', ['pull', '--rebase', 'origin', branch], { cwd: workspacePath });
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=workspace-git.js.map
|