@mrpatronz/nexusflow 2.9.0 → 2.10.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 +177 -113
- package/desktop/assets/icon.png +0 -0
- package/dist/agent/AcpCliAdapter.d.ts +2 -0
- package/dist/agent/AcpCliAdapter.d.ts.map +1 -1
- package/dist/agent/AcpCliAdapter.js +50 -4
- package/dist/agent/AcpCliAdapter.js.map +1 -1
- package/dist/agent/AntigravityCliAdapter.d.ts +44 -2
- package/dist/agent/AntigravityCliAdapter.d.ts.map +1 -1
- package/dist/agent/AntigravityCliAdapter.js +363 -16
- package/dist/agent/AntigravityCliAdapter.js.map +1 -1
- package/dist/agent/ClaudeCliAdapter.d.ts +5 -2
- package/dist/agent/ClaudeCliAdapter.d.ts.map +1 -1
- package/dist/agent/ClaudeCliAdapter.js +43 -14
- package/dist/agent/ClaudeCliAdapter.js.map +1 -1
- package/dist/agent/ClaudeSdkAdapter.d.ts +1 -0
- package/dist/agent/ClaudeSdkAdapter.d.ts.map +1 -1
- package/dist/agent/ClaudeSdkAdapter.js +38 -11
- package/dist/agent/ClaudeSdkAdapter.js.map +1 -1
- package/dist/agent/CliAdapterBase.d.ts +2 -0
- package/dist/agent/CliAdapterBase.d.ts.map +1 -1
- package/dist/agent/CliAdapterBase.js +12 -1
- package/dist/agent/CliAdapterBase.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/CodexSdkAdapter.d.ts.map +1 -1
- package/dist/agent/CodexSdkAdapter.js +4 -1
- package/dist/agent/CodexSdkAdapter.js.map +1 -1
- package/dist/agent/CopilotAcpAdapter.d.ts.map +1 -1
- package/dist/agent/CopilotAcpAdapter.js +2 -2
- package/dist/agent/CopilotAcpAdapter.js.map +1 -1
- package/dist/agent/ProviderRegistry.d.ts +8 -1
- package/dist/agent/ProviderRegistry.d.ts.map +1 -1
- package/dist/agent/ProviderRegistry.js.map +1 -1
- package/dist/agent/TurnSessionManager.d.ts +65 -0
- package/dist/agent/TurnSessionManager.d.ts.map +1 -0
- package/dist/agent/TurnSessionManager.js +330 -0
- package/dist/agent/TurnSessionManager.js.map +1 -0
- package/dist/agent/adapters.d.ts.map +1 -1
- package/dist/agent/adapters.js +23 -6
- package/dist/agent/adapters.js.map +1 -1
- package/dist/agent/cliAvailability.d.ts +2 -5
- package/dist/agent/cliAvailability.d.ts.map +1 -1
- package/dist/agent/cliAvailability.js +18 -41
- package/dist/agent/cliAvailability.js.map +1 -1
- package/dist/agent/mcp-config.d.ts +0 -5
- package/dist/agent/mcp-config.d.ts.map +1 -1
- package/dist/agent/mcp-config.js +2 -1
- package/dist/agent/mcp-config.js.map +1 -1
- package/dist/agent/models.d.ts +13 -0
- package/dist/agent/models.d.ts.map +1 -1
- package/dist/agent/models.js +262 -8
- package/dist/agent/models.js.map +1 -1
- package/dist/agent/nativeTools.d.ts.map +1 -1
- package/dist/agent/nativeTools.js +1 -0
- package/dist/agent/nativeTools.js.map +1 -1
- package/dist/agent/orchestrator.d.ts.map +1 -1
- package/dist/agent/orchestrator.js +3 -2
- package/dist/agent/orchestrator.js.map +1 -1
- package/dist/agent/session.d.ts +6 -0
- package/dist/agent/session.d.ts.map +1 -1
- package/dist/agent/session.js +8 -0
- package/dist/agent/session.js.map +1 -1
- package/dist/analyzers/detect-deps.js +16 -1
- package/dist/analyzers/detect-deps.js.map +1 -1
- package/dist/analyzers/run-analyzer.d.ts.map +1 -1
- package/dist/analyzers/run-analyzer.js.map +1 -1
- package/dist/commands/adapter.d.ts.map +1 -1
- package/dist/commands/adapter.js +15 -14
- package/dist/commands/adapter.js.map +1 -1
- package/dist/commands/add-repo.d.ts.map +1 -1
- package/dist/commands/add-repo.js +6 -5
- package/dist/commands/add-repo.js.map +1 -1
- package/dist/commands/commit.js +6 -8
- package/dist/commands/commit.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +2 -1
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/create.d.ts +4 -4
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +48 -7
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/desktop.d.ts +46 -3
- package/dist/commands/desktop.d.ts.map +1 -1
- package/dist/commands/desktop.js +343 -33
- package/dist/commands/desktop.js.map +1 -1
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +3 -2
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +3 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/finish.js +2 -1
- package/dist/commands/finish.js.map +1 -1
- package/dist/commands/handoff.d.ts.map +1 -1
- package/dist/commands/handoff.js +12 -12
- package/dist/commands/handoff.js.map +1 -1
- package/dist/commands/init.d.ts +2 -2
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +8 -7
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/isolate.d.ts.map +1 -1
- package/dist/commands/isolate.js +2 -1
- package/dist/commands/isolate.js.map +1 -1
- package/dist/commands/knowledge.d.ts.map +1 -1
- package/dist/commands/knowledge.js +3 -2
- package/dist/commands/knowledge.js.map +1 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +3 -2
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/logs.js +3 -3
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/mcp.d.ts +1 -2
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +19 -12
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/migrate.d.ts +12 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +128 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/open.d.ts.map +1 -1
- package/dist/commands/open.js +2 -1
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/progress.d.ts.map +1 -1
- package/dist/commands/progress.js +2 -1
- package/dist/commands/progress.js.map +1 -1
- package/dist/commands/project.d.ts.map +1 -1
- package/dist/commands/project.js +7 -6
- package/dist/commands/project.js.map +1 -1
- package/dist/commands/refresh.d.ts.map +1 -1
- package/dist/commands/refresh.js +8 -11
- package/dist/commands/refresh.js.map +1 -1
- package/dist/commands/remove.d.ts.map +1 -1
- package/dist/commands/remove.js +2 -1
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/schedule.js +16 -18
- package/dist/commands/schedule.js.map +1 -1
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +9 -8
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +2 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/stop.d.ts.map +1 -1
- package/dist/commands/stop.js +2 -1
- package/dist/commands/stop.js.map +1 -1
- package/dist/commands/strategy.d.ts.map +1 -1
- package/dist/commands/strategy.js +6 -5
- package/dist/commands/strategy.js.map +1 -1
- package/dist/commands/sync.js +8 -10
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/tui.d.ts.map +1 -1
- package/dist/commands/tui.js +11 -10
- package/dist/commands/tui.js.map +1 -1
- package/dist/commands/ui.d.ts.map +1 -1
- package/dist/commands/ui.js +4 -3
- package/dist/commands/ui.js.map +1 -1
- package/dist/core/adapters/local-storage.d.ts +3 -1
- package/dist/core/adapters/local-storage.d.ts.map +1 -1
- package/dist/core/adapters/local-storage.js +62 -4
- package/dist/core/adapters/local-storage.js.map +1 -1
- package/dist/core/analysis-cache.d.ts.map +1 -1
- package/dist/core/analysis-cache.js +8 -7
- package/dist/core/analysis-cache.js.map +1 -1
- package/dist/core/brand-config.d.ts +261 -0
- package/dist/core/brand-config.d.ts.map +1 -0
- package/dist/core/brand-config.js +514 -0
- package/dist/core/brand-config.js.map +1 -0
- package/dist/core/config.d.ts +1 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +18 -8
- package/dist/core/config.js.map +1 -1
- package/dist/core/constants.d.ts +88 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/constants.js +103 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/doctor.d.ts.map +1 -1
- package/dist/core/doctor.js +11 -3
- package/dist/core/doctor.js.map +1 -1
- package/dist/core/generation-lock.d.ts +2 -2
- package/dist/core/generation-lock.d.ts.map +1 -1
- package/dist/core/generation-lock.js +49 -22
- package/dist/core/generation-lock.js.map +1 -1
- package/dist/core/knowledge.d.ts +19 -0
- package/dist/core/knowledge.d.ts.map +1 -1
- package/dist/core/knowledge.js +150 -24
- package/dist/core/knowledge.js.map +1 -1
- package/dist/core/migrate.d.ts +53 -0
- package/dist/core/migrate.d.ts.map +1 -0
- package/dist/core/migrate.js +607 -0
- package/dist/core/migrate.js.map +1 -0
- package/dist/core/new-repo.js +1 -1
- package/dist/core/new-repo.js.map +1 -1
- package/dist/core/projects.d.ts.map +1 -1
- package/dist/core/projects.js +13 -4
- package/dist/core/projects.js.map +1 -1
- package/dist/core/refresh.d.ts.map +1 -1
- package/dist/core/refresh.js +6 -4
- package/dist/core/refresh.js.map +1 -1
- package/dist/core/scheduler.d.ts +1 -1
- package/dist/core/scheduler.d.ts.map +1 -1
- package/dist/core/scheduler.js +11 -9
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/sync.js +1 -1
- package/dist/core/sync.js.map +1 -1
- package/dist/core/workspace-git.d.ts.map +1 -1
- package/dist/core/workspace-git.js +34 -10
- package/dist/core/workspace-git.js.map +1 -1
- package/dist/core/workspace-state.d.ts +4 -0
- package/dist/core/workspace-state.d.ts.map +1 -1
- package/dist/core/workspace-state.js +8 -8
- package/dist/core/workspace-state.js.map +1 -1
- package/dist/core/workspace.d.ts +13 -5
- package/dist/core/workspace.d.ts.map +1 -1
- package/dist/core/workspace.js +83 -34
- package/dist/core/workspace.js.map +1 -1
- package/dist/core/worktree.d.ts +10 -4
- package/dist/core/worktree.d.ts.map +1 -1
- package/dist/core/worktree.js +34 -47
- package/dist/core/worktree.js.map +1 -1
- package/dist/desktop-server.js +6 -3
- package/dist/desktop-server.js.map +1 -1
- package/dist/generators/base.d.ts.map +1 -1
- package/dist/generators/base.js +6 -5
- package/dist/generators/base.js.map +1 -1
- package/dist/generators/claude.d.ts.map +1 -1
- package/dist/generators/claude.js +2 -1
- package/dist/generators/claude.js.map +1 -1
- package/dist/generators/cursor.d.ts +1 -1
- package/dist/generators/cursor.d.ts.map +1 -1
- package/dist/generators/cursor.js +9 -4
- package/dist/generators/cursor.js.map +1 -1
- package/dist/generators/index.d.ts +4 -8
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/index.js +34 -69
- package/dist/generators/index.js.map +1 -1
- package/dist/generators/plan-generator.d.ts.map +1 -1
- package/dist/generators/plan-generator.js +20 -11
- package/dist/generators/plan-generator.js.map +1 -1
- package/dist/generators/skills-generator.d.ts.map +1 -1
- package/dist/generators/skills-generator.js +26 -11
- package/dist/generators/skills-generator.js.map +1 -1
- package/dist/gui/app_logo.png +0 -0
- package/dist/gui/assets/AgentsPage-DbivhmK0.js +3 -0
- package/dist/gui/assets/DashboardPage-D50Qrm3e.js +1 -0
- package/dist/gui/assets/GettingStartedPage-1MOTng3B.js +1 -0
- package/dist/gui/assets/NullStore-tdPen1kp.js +1 -0
- package/dist/gui/assets/ProjectsPage-srKgf7VN.js +1 -0
- package/dist/gui/assets/ScaffoldRepoInline-CP0yn5mw.js +1 -0
- package/dist/gui/assets/SettingsPage-DWmrLV8o.js +1 -0
- package/dist/gui/assets/SkillsPage-CKjTXdrd.js +6 -0
- package/dist/gui/assets/StartWorkPage-BCUnJ9k8.js +1 -0
- package/dist/gui/assets/{StrategiesPage-C36TZgDX.js → StrategiesPage-CdCbbIu-.js} +2 -2
- package/dist/gui/assets/WorkroomsPage-BcT-mGtT.js +4 -0
- package/dist/gui/assets/WorkspacesPage-CYFCm-7_.js +2 -0
- package/dist/gui/assets/alert-QnMXzwpU.js +1 -0
- package/dist/gui/assets/alert-dialog-u7qgb9Hq.js +1 -0
- package/dist/gui/assets/badge-DwXvB44H.js +1 -0
- package/dist/gui/assets/brand-hHByyyzq.js +1 -0
- package/dist/gui/assets/button-CREn1mup.js +1 -0
- package/dist/gui/assets/card-yrg6ov8B.js +1 -0
- package/dist/gui/assets/chevron-down-B_Mwbim8.js +1 -0
- package/dist/gui/assets/chunk-BV7QT456-DfUBKG-z.js +3 -0
- package/dist/gui/assets/{circle-plus-lmU1yNJd.js → circle-plus--zM3-3r3.js} +1 -1
- package/dist/gui/assets/{code-xml-jFAa3-TT.js → code-xml-DH-38Tt7.js} +1 -1
- package/dist/gui/assets/{git-branch-Cfj9D8yW.js → git-branch-Ce0I2663.js} +1 -1
- package/dist/gui/assets/index-3tD_IeyQ.js +55 -0
- package/dist/gui/assets/index-CK5YRfPV.css +2 -0
- package/dist/gui/assets/label-DC730X8s.js +1 -0
- package/dist/gui/assets/layers-j_brOuoa.js +1 -0
- package/dist/gui/assets/shield-check-Dd1Yv3l2.js +1 -0
- package/dist/gui/assets/square-check-big-BSIiYXPI.js +1 -0
- package/dist/gui/assets/tabs-BrHKp5bD.js +1 -0
- package/dist/gui/assets/{trash-2-CtR35_eF.js → trash-2-CMdv3eD3.js} +1 -1
- package/dist/gui/assets/useAriaLabelledBy-C4zV-1Ra.js +1 -0
- package/dist/gui/assets/{vsc-DFh0-53h.js → vsc-D80c4gBT.js} +1 -1
- package/dist/gui/favicon-aurora.svg +8 -0
- package/dist/gui/favicon.ico +0 -0
- package/dist/gui/favicon.svg +8 -1
- package/dist/gui/index.html +18 -12
- package/dist/harness/claude.d.ts.map +1 -1
- package/dist/harness/claude.js +97 -7
- package/dist/harness/claude.js.map +1 -1
- package/dist/harness/codex.d.ts +1 -0
- package/dist/harness/codex.d.ts.map +1 -1
- package/dist/harness/codex.js +51 -34
- package/dist/harness/codex.js.map +1 -1
- package/dist/index.js +57 -27
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +12 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +24 -6
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts +4 -2
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +372 -17
- package/dist/mcp/tools.js.map +1 -1
- package/dist/orchestration/detect.d.ts.map +1 -1
- package/dist/orchestration/detect.js +12 -5
- package/dist/orchestration/detect.js.map +1 -1
- package/dist/orchestration/log-tail.js +17 -17
- package/dist/orchestration/log-tail.js.map +1 -1
- package/dist/orchestration/runner.d.ts +1 -1
- package/dist/orchestration/runner.d.ts.map +1 -1
- package/dist/orchestration/runner.js +41 -18
- package/dist/orchestration/runner.js.map +1 -1
- package/dist/resources/agents-catalog.d.ts +3 -1
- package/dist/resources/agents-catalog.d.ts.map +1 -1
- package/dist/resources/agents-catalog.js +12 -6
- package/dist/resources/agents-catalog.js.map +1 -1
- package/dist/resources/contracts.d.ts +7 -0
- package/dist/resources/contracts.d.ts.map +1 -1
- package/dist/resources/contracts.js +8 -1
- package/dist/resources/contracts.js.map +1 -1
- package/dist/resources/fs-safety.d.ts +7 -1
- package/dist/resources/fs-safety.d.ts.map +1 -1
- package/dist/resources/fs-safety.js +44 -1
- package/dist/resources/fs-safety.js.map +1 -1
- package/dist/resources/materializer.d.ts +1 -0
- package/dist/resources/materializer.d.ts.map +1 -1
- package/dist/resources/materializer.js +48 -17
- package/dist/resources/materializer.js.map +1 -1
- package/dist/resources/service.d.ts.map +1 -1
- package/dist/resources/service.js +3 -2
- package/dist/resources/service.js.map +1 -1
- package/dist/server.d.ts +2 -19
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1294 -348
- package/dist/server.js.map +1 -1
- package/dist/static-resources/workflows/cost-aware-sol-luna.md +95 -0
- package/dist/storage/db.d.ts +94 -0
- package/dist/storage/db.d.ts.map +1 -0
- package/dist/storage/db.js +609 -0
- package/dist/storage/db.js.map +1 -0
- package/dist/types.d.ts +19 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/detect-ai.d.ts.map +1 -1
- package/dist/utils/detect-ai.js +1 -3
- package/dist/utils/detect-ai.js.map +1 -1
- package/dist/utils/multi-git.d.ts +0 -8
- package/dist/utils/multi-git.d.ts.map +1 -1
- package/dist/utils/multi-git.js +12 -4
- package/dist/utils/multi-git.js.map +1 -1
- package/dist/utils/pr.d.ts.map +1 -1
- package/dist/utils/pr.js +10 -5
- package/dist/utils/pr.js.map +1 -1
- package/dist/utils/repo-freshness.d.ts +106 -0
- package/dist/utils/repo-freshness.d.ts.map +1 -0
- package/dist/utils/repo-freshness.js +405 -0
- package/dist/utils/repo-freshness.js.map +1 -0
- package/dist/utils/resolve-workspace.d.ts +1 -1
- package/dist/utils/resolve-workspace.d.ts.map +1 -1
- package/dist/utils/resolve-workspace.js +10 -3
- package/dist/utils/resolve-workspace.js.map +1 -1
- package/dist/utils/session-finder.d.ts +12 -1
- package/dist/utils/session-finder.d.ts.map +1 -1
- package/dist/utils/session-finder.js +206 -8
- package/dist/utils/session-finder.js.map +1 -1
- package/dist/utils/skills-catalog.d.ts +5 -1
- package/dist/utils/skills-catalog.d.ts.map +1 -1
- package/dist/utils/skills-catalog.js +131 -75
- package/dist/utils/skills-catalog.js.map +1 -1
- package/dist/utils/terminal-launch.d.ts +8 -2
- package/dist/utils/terminal-launch.d.ts.map +1 -1
- package/dist/utils/terminal-launch.js +88 -19
- package/dist/utils/terminal-launch.js.map +1 -1
- package/dist/utils/update-check.d.ts +4 -1
- package/dist/utils/update-check.d.ts.map +1 -1
- package/dist/utils/update-check.js +66 -19
- package/dist/utils/update-check.js.map +1 -1
- package/dist/utils/user-paths.d.ts +23 -0
- package/dist/utils/user-paths.d.ts.map +1 -0
- package/dist/utils/user-paths.js +126 -0
- package/dist/utils/user-paths.js.map +1 -0
- package/dist/utils/workflows.d.ts +4 -1
- package/dist/utils/workflows.d.ts.map +1 -1
- package/dist/utils/workflows.js +51 -21
- package/dist/utils/workflows.js.map +1 -1
- package/dist/workrooms/client.d.ts +54 -0
- package/dist/workrooms/client.d.ts.map +1 -0
- package/dist/workrooms/client.js +191 -0
- package/dist/workrooms/client.js.map +1 -0
- package/dist/workrooms/contracts.d.ts +579 -0
- package/dist/workrooms/contracts.d.ts.map +1 -0
- package/dist/workrooms/contracts.js +231 -0
- package/dist/workrooms/contracts.js.map +1 -0
- package/dist/workrooms/crypto.d.ts +30 -0
- package/dist/workrooms/crypto.d.ts.map +1 -0
- package/dist/workrooms/crypto.js +72 -0
- package/dist/workrooms/crypto.js.map +1 -0
- package/dist/workrooms/host.d.ts +61 -0
- package/dist/workrooms/host.d.ts.map +1 -0
- package/dist/workrooms/host.js +747 -0
- package/dist/workrooms/host.js.map +1 -0
- package/dist/workrooms/local-resources.d.ts +26 -0
- package/dist/workrooms/local-resources.d.ts.map +1 -0
- package/dist/workrooms/local-resources.js +367 -0
- package/dist/workrooms/local-resources.js.map +1 -0
- package/dist/workrooms/manager.d.ts +228 -0
- package/dist/workrooms/manager.d.ts.map +1 -0
- package/dist/workrooms/manager.js +768 -0
- package/dist/workrooms/manager.js.map +1 -0
- package/dist/workrooms/milestones.d.ts +42 -0
- package/dist/workrooms/milestones.d.ts.map +1 -0
- package/dist/workrooms/milestones.js +94 -0
- package/dist/workrooms/milestones.js.map +1 -0
- package/dist/workrooms/portable.d.ts +21 -0
- package/dist/workrooms/portable.d.ts.map +1 -0
- package/dist/workrooms/portable.js +201 -0
- package/dist/workrooms/portable.js.map +1 -0
- package/dist/workrooms/resource-package.d.ts +7 -0
- package/dist/workrooms/resource-package.d.ts.map +1 -0
- package/dist/workrooms/resource-package.js +260 -0
- package/dist/workrooms/resource-package.js.map +1 -0
- package/dist/workrooms/service.d.ts +92 -0
- package/dist/workrooms/service.d.ts.map +1 -0
- package/dist/workrooms/service.js +788 -0
- package/dist/workrooms/service.js.map +1 -0
- package/dist/workrooms/sqlite-store.d.ts +31 -0
- package/dist/workrooms/sqlite-store.d.ts.map +1 -0
- package/dist/workrooms/sqlite-store.js +511 -0
- package/dist/workrooms/sqlite-store.js.map +1 -0
- package/dist/workrooms/store.d.ts +542 -0
- package/dist/workrooms/store.d.ts.map +1 -0
- package/dist/workrooms/store.js +71 -0
- package/dist/workrooms/store.js.map +1 -0
- package/package.json +21 -11
- package/resources/workflows/cost-aware-sol-luna.md +95 -0
- package/dist/agent/AcpCliAdapter.test.d.ts +0 -2
- package/dist/agent/AcpCliAdapter.test.d.ts.map +0 -1
- package/dist/agent/AcpCliAdapter.test.js +0 -235
- package/dist/agent/AcpCliAdapter.test.js.map +0 -1
- package/dist/agent/AntigravityCliAdapter.test.d.ts +0 -2
- package/dist/agent/AntigravityCliAdapter.test.d.ts.map +0 -1
- package/dist/agent/AntigravityCliAdapter.test.js +0 -222
- package/dist/agent/AntigravityCliAdapter.test.js.map +0 -1
- package/dist/agent/ClaudeCliAdapter.test.d.ts +0 -2
- package/dist/agent/ClaudeCliAdapter.test.d.ts.map +0 -1
- package/dist/agent/ClaudeCliAdapter.test.js +0 -320
- package/dist/agent/ClaudeCliAdapter.test.js.map +0 -1
- package/dist/agent/ClaudeSdkAdapter.test.d.ts +0 -2
- package/dist/agent/ClaudeSdkAdapter.test.d.ts.map +0 -1
- package/dist/agent/ClaudeSdkAdapter.test.js +0 -155
- package/dist/agent/ClaudeSdkAdapter.test.js.map +0 -1
- package/dist/agent/CliAdapterBase.test.d.ts +0 -2
- package/dist/agent/CliAdapterBase.test.d.ts.map +0 -1
- package/dist/agent/CliAdapterBase.test.js +0 -240
- package/dist/agent/CliAdapterBase.test.js.map +0 -1
- package/dist/agent/CodexCliAdapter.test.d.ts +0 -2
- package/dist/agent/CodexCliAdapter.test.d.ts.map +0 -1
- package/dist/agent/CodexCliAdapter.test.js +0 -331
- package/dist/agent/CodexCliAdapter.test.js.map +0 -1
- package/dist/agent/CodexSdkAdapter.test.d.ts +0 -2
- package/dist/agent/CodexSdkAdapter.test.d.ts.map +0 -1
- package/dist/agent/CodexSdkAdapter.test.js +0 -76
- package/dist/agent/CodexSdkAdapter.test.js.map +0 -1
- package/dist/agent/ProviderRegistry.test.d.ts +0 -2
- package/dist/agent/ProviderRegistry.test.d.ts.map +0 -1
- package/dist/agent/ProviderRegistry.test.js +0 -129
- package/dist/agent/ProviderRegistry.test.js.map +0 -1
- package/dist/agent/adapters.test.d.ts +0 -2
- package/dist/agent/adapters.test.d.ts.map +0 -1
- package/dist/agent/adapters.test.js +0 -71
- package/dist/agent/adapters.test.js.map +0 -1
- package/dist/agent/cliAvailability.test.d.ts +0 -2
- package/dist/agent/cliAvailability.test.d.ts.map +0 -1
- package/dist/agent/cliAvailability.test.js +0 -217
- package/dist/agent/cliAvailability.test.js.map +0 -1
- package/dist/agent/mcp-config.test.d.ts +0 -2
- package/dist/agent/mcp-config.test.d.ts.map +0 -1
- package/dist/agent/mcp-config.test.js +0 -22
- package/dist/agent/mcp-config.test.js.map +0 -1
- package/dist/agent/models.test.d.ts +0 -2
- package/dist/agent/models.test.d.ts.map +0 -1
- package/dist/agent/models.test.js +0 -40
- package/dist/agent/models.test.js.map +0 -1
- package/dist/agent/nativeAgent.test.d.ts +0 -2
- package/dist/agent/nativeAgent.test.d.ts.map +0 -1
- package/dist/agent/nativeAgent.test.js +0 -35
- package/dist/agent/nativeAgent.test.js.map +0 -1
- package/dist/agent/nativeTools.test.d.ts +0 -2
- package/dist/agent/nativeTools.test.d.ts.map +0 -1
- package/dist/agent/nativeTools.test.js +0 -67
- package/dist/agent/nativeTools.test.js.map +0 -1
- package/dist/agent/orchestrator.test.d.ts +0 -2
- package/dist/agent/orchestrator.test.d.ts.map +0 -1
- package/dist/agent/orchestrator.test.js +0 -284
- package/dist/agent/orchestrator.test.js.map +0 -1
- package/dist/agent/session.test.d.ts +0 -2
- package/dist/agent/session.test.d.ts.map +0 -1
- package/dist/agent/session.test.js +0 -74
- package/dist/agent/session.test.js.map +0 -1
- package/dist/agent/smoke-chat.test.d.ts +0 -2
- package/dist/agent/smoke-chat.test.d.ts.map +0 -1
- package/dist/agent/smoke-chat.test.js +0 -166
- package/dist/agent/smoke-chat.test.js.map +0 -1
- package/dist/commands/add-repo.test.d.ts +0 -2
- package/dist/commands/add-repo.test.d.ts.map +0 -1
- package/dist/commands/add-repo.test.js +0 -30
- package/dist/commands/add-repo.test.js.map +0 -1
- package/dist/commands/commands.test.d.ts +0 -2
- package/dist/commands/commands.test.d.ts.map +0 -1
- package/dist/commands/commands.test.js +0 -156
- package/dist/commands/commands.test.js.map +0 -1
- package/dist/commands/commit.test.d.ts +0 -2
- package/dist/commands/commit.test.d.ts.map +0 -1
- package/dist/commands/commit.test.js +0 -54
- package/dist/commands/commit.test.js.map +0 -1
- package/dist/commands/isolate.test.d.ts +0 -2
- package/dist/commands/isolate.test.d.ts.map +0 -1
- package/dist/commands/isolate.test.js +0 -59
- package/dist/commands/isolate.test.js.map +0 -1
- package/dist/commands/knowledge.test.d.ts +0 -2
- package/dist/commands/knowledge.test.d.ts.map +0 -1
- package/dist/commands/knowledge.test.js +0 -90
- package/dist/commands/knowledge.test.js.map +0 -1
- package/dist/commands/status.test.d.ts +0 -2
- package/dist/commands/status.test.d.ts.map +0 -1
- package/dist/commands/status.test.js +0 -31
- package/dist/commands/status.test.js.map +0 -1
- package/dist/commands/ui.test.d.ts +0 -2
- package/dist/commands/ui.test.d.ts.map +0 -1
- package/dist/commands/ui.test.js +0 -58
- package/dist/commands/ui.test.js.map +0 -1
- package/dist/core/adapters/storage.test.d.ts +0 -2
- package/dist/core/adapters/storage.test.d.ts.map +0 -1
- package/dist/core/adapters/storage.test.js +0 -65
- package/dist/core/adapters/storage.test.js.map +0 -1
- package/dist/core/analysis-cache.test.d.ts +0 -2
- package/dist/core/analysis-cache.test.d.ts.map +0 -1
- package/dist/core/analysis-cache.test.js +0 -163
- package/dist/core/analysis-cache.test.js.map +0 -1
- package/dist/core/config.test.d.ts +0 -2
- package/dist/core/config.test.d.ts.map +0 -1
- package/dist/core/config.test.js +0 -90
- package/dist/core/config.test.js.map +0 -1
- package/dist/core/finish.test.d.ts +0 -2
- package/dist/core/finish.test.d.ts.map +0 -1
- package/dist/core/finish.test.js +0 -110
- package/dist/core/finish.test.js.map +0 -1
- package/dist/core/generation-lock.test.d.ts +0 -2
- package/dist/core/generation-lock.test.d.ts.map +0 -1
- package/dist/core/generation-lock.test.js +0 -134
- package/dist/core/generation-lock.test.js.map +0 -1
- package/dist/core/isolate.test.d.ts +0 -2
- package/dist/core/isolate.test.d.ts.map +0 -1
- package/dist/core/isolate.test.js +0 -320
- package/dist/core/isolate.test.js.map +0 -1
- package/dist/core/knowledge.test.d.ts +0 -2
- package/dist/core/knowledge.test.d.ts.map +0 -1
- package/dist/core/knowledge.test.js +0 -287
- package/dist/core/knowledge.test.js.map +0 -1
- package/dist/core/locks.test.d.ts +0 -2
- package/dist/core/locks.test.d.ts.map +0 -1
- package/dist/core/locks.test.js +0 -143
- package/dist/core/locks.test.js.map +0 -1
- package/dist/core/new-repo.test.d.ts +0 -2
- package/dist/core/new-repo.test.d.ts.map +0 -1
- package/dist/core/new-repo.test.js +0 -78
- package/dist/core/new-repo.test.js.map +0 -1
- package/dist/core/progress.test.d.ts +0 -2
- package/dist/core/progress.test.d.ts.map +0 -1
- package/dist/core/progress.test.js +0 -52
- package/dist/core/progress.test.js.map +0 -1
- package/dist/core/projects.test.d.ts +0 -2
- package/dist/core/projects.test.d.ts.map +0 -1
- package/dist/core/projects.test.js +0 -165
- package/dist/core/projects.test.js.map +0 -1
- package/dist/core/refresh.test.d.ts +0 -2
- package/dist/core/refresh.test.d.ts.map +0 -1
- package/dist/core/refresh.test.js +0 -93
- package/dist/core/refresh.test.js.map +0 -1
- package/dist/core/scanner.test.d.ts +0 -2
- package/dist/core/scanner.test.d.ts.map +0 -1
- package/dist/core/scanner.test.js +0 -53
- package/dist/core/scanner.test.js.map +0 -1
- package/dist/core/scheduler.test.d.ts +0 -2
- package/dist/core/scheduler.test.d.ts.map +0 -1
- package/dist/core/scheduler.test.js +0 -169
- package/dist/core/scheduler.test.js.map +0 -1
- package/dist/core/sync.test.d.ts +0 -2
- package/dist/core/sync.test.d.ts.map +0 -1
- package/dist/core/sync.test.js +0 -128
- package/dist/core/sync.test.js.map +0 -1
- package/dist/core/workspace-git.test.d.ts +0 -2
- package/dist/core/workspace-git.test.d.ts.map +0 -1
- package/dist/core/workspace-git.test.js +0 -52
- package/dist/core/workspace-git.test.js.map +0 -1
- package/dist/core/workspace-skills-workflow.integration.test.d.ts +0 -2
- package/dist/core/workspace-skills-workflow.integration.test.d.ts.map +0 -1
- package/dist/core/workspace-skills-workflow.integration.test.js +0 -177
- package/dist/core/workspace-skills-workflow.integration.test.js.map +0 -1
- package/dist/core/workspace-state.test.d.ts +0 -2
- package/dist/core/workspace-state.test.d.ts.map +0 -1
- package/dist/core/workspace-state.test.js +0 -84
- package/dist/core/workspace-state.test.js.map +0 -1
- package/dist/core/workspace.create.test.d.ts +0 -2
- package/dist/core/workspace.create.test.d.ts.map +0 -1
- package/dist/core/workspace.create.test.js +0 -224
- package/dist/core/workspace.create.test.js.map +0 -1
- package/dist/core/workspace.test.d.ts +0 -2
- package/dist/core/workspace.test.d.ts.map +0 -1
- package/dist/core/workspace.test.js +0 -53
- package/dist/core/workspace.test.js.map +0 -1
- package/dist/core/worktree.test.d.ts +0 -2
- package/dist/core/worktree.test.d.ts.map +0 -1
- package/dist/core/worktree.test.js +0 -153
- package/dist/core/worktree.test.js.map +0 -1
- package/dist/generators/base.test.d.ts +0 -2
- package/dist/generators/base.test.d.ts.map +0 -1
- package/dist/generators/base.test.js +0 -287
- package/dist/generators/base.test.js.map +0 -1
- package/dist/generators/knowledge-migration.test.d.ts +0 -2
- package/dist/generators/knowledge-migration.test.d.ts.map +0 -1
- package/dist/generators/knowledge-migration.test.js +0 -22
- package/dist/generators/knowledge-migration.test.js.map +0 -1
- package/dist/generators/plan-generator.test.d.ts +0 -2
- package/dist/generators/plan-generator.test.d.ts.map +0 -1
- package/dist/generators/plan-generator.test.js +0 -220
- package/dist/generators/plan-generator.test.js.map +0 -1
- package/dist/generators/skills-generator.test.d.ts +0 -2
- package/dist/generators/skills-generator.test.d.ts.map +0 -1
- package/dist/generators/skills-generator.test.js +0 -79
- package/dist/generators/skills-generator.test.js.map +0 -1
- package/dist/gui/assets/AgentsPage-B4fx43rd.js +0 -3
- package/dist/gui/assets/CSPContext-DBUu9tE0.js +0 -1
- package/dist/gui/assets/DashboardPage-DH52G8IG.js +0 -1
- package/dist/gui/assets/GettingStartedPage-BlTrQhvi.js +0 -1
- package/dist/gui/assets/ProjectsPage-BPVSLPXv.js +0 -1
- package/dist/gui/assets/ScaffoldRepoInline-ywcpq9PX.js +0 -1
- package/dist/gui/assets/SettingsPage-RQr8SalV.js +0 -1
- package/dist/gui/assets/SkillsPage-CYoSRrwx.js +0 -6
- package/dist/gui/assets/StartWorkPage-DBKK4lFi.js +0 -1
- package/dist/gui/assets/WorkspacesPage-DxEONvSq.js +0 -6
- package/dist/gui/assets/alert-dialog-CQAX2yRx.js +0 -1
- package/dist/gui/assets/badge-CAohJGj6.js +0 -1
- package/dist/gui/assets/bot-C2HWrAft.js +0 -1
- package/dist/gui/assets/button-BDDZnIHx.js +0 -1
- package/dist/gui/assets/card-BKXzd_5L.js +0 -1
- package/dist/gui/assets/chevron-down-qTL8HPug.js +0 -1
- package/dist/gui/assets/cpu-Cdwd84Jz.js +0 -1
- package/dist/gui/assets/empty-BdlgbifD.js +0 -1
- package/dist/gui/assets/index-BF6pre6G.css +0 -2
- package/dist/gui/assets/index-C_rwnBzF.js +0 -52
- package/dist/gui/assets/isElementDisabled-uy_EOitH.js +0 -1
- package/dist/gui/assets/label-CG5exjag.js +0 -1
- package/dist/gui/assets/square-DlIYnlSq.js +0 -1
- package/dist/gui/assets/textarea-ByfoCb54.js +0 -1
- package/dist/gui/assets/useAriaLabelledBy-ClesgjMe.js +0 -1
- package/dist/gui/assets/useValueChanged-DeYvGnKs.js +0 -1
- package/dist/gui/assets/zap-CWG_Lvki.js +0 -1
- package/dist/harness/contract.test.d.ts +0 -2
- package/dist/harness/contract.test.d.ts.map +0 -1
- package/dist/harness/contract.test.js +0 -426
- package/dist/harness/contract.test.js.map +0 -1
- package/dist/harness/harness.test.d.ts +0 -2
- package/dist/harness/harness.test.d.ts.map +0 -1
- package/dist/harness/harness.test.js +0 -215
- package/dist/harness/harness.test.js.map +0 -1
- package/dist/mcp/tools.test.d.ts +0 -2
- package/dist/mcp/tools.test.d.ts.map +0 -1
- package/dist/mcp/tools.test.js +0 -194
- package/dist/mcp/tools.test.js.map +0 -1
- package/dist/orchestration/log-tail.test.d.ts +0 -2
- package/dist/orchestration/log-tail.test.d.ts.map +0 -1
- package/dist/orchestration/log-tail.test.js +0 -72
- package/dist/orchestration/log-tail.test.js.map +0 -1
- package/dist/orchestration/orchestrator.test.d.ts +0 -2
- package/dist/orchestration/orchestrator.test.d.ts.map +0 -1
- package/dist/orchestration/orchestrator.test.js +0 -85
- package/dist/orchestration/orchestrator.test.js.map +0 -1
- package/dist/orchestration/runner.test.d.ts +0 -2
- package/dist/orchestration/runner.test.d.ts.map +0 -1
- package/dist/orchestration/runner.test.js +0 -233
- package/dist/orchestration/runner.test.js.map +0 -1
- package/dist/resources/agents-catalog.test.d.ts +0 -2
- package/dist/resources/agents-catalog.test.d.ts.map +0 -1
- package/dist/resources/agents-catalog.test.js +0 -50
- package/dist/resources/agents-catalog.test.js.map +0 -1
- package/dist/resources/codex-agent.test.d.ts +0 -2
- package/dist/resources/codex-agent.test.d.ts.map +0 -1
- package/dist/resources/codex-agent.test.js +0 -27
- package/dist/resources/codex-agent.test.js.map +0 -1
- package/dist/resources/materializer.test.d.ts +0 -2
- package/dist/resources/materializer.test.d.ts.map +0 -1
- package/dist/resources/materializer.test.js +0 -149
- package/dist/resources/materializer.test.js.map +0 -1
- package/dist/resources/service.test.d.ts +0 -2
- package/dist/resources/service.test.d.ts.map +0 -1
- package/dist/resources/service.test.js +0 -58
- package/dist/resources/service.test.js.map +0 -1
- package/dist/server.test.d.ts +0 -2
- package/dist/server.test.d.ts.map +0 -1
- package/dist/server.test.js +0 -1697
- package/dist/server.test.js.map +0 -1
- package/dist/utils/detect-ai.test.d.ts +0 -2
- package/dist/utils/detect-ai.test.d.ts.map +0 -1
- package/dist/utils/detect-ai.test.js +0 -70
- package/dist/utils/detect-ai.test.js.map +0 -1
- package/dist/utils/detect-editors.test.d.ts +0 -2
- package/dist/utils/detect-editors.test.d.ts.map +0 -1
- package/dist/utils/detect-editors.test.js +0 -85
- package/dist/utils/detect-editors.test.js.map +0 -1
- package/dist/utils/git.test.d.ts +0 -2
- package/dist/utils/git.test.d.ts.map +0 -1
- package/dist/utils/git.test.js +0 -125
- package/dist/utils/git.test.js.map +0 -1
- package/dist/utils/multi-git.test.d.ts +0 -2
- package/dist/utils/multi-git.test.d.ts.map +0 -1
- package/dist/utils/multi-git.test.js +0 -330
- package/dist/utils/multi-git.test.js.map +0 -1
- package/dist/utils/pr.test.d.ts +0 -2
- package/dist/utils/pr.test.d.ts.map +0 -1
- package/dist/utils/pr.test.js +0 -47
- package/dist/utils/pr.test.js.map +0 -1
- package/dist/utils/session-finder.test.d.ts +0 -2
- package/dist/utils/session-finder.test.d.ts.map +0 -1
- package/dist/utils/session-finder.test.js +0 -304
- package/dist/utils/session-finder.test.js.map +0 -1
- package/dist/utils/skills-catalog.test.d.ts +0 -2
- package/dist/utils/skills-catalog.test.d.ts.map +0 -1
- package/dist/utils/skills-catalog.test.js +0 -281
- package/dist/utils/skills-catalog.test.js.map +0 -1
- package/dist/utils/system-scanner.test.d.ts +0 -2
- package/dist/utils/system-scanner.test.d.ts.map +0 -1
- package/dist/utils/system-scanner.test.js +0 -73
- package/dist/utils/system-scanner.test.js.map +0 -1
- package/dist/utils/terminal-launch.test.d.ts +0 -2
- package/dist/utils/terminal-launch.test.d.ts.map +0 -1
- package/dist/utils/terminal-launch.test.js +0 -117
- package/dist/utils/terminal-launch.test.js.map +0 -1
- package/dist/utils/update-check.test.d.ts +0 -2
- package/dist/utils/update-check.test.d.ts.map +0 -1
- package/dist/utils/update-check.test.js +0 -30
- package/dist/utils/update-check.test.js.map +0 -1
- package/dist/utils/workflows.test.d.ts +0 -2
- package/dist/utils/workflows.test.d.ts.map +0 -1
- package/dist/utils/workflows.test.js +0 -86
- package/dist/utils/workflows.test.js.map +0 -1
- package/dist/utils/workspace-launch.test.d.ts +0 -2
- package/dist/utils/workspace-launch.test.d.ts.map +0 -1
- package/dist/utils/workspace-launch.test.js +0 -128
- package/dist/utils/workspace-launch.test.js.map +0 -1
|
@@ -1,320 +0,0 @@
|
|
|
1
|
-
import * as fs from 'node:fs/promises';
|
|
2
|
-
import * as path from 'node:path';
|
|
3
|
-
import * as os from 'node:os';
|
|
4
|
-
import { describe, expect, it, beforeEach, afterEach } from 'vitest';
|
|
5
|
-
import { execa } from 'execa';
|
|
6
|
-
import { isolateWorkspaceRepo } from './isolate.js';
|
|
7
|
-
import { saveFeatureConfig, loadFeatureConfig, deleteWorkspace } from './workspace.js';
|
|
8
|
-
import { resolveFeatureRepoPath, isRepoIsolated } from '../utils/feature.js';
|
|
9
|
-
import { syncWorkspace } from './sync.js';
|
|
10
|
-
import { runDoctor } from './doctor.js';
|
|
11
|
-
async function initGitRepo(dir) {
|
|
12
|
-
await fs.mkdir(dir, { recursive: true });
|
|
13
|
-
await execa('git', ['init', '-b', 'main'], { cwd: dir });
|
|
14
|
-
await execa('git', ['config', 'user.name', 'Test User'], { cwd: dir });
|
|
15
|
-
await execa('git', ['config', 'user.email', 'test@example.com'], { cwd: dir });
|
|
16
|
-
await fs.writeFile(path.join(dir, 'README.md'), '# Test Repo\n', 'utf-8');
|
|
17
|
-
await execa('git', ['add', '.'], { cwd: dir });
|
|
18
|
-
await execa('git', ['commit', '-m', 'Initial commit'], { cwd: dir });
|
|
19
|
-
}
|
|
20
|
-
describe('isolateWorkspaceRepo & on-demand worktree isolation', { timeout: 30000 }, () => {
|
|
21
|
-
let tmpDir;
|
|
22
|
-
let repo1Dir;
|
|
23
|
-
let repo2Dir;
|
|
24
|
-
let workspaceDir;
|
|
25
|
-
beforeEach(async () => {
|
|
26
|
-
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'nf-isolate-test-'));
|
|
27
|
-
repo1Dir = path.join(tmpDir, 'repo1');
|
|
28
|
-
repo2Dir = path.join(tmpDir, 'repo2');
|
|
29
|
-
workspaceDir = path.join(tmpDir, 'workspace');
|
|
30
|
-
await initGitRepo(repo1Dir);
|
|
31
|
-
await initGitRepo(repo2Dir);
|
|
32
|
-
await fs.mkdir(workspaceDir, { recursive: true });
|
|
33
|
-
});
|
|
34
|
-
afterEach(async () => {
|
|
35
|
-
try {
|
|
36
|
-
await fs.rm(tmpDir, { recursive: true, force: true, maxRetries: 5 });
|
|
37
|
-
}
|
|
38
|
-
catch { }
|
|
39
|
-
});
|
|
40
|
-
it('throws when the workspace manifest does not exist', async () => {
|
|
41
|
-
await expect(isolateWorkspaceRepo(path.join(tmpDir, 'non-existent'), 'repo1')).rejects.toThrow('Workspace manifest not found');
|
|
42
|
-
});
|
|
43
|
-
it('throws when the target repo is not in the workspace', async () => {
|
|
44
|
-
const feature = {
|
|
45
|
-
id: 'test-ws',
|
|
46
|
-
mode: 'in-place',
|
|
47
|
-
branchName: 'test-ws',
|
|
48
|
-
description: 'test in-place',
|
|
49
|
-
repos: [repo1Dir],
|
|
50
|
-
originalRepos: [repo1Dir],
|
|
51
|
-
assistants: ['antigravity'],
|
|
52
|
-
workspacePath: workspaceDir,
|
|
53
|
-
createdAt: new Date().toISOString(),
|
|
54
|
-
};
|
|
55
|
-
await saveFeatureConfig(workspaceDir, feature);
|
|
56
|
-
await expect(isolateWorkspaceRepo(workspaceDir, 'unknown-repo')).rejects.toThrow('is not part of workspace');
|
|
57
|
-
});
|
|
58
|
-
it('returns alreadyIsolated: true if workspace is already in worktree mode', async () => {
|
|
59
|
-
const feature = {
|
|
60
|
-
id: 'test-worktree-ws',
|
|
61
|
-
mode: 'worktree',
|
|
62
|
-
branchName: 'feat/all-repos',
|
|
63
|
-
description: 'test worktree mode',
|
|
64
|
-
repos: [path.join(workspaceDir, 'repo1')],
|
|
65
|
-
originalRepos: [repo1Dir],
|
|
66
|
-
assistants: ['antigravity'],
|
|
67
|
-
workspacePath: workspaceDir,
|
|
68
|
-
createdAt: new Date().toISOString(),
|
|
69
|
-
};
|
|
70
|
-
await saveFeatureConfig(workspaceDir, feature);
|
|
71
|
-
const result = await isolateWorkspaceRepo(workspaceDir, 'repo1');
|
|
72
|
-
expect(result.alreadyIsolated).toBe(true);
|
|
73
|
-
expect(result.repoName).toBe('repo1');
|
|
74
|
-
expect(result.branchName).toBe('feat/all-repos');
|
|
75
|
-
});
|
|
76
|
-
it('dynamically isolates an in-place repo into a worktree on-demand', async () => {
|
|
77
|
-
const feature = {
|
|
78
|
-
id: 'my-feature',
|
|
79
|
-
mode: 'in-place',
|
|
80
|
-
branchName: 'my-feature',
|
|
81
|
-
description: 'In-place with lazy isolation',
|
|
82
|
-
repos: [repo1Dir, repo2Dir],
|
|
83
|
-
originalRepos: [repo1Dir, repo2Dir],
|
|
84
|
-
assistants: ['antigravity', 'claude'],
|
|
85
|
-
workspacePath: workspaceDir,
|
|
86
|
-
createdAt: new Date().toISOString(),
|
|
87
|
-
};
|
|
88
|
-
await saveFeatureConfig(workspaceDir, feature);
|
|
89
|
-
// Initial state: repos are NOT isolated
|
|
90
|
-
expect(isRepoIsolated(feature, 'repo1')).toBe(false);
|
|
91
|
-
expect(resolveFeatureRepoPath(feature, workspaceDir, repo1Dir)).toBe(repo1Dir);
|
|
92
|
-
// Isolate repo1
|
|
93
|
-
const result = await isolateWorkspaceRepo(workspaceDir, 'repo1', {
|
|
94
|
-
branchName: 'feat/repo1-custom',
|
|
95
|
-
});
|
|
96
|
-
expect(result.alreadyIsolated).toBe(false);
|
|
97
|
-
expect(result.repoName).toBe('repo1');
|
|
98
|
-
expect(result.branchName).toBe('feat/repo1-custom');
|
|
99
|
-
expect(result.worktreePath).toBe(path.join(workspaceDir, 'repo1'));
|
|
100
|
-
// Check that worktree directory exists on disk and is on the right branch
|
|
101
|
-
const { stdout: branchOut } = await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
|
|
102
|
-
cwd: result.worktreePath,
|
|
103
|
-
});
|
|
104
|
-
expect(branchOut.trim()).toBe('feat/repo1-custom');
|
|
105
|
-
// Check manifest was updated
|
|
106
|
-
const updated = await loadFeatureConfig(workspaceDir);
|
|
107
|
-
expect(updated?.isolatedRepos?.['repo1']).toBeDefined();
|
|
108
|
-
expect(updated?.isolatedRepos?.['repo1']?.branchName).toBe('feat/repo1-custom');
|
|
109
|
-
expect(updated?.isolatedRepos?.['repo1']?.worktreePath).toBe(result.worktreePath);
|
|
110
|
-
// Check that resolveFeatureRepoPath now points to worktree for repo1, and source for repo2
|
|
111
|
-
expect(isRepoIsolated(updated, 'repo1')).toBe(true);
|
|
112
|
-
expect(isRepoIsolated(updated, 'repo2')).toBe(false);
|
|
113
|
-
expect(resolveFeatureRepoPath(updated, workspaceDir, repo1Dir)).toBe(result.worktreePath);
|
|
114
|
-
expect(resolveFeatureRepoPath(updated, workspaceDir, repo2Dir)).toBe(repo2Dir);
|
|
115
|
-
// Check .gitignore in workspace ignores /repo1/
|
|
116
|
-
const gitignoreContent = await fs.readFile(path.join(workspaceDir, '.gitignore'), 'utf-8');
|
|
117
|
-
expect(gitignoreContent).toContain('/repo1/');
|
|
118
|
-
// Calling isolate again on repo1 is idempotent
|
|
119
|
-
const rerun = await isolateWorkspaceRepo(workspaceDir, 'repo1');
|
|
120
|
-
expect(rerun.alreadyIsolated).toBe(true);
|
|
121
|
-
expect(rerun.branchName).toBe('feat/repo1-custom');
|
|
122
|
-
});
|
|
123
|
-
it('syncs isolated worktree repos while skipping non-isolated repos in in-place mode', async () => {
|
|
124
|
-
const remote1Dir = path.join(tmpDir, 'remote1.git');
|
|
125
|
-
const syncRepo1Dir = path.join(tmpDir, 'syncRepo1');
|
|
126
|
-
await fs.mkdir(remote1Dir, { recursive: true });
|
|
127
|
-
await execa('git', ['init', '--bare', '-b', 'main'], { cwd: remote1Dir });
|
|
128
|
-
await fs.mkdir(syncRepo1Dir, { recursive: true });
|
|
129
|
-
await execa('git', ['init', '-b', 'main'], { cwd: syncRepo1Dir });
|
|
130
|
-
await execa('git', ['config', 'user.name', 'Test User'], { cwd: syncRepo1Dir });
|
|
131
|
-
await execa('git', ['config', 'user.email', 'test@example.com'], { cwd: syncRepo1Dir });
|
|
132
|
-
await fs.writeFile(path.join(syncRepo1Dir, 'README.md'), '# Sync Repo\n', 'utf-8');
|
|
133
|
-
await execa('git', ['add', '.'], { cwd: syncRepo1Dir });
|
|
134
|
-
await execa('git', ['commit', '-m', 'Initial commit'], { cwd: syncRepo1Dir });
|
|
135
|
-
await execa('git', ['remote', 'add', 'origin', remote1Dir], { cwd: syncRepo1Dir });
|
|
136
|
-
await execa('git', ['push', '-u', 'origin', 'main'], { cwd: syncRepo1Dir });
|
|
137
|
-
const feature = {
|
|
138
|
-
id: 'sync-test',
|
|
139
|
-
mode: 'in-place',
|
|
140
|
-
branchName: 'sync-test',
|
|
141
|
-
description: 'In-place sync test',
|
|
142
|
-
repos: [syncRepo1Dir, repo2Dir],
|
|
143
|
-
originalRepos: [syncRepo1Dir, repo2Dir],
|
|
144
|
-
assistants: ['antigravity'],
|
|
145
|
-
workspacePath: workspaceDir,
|
|
146
|
-
createdAt: new Date().toISOString(),
|
|
147
|
-
};
|
|
148
|
-
await saveFeatureConfig(workspaceDir, feature);
|
|
149
|
-
// Isolate syncRepo1
|
|
150
|
-
await isolateWorkspaceRepo(workspaceDir, 'syncRepo1', { branchName: 'feat/sync-repo1' });
|
|
151
|
-
// Commit and push a new change on origin main
|
|
152
|
-
await fs.writeFile(path.join(syncRepo1Dir, 'newfile.txt'), 'hello\n');
|
|
153
|
-
await execa('git', ['add', '.'], { cwd: syncRepo1Dir });
|
|
154
|
-
await execa('git', ['commit', '-m', 'Add newfile on main'], { cwd: syncRepo1Dir });
|
|
155
|
-
await execa('git', ['push', 'origin', 'main'], { cwd: syncRepo1Dir });
|
|
156
|
-
const syncReport = await syncWorkspace(workspaceDir);
|
|
157
|
-
expect(syncReport.repos).toHaveLength(2);
|
|
158
|
-
const repo1Sync = syncReport.repos.find((r) => r.name === 'syncRepo1');
|
|
159
|
-
const repo2Sync = syncReport.repos.find((r) => r.name === 'repo2');
|
|
160
|
-
expect(repo1Sync?.status).toBe('rebased');
|
|
161
|
-
expect(repo2Sync?.message).toContain('In-place repo — branches are managed by you');
|
|
162
|
-
});
|
|
163
|
-
it('cleans up isolated worktrees when deleting an in-place workspace', async () => {
|
|
164
|
-
const feature = {
|
|
165
|
-
id: 'cleanup-test',
|
|
166
|
-
mode: 'in-place',
|
|
167
|
-
branchName: 'cleanup-test',
|
|
168
|
-
description: 'In-place cleanup test',
|
|
169
|
-
repos: [repo1Dir],
|
|
170
|
-
originalRepos: [repo1Dir],
|
|
171
|
-
assistants: ['antigravity'],
|
|
172
|
-
workspacePath: workspaceDir,
|
|
173
|
-
createdAt: new Date().toISOString(),
|
|
174
|
-
};
|
|
175
|
-
await saveFeatureConfig(workspaceDir, feature);
|
|
176
|
-
await isolateWorkspaceRepo(workspaceDir, 'repo1');
|
|
177
|
-
const worktreeDir = path.join(workspaceDir, 'repo1');
|
|
178
|
-
expect(await fs.stat(worktreeDir)).toBeDefined();
|
|
179
|
-
await deleteWorkspace(workspaceDir);
|
|
180
|
-
// Workspace directory removed
|
|
181
|
-
await expect(fs.access(workspaceDir)).rejects.toThrow();
|
|
182
|
-
// Source repo intact
|
|
183
|
-
expect(await fs.stat(repo1Dir)).toBeDefined();
|
|
184
|
-
// Worktree list in source repo is clean
|
|
185
|
-
const { stdout: wtList } = await execa('git', ['worktree', 'list'], { cwd: repo1Dir });
|
|
186
|
-
expect(wtList).not.toContain(worktreeDir);
|
|
187
|
-
});
|
|
188
|
-
it('rejects invalid or option-injected branch names', async () => {
|
|
189
|
-
const feature = {
|
|
190
|
-
id: 'sec-test',
|
|
191
|
-
mode: 'in-place',
|
|
192
|
-
branchName: 'sec-test',
|
|
193
|
-
description: 'Security validation test',
|
|
194
|
-
repos: [repo1Dir],
|
|
195
|
-
originalRepos: [repo1Dir],
|
|
196
|
-
assistants: ['antigravity'],
|
|
197
|
-
workspacePath: workspaceDir,
|
|
198
|
-
createdAt: new Date().toISOString(),
|
|
199
|
-
};
|
|
200
|
-
await saveFeatureConfig(workspaceDir, feature);
|
|
201
|
-
await expect(isolateWorkspaceRepo(workspaceDir, 'repo1', { branchName: '--lock' })).rejects.toThrow('Invalid branch name');
|
|
202
|
-
await expect(isolateWorkspaceRepo(workspaceDir, 'repo1', { branchName: '-f' })).rejects.toThrow('Invalid branch name');
|
|
203
|
-
await expect(isolateWorkspaceRepo(workspaceDir, 'repo1', { branchName: 'invalid branch with spaces' })).rejects.toThrow('Invalid branch name');
|
|
204
|
-
});
|
|
205
|
-
it('recovers and recreates worktree if directory is deleted from disk', async () => {
|
|
206
|
-
const feature = {
|
|
207
|
-
id: 'recover-test',
|
|
208
|
-
mode: 'in-place',
|
|
209
|
-
branchName: 'recover-test',
|
|
210
|
-
description: 'Recovery test',
|
|
211
|
-
repos: [repo1Dir],
|
|
212
|
-
originalRepos: [repo1Dir],
|
|
213
|
-
assistants: ['antigravity'],
|
|
214
|
-
workspacePath: workspaceDir,
|
|
215
|
-
createdAt: new Date().toISOString(),
|
|
216
|
-
};
|
|
217
|
-
await saveFeatureConfig(workspaceDir, feature);
|
|
218
|
-
// Initial isolation
|
|
219
|
-
const res1 = await isolateWorkspaceRepo(workspaceDir, 'repo1', { branchName: 'feat/rec-1' });
|
|
220
|
-
expect(res1.alreadyIsolated).toBe(false);
|
|
221
|
-
// Simulate accidental deletion of worktree folder from disk
|
|
222
|
-
await fs.rm(res1.worktreePath, { recursive: true, force: true });
|
|
223
|
-
// Calling isolate again should prune stale git registration and recreate cleanly
|
|
224
|
-
const res2 = await isolateWorkspaceRepo(workspaceDir, 'repo1', { branchName: 'feat/rec-1' });
|
|
225
|
-
expect(res2.worktreePath).toBe(res1.worktreePath);
|
|
226
|
-
expect(await fs.stat(res2.worktreePath)).toBeDefined();
|
|
227
|
-
});
|
|
228
|
-
it('handles case-insensitive repository lookups on Windows', async () => {
|
|
229
|
-
const feature = {
|
|
230
|
-
id: 'case-test',
|
|
231
|
-
mode: 'in-place',
|
|
232
|
-
branchName: 'case-test',
|
|
233
|
-
description: 'Case sensitivity test',
|
|
234
|
-
repos: [repo1Dir],
|
|
235
|
-
originalRepos: [repo1Dir],
|
|
236
|
-
assistants: ['antigravity'],
|
|
237
|
-
workspacePath: workspaceDir,
|
|
238
|
-
createdAt: new Date().toISOString(),
|
|
239
|
-
};
|
|
240
|
-
await saveFeatureConfig(workspaceDir, feature);
|
|
241
|
-
// Pass uppercase repo name 'REPO1'
|
|
242
|
-
const result = await isolateWorkspaceRepo(workspaceDir, 'REPO1', { branchName: 'feat/case-test' });
|
|
243
|
-
expect(result.repoName).toBe('repo1');
|
|
244
|
-
expect(result.branchName).toBe('feat/case-test');
|
|
245
|
-
});
|
|
246
|
-
it('handles concurrent isolation operations without manifest clobbering', async () => {
|
|
247
|
-
const feature = {
|
|
248
|
-
id: 'concurrency-test',
|
|
249
|
-
mode: 'in-place',
|
|
250
|
-
branchName: 'concurrency-test',
|
|
251
|
-
description: 'Concurrency test',
|
|
252
|
-
repos: [repo1Dir, repo2Dir],
|
|
253
|
-
originalRepos: [repo1Dir, repo2Dir],
|
|
254
|
-
assistants: ['antigravity'],
|
|
255
|
-
workspacePath: workspaceDir,
|
|
256
|
-
createdAt: new Date().toISOString(),
|
|
257
|
-
};
|
|
258
|
-
await saveFeatureConfig(workspaceDir, feature);
|
|
259
|
-
// Isolate repo1 and repo2 concurrently
|
|
260
|
-
const [res1, res2] = await Promise.all([
|
|
261
|
-
isolateWorkspaceRepo(workspaceDir, 'repo1', { branchName: 'feat/concurrent-1' }),
|
|
262
|
-
isolateWorkspaceRepo(workspaceDir, 'repo2', { branchName: 'feat/concurrent-2' }),
|
|
263
|
-
]);
|
|
264
|
-
expect(res1.repoName).toBe('repo1');
|
|
265
|
-
expect(res2.repoName).toBe('repo2');
|
|
266
|
-
const updated = await loadFeatureConfig(workspaceDir);
|
|
267
|
-
expect(updated?.isolatedRepos?.['repo1']).toBeDefined();
|
|
268
|
-
expect(updated?.isolatedRepos?.['repo2']).toBeDefined();
|
|
269
|
-
});
|
|
270
|
-
it('doctor passes cleanly on isolated in-place workspace without false branch mismatch warnings', async () => {
|
|
271
|
-
const feature = {
|
|
272
|
-
id: 'doc-test',
|
|
273
|
-
mode: 'in-place',
|
|
274
|
-
branchName: 'doc-test',
|
|
275
|
-
description: 'Doctor test',
|
|
276
|
-
repos: [repo1Dir],
|
|
277
|
-
originalRepos: [repo1Dir],
|
|
278
|
-
assistants: ['antigravity'],
|
|
279
|
-
workspacePath: workspaceDir,
|
|
280
|
-
createdAt: new Date().toISOString(),
|
|
281
|
-
};
|
|
282
|
-
await saveFeatureConfig(workspaceDir, feature);
|
|
283
|
-
await isolateWorkspaceRepo(workspaceDir, 'repo1', { branchName: 'feat/doc-isolated' });
|
|
284
|
-
const report = await runDoctor(workspaceDir);
|
|
285
|
-
const branchCheck = report.checks.find((c) => c.category === 'Branch Alignment & Git Status');
|
|
286
|
-
expect(branchCheck?.status).toBe('pass');
|
|
287
|
-
expect(report.errors).toHaveLength(0);
|
|
288
|
-
});
|
|
289
|
-
it('doctor rejects explicit contract endpoints that do not exist', async () => {
|
|
290
|
-
const feature = {
|
|
291
|
-
id: 'contract-test', mode: 'in-place', branchName: 'contract-test', description: 'Contract test',
|
|
292
|
-
repos: [repo1Dir], originalRepos: [repo1Dir], assistants: [], workspacePath: workspaceDir,
|
|
293
|
-
createdAt: new Date().toISOString(),
|
|
294
|
-
contracts: [{ from: 'src/missing-bff', to: 'src/missing-spa', kind: 'http-envelope', entry: '2026-08-25-bff-errors' }],
|
|
295
|
-
};
|
|
296
|
-
await saveFeatureConfig(workspaceDir, feature);
|
|
297
|
-
await fs.writeFile(path.join(workspaceDir, 'nexusflow-knowledge.md'), '### 2026-08-25 — bff-errors\n**Gotcha:** Decode once.\n');
|
|
298
|
-
const report = await runDoctor(workspaceDir);
|
|
299
|
-
expect(report.checks).toEqual(expect.arrayContaining([
|
|
300
|
-
expect.objectContaining({ category: 'Explicit Contracts', status: 'fail' }),
|
|
301
|
-
]));
|
|
302
|
-
});
|
|
303
|
-
it('doctor accepts explicit contract endpoints backed by real paths and knowledge', async () => {
|
|
304
|
-
await fs.mkdir(path.join(repo1Dir, 'apps', 'bff'), { recursive: true });
|
|
305
|
-
await fs.mkdir(path.join(repo1Dir, 'apps', 'spa'), { recursive: true });
|
|
306
|
-
const feature = {
|
|
307
|
-
id: 'contract-test', mode: 'in-place', branchName: 'contract-test', description: 'Contract test',
|
|
308
|
-
repos: [repo1Dir], originalRepos: [repo1Dir], assistants: [], workspacePath: workspaceDir,
|
|
309
|
-
createdAt: new Date().toISOString(),
|
|
310
|
-
contracts: [{ from: 'apps/bff', to: 'apps/spa', kind: 'http-envelope', entry: '2026-08-25-bff-errors' }],
|
|
311
|
-
};
|
|
312
|
-
await saveFeatureConfig(workspaceDir, feature);
|
|
313
|
-
await fs.writeFile(path.join(workspaceDir, 'nexusflow-knowledge.md'), '### 2026-08-25 — bff-errors\n**Gotcha:** Decode once.\n');
|
|
314
|
-
const report = await runDoctor(workspaceDir);
|
|
315
|
-
expect(report.checks).toEqual(expect.arrayContaining([
|
|
316
|
-
expect.objectContaining({ category: 'Explicit Contracts', name: 'http-envelope', status: 'pass' }),
|
|
317
|
-
]));
|
|
318
|
-
});
|
|
319
|
-
});
|
|
320
|
-
//# sourceMappingURL=isolate.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"isolate.test.js","sourceRoot":"","sources":["../../src/core/isolate.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"knowledge.test.d.ts","sourceRoot":"","sources":["../../src/core/knowledge.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
import { insertUnderHeading, formatEntry, parseKnowledgeEntries, addWorkspaceKnowledge, addBaseKnowledge, promoteKnowledge, readWorkspaceKnowledge, MAX_ENTRY_CHARS, } from './knowledge.js';
|
|
3
|
-
import * as storage from './storage.js';
|
|
4
|
-
import * as workspace from './workspace.js';
|
|
5
|
-
import * as generators from '../generators/index.js';
|
|
6
|
-
import * as fs from 'node:fs/promises';
|
|
7
|
-
import * as workspaceGit from './workspace-git.js';
|
|
8
|
-
import * as locks from './locks.js';
|
|
9
|
-
vi.mock('./storage.js');
|
|
10
|
-
vi.mock('./workspace.js');
|
|
11
|
-
vi.mock('../generators/index.js');
|
|
12
|
-
vi.mock('./workspace-git.js');
|
|
13
|
-
vi.mock('./locks.js');
|
|
14
|
-
vi.mock('node:fs/promises', async (importOriginal) => {
|
|
15
|
-
const actual = await importOriginal();
|
|
16
|
-
return { ...actual, access: vi.fn() };
|
|
17
|
-
});
|
|
18
|
-
function missingGitRepository() {
|
|
19
|
-
return Object.assign(new Error('ENOENT'), { code: 'ENOENT' });
|
|
20
|
-
}
|
|
21
|
-
// ─── Pure helpers ───────────────────────────────────────────────────────────
|
|
22
|
-
describe('insertUnderHeading', () => {
|
|
23
|
-
it('inserts under an existing heading and strips the placeholder', () => {
|
|
24
|
-
const md = `## Known Gotchas\n\n<!-- keep me -->\n\n_(No gotchas recorded yet.)_\n`;
|
|
25
|
-
const out = insertUnderHeading(md, ['Known Gotchas'], '- **2026-07-04:** watch the cache');
|
|
26
|
-
expect(out).toContain('- **2026-07-04:** watch the cache');
|
|
27
|
-
expect(out).not.toContain('No gotchas recorded yet');
|
|
28
|
-
expect(out).toContain('<!-- keep me -->'); // comments are preserved
|
|
29
|
-
});
|
|
30
|
-
it('matches a heading via an alias', () => {
|
|
31
|
-
const md = `## Discovered Gotchas & Watch-outs\n\n- None recorded yet.\n`;
|
|
32
|
-
const out = insertUnderHeading(md, ['Discovered Gotchas & Watch-outs', 'Known Gotchas'], '- **2026-07-04:** x');
|
|
33
|
-
expect(out).toContain('- **2026-07-04:** x');
|
|
34
|
-
expect(out).not.toContain('None recorded yet');
|
|
35
|
-
});
|
|
36
|
-
it('appends a new section when the heading is missing', () => {
|
|
37
|
-
const md = `# Workspace Knowledge — feat\n`;
|
|
38
|
-
const out = insertUnderHeading(md, ['Architecture Decisions'], '### 2026-07-04 — Chose X\n**Decision:** because reasons');
|
|
39
|
-
expect(out).toContain('## Architecture Decisions');
|
|
40
|
-
expect(out).toContain('**Decision:** because reasons');
|
|
41
|
-
});
|
|
42
|
-
it('preserves CRLF line endings', () => {
|
|
43
|
-
const md = `## Known Gotchas\r\n\r\n_(No gotchas recorded yet.)_\r\n`;
|
|
44
|
-
const out = insertUnderHeading(md, ['Known Gotchas'], '- foo');
|
|
45
|
-
expect(out.includes('\r\n')).toBe(true);
|
|
46
|
-
// No bare LF (every \n must be preceded by \r).
|
|
47
|
-
expect(/[^\r]\n/.test(out)).toBe(false);
|
|
48
|
-
});
|
|
49
|
-
it('passes through a leading YAML frontmatter block', () => {
|
|
50
|
-
const md = `---\ntags: ["x"]\ntype: workspace-context\n---\n\n## Known Gotchas\n\n_(No gotchas recorded yet.)_\n`;
|
|
51
|
-
const out = insertUnderHeading(md, ['Known Gotchas'], '- foo');
|
|
52
|
-
expect(out.startsWith('---')).toBe(true);
|
|
53
|
-
expect(out).toContain('tags: ["x"]');
|
|
54
|
-
expect(out).toContain('- foo');
|
|
55
|
-
});
|
|
56
|
-
it('does not destroy an existing entry when adding another', () => {
|
|
57
|
-
const md = `## Known Gotchas\n\n- **2026-07-01:** first\n`;
|
|
58
|
-
const out = insertUnderHeading(md, ['Known Gotchas'], '- **2026-07-04:** second');
|
|
59
|
-
expect(out).toContain('- **2026-07-01:** first');
|
|
60
|
-
expect(out).toContain('- **2026-07-04:** second');
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
describe('formatEntry', () => {
|
|
64
|
-
const ts = '2026-07-04T10:00:00.000Z';
|
|
65
|
-
it('formats a decision with a title as a dated ### block', () => {
|
|
66
|
-
const out = formatEntry({ type: 'decision', message: 'use worktrees', title: 'Worktrees', timestamp: ts }, 'workspace');
|
|
67
|
-
expect(out).toBe('### 2026-07-04 — worktrees\n**Decision:** use worktrees');
|
|
68
|
-
});
|
|
69
|
-
it('leads a gotcha with its title so the file stays skimmable', () => {
|
|
70
|
-
// The file only grows, so a reader must be able to judge relevance from the
|
|
71
|
-
// first few words instead of reading every entry.
|
|
72
|
-
const out = formatEntry({ type: 'gotcha', title: 'EBUSY on Windows', message: 'fs.rm needs maxRetries', timestamp: ts }, 'workspace');
|
|
73
|
-
expect(out).toBe('### 2026-07-04 — ebusy-on-windows\n**Gotcha:** fs.rm needs maxRetries');
|
|
74
|
-
});
|
|
75
|
-
it('rejects a missing title instead of deriving and truncating a heading', () => {
|
|
76
|
-
expect(() => formatEntry({ type: 'gotcha', message: 'EBUSY on Windows', timestamp: ts }, 'workspace'))
|
|
77
|
-
.toThrow(/title is required/);
|
|
78
|
-
});
|
|
79
|
-
it('does not format legacy progress without a searchable title', () => {
|
|
80
|
-
expect(() => formatEntry({ type: 'progress', message: 'shipped rollback', timestamp: ts }, 'workspace'))
|
|
81
|
-
.toThrow(/title is required/);
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
describe('entry length cap', () => {
|
|
85
|
-
beforeEach(() => {
|
|
86
|
-
vi.clearAllMocks();
|
|
87
|
-
vi.mocked(workspace.loadFeatureConfig).mockResolvedValue({ id: 'feat', repos: ['/repos/repo-a'] });
|
|
88
|
-
vi.mocked(storage.workspaceFileExists).mockResolvedValue(false);
|
|
89
|
-
vi.mocked(storage.baseFileExists).mockResolvedValue(false);
|
|
90
|
-
vi.mocked(storage.writeWorkspaceFile).mockResolvedValue(undefined);
|
|
91
|
-
vi.mocked(storage.writeBaseFile).mockResolvedValue(undefined);
|
|
92
|
-
vi.mocked(generators.buildBaseKnowledgeContent).mockReturnValue('# Base\n');
|
|
93
|
-
vi.mocked(workspaceGit.commitExactWorkspaceArtifacts).mockResolvedValue({ committed: false });
|
|
94
|
-
vi.mocked(locks.acquireLock).mockResolvedValue(vi.fn().mockResolvedValue(undefined));
|
|
95
|
-
vi.mocked(fs.access).mockRejectedValue(missingGitRepository());
|
|
96
|
-
});
|
|
97
|
-
const tooLong = 'x'.repeat(MAX_ENTRY_CHARS + 1);
|
|
98
|
-
// Enforced in core precisely because the MCP tool and the HTTP endpoint call
|
|
99
|
-
// these directly; a cap in the CLI handler bound neither.
|
|
100
|
-
it('rejects an over-long workspace entry and writes nothing', async () => {
|
|
101
|
-
await expect(addWorkspaceKnowledge('/ws', { type: 'decision', message: tooLong })).rejects.toThrow(/limit is 300/);
|
|
102
|
-
expect(storage.writeWorkspaceFile).not.toHaveBeenCalled();
|
|
103
|
-
});
|
|
104
|
-
it('rejects an over-long base entry and writes nothing', async () => {
|
|
105
|
-
await expect(addBaseKnowledge('/ws', 'repo-a', { type: 'gotcha', message: tooLong })).rejects.toThrow(/limit is 300/);
|
|
106
|
-
expect(storage.writeBaseFile).not.toHaveBeenCalled();
|
|
107
|
-
});
|
|
108
|
-
it('explains how to shorten rather than only refusing', async () => {
|
|
109
|
-
await expect(addWorkspaceKnowledge('/ws', { type: 'decision', message: tooLong })).rejects.toThrow(/separate entries/);
|
|
110
|
-
});
|
|
111
|
-
it('accepts an entry at the limit', async () => {
|
|
112
|
-
await expect(addWorkspaceKnowledge('/ws', { type: 'decision', title: 'At limit', message: 'x'.repeat(MAX_ENTRY_CHARS) })).resolves.toBeTruthy();
|
|
113
|
-
});
|
|
114
|
-
it('stores the same collapsed string it measured', async () => {
|
|
115
|
-
// Validating the trimmed form and storing the raw one let embedded newlines
|
|
116
|
-
// past the limit and broke the one-entry-per-line shape.
|
|
117
|
-
await addWorkspaceKnowledge('/ws', {
|
|
118
|
-
type: 'gotcha',
|
|
119
|
-
title: 'Spacing',
|
|
120
|
-
message: ' keep it\n\n on one line ',
|
|
121
|
-
timestamp: '2026-07-04T10:00:00.000Z',
|
|
122
|
-
});
|
|
123
|
-
const written = vi.mocked(storage.writeWorkspaceFile).mock.calls[0][3];
|
|
124
|
-
expect(written).toContain('### 2026-07-04 — spacing\n**Gotcha:** keep it on one line');
|
|
125
|
-
expect(written).not.toMatch(/keep {2,}it/);
|
|
126
|
-
});
|
|
127
|
-
it('still rejects an empty message', async () => {
|
|
128
|
-
await expect(addWorkspaceKnowledge('/ws', { type: 'decision', message: ' ' })).rejects.toThrow(/cannot be empty/);
|
|
129
|
-
});
|
|
130
|
-
it('requires a title and rejects rather than truncating long titles', async () => {
|
|
131
|
-
await expect(addWorkspaceKnowledge('/ws', { type: 'gotcha', message: 'rule' }))
|
|
132
|
-
.rejects.toThrow(/title is required/);
|
|
133
|
-
await expect(addWorkspaceKnowledge('/ws', { type: 'gotcha', title: 'x'.repeat(61), message: 'rule' }))
|
|
134
|
-
.rejects.toThrow(/rejected rather than truncated/);
|
|
135
|
-
});
|
|
136
|
-
it('rejects authored progress and invalid scope traversal', async () => {
|
|
137
|
-
await expect(addWorkspaceKnowledge('/ws', { type: 'progress', title: 'Done', message: 'done' }))
|
|
138
|
-
.rejects.toThrow(/derived from live git state/);
|
|
139
|
-
await expect(addWorkspaceKnowledge('/ws', { type: 'gotcha', title: 'Scope', scope: 'path:../secret', message: 'rule' }))
|
|
140
|
-
.rejects.toThrow(/parent traversal/);
|
|
141
|
-
});
|
|
142
|
-
it('renders scope and evidence as searchable metadata', async () => {
|
|
143
|
-
await addWorkspaceKnowledge('/ws', {
|
|
144
|
-
type: 'gotcha', title: 'BFF error encoding', scope: 'seam:bff-spa', evidence: 'commit abc123', message: 'Decode once.',
|
|
145
|
-
timestamp: '2026-08-25T00:00:00.000Z',
|
|
146
|
-
});
|
|
147
|
-
const written = vi.mocked(storage.writeWorkspaceFile).mock.calls.at(-1)[3];
|
|
148
|
-
expect(written).toContain('### 2026-08-25 — bff-error-encoding');
|
|
149
|
-
expect(written).toContain('**Scope:** `seam:bff-spa`');
|
|
150
|
-
expect(written).toContain('**Evidence:** commit abc123');
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
describe('parseKnowledgeEntries', () => {
|
|
154
|
-
it('parses bullet entries and decision blocks with their types', () => {
|
|
155
|
-
const md = [
|
|
156
|
-
'## Known Gotchas',
|
|
157
|
-
'',
|
|
158
|
-
'- **2026-07-04:** watch out',
|
|
159
|
-
'',
|
|
160
|
-
'## Architecture Decisions',
|
|
161
|
-
'',
|
|
162
|
-
'### 2026-07-04 — Chose X',
|
|
163
|
-
'**Decision:** because',
|
|
164
|
-
'',
|
|
165
|
-
].join('\n');
|
|
166
|
-
const parsed = parseKnowledgeEntries(md);
|
|
167
|
-
expect(parsed).toContainEqual({
|
|
168
|
-
section: 'Known Gotchas',
|
|
169
|
-
type: 'gotcha',
|
|
170
|
-
text: '- **2026-07-04:** watch out',
|
|
171
|
-
});
|
|
172
|
-
const decision = parsed.find((p) => p.type === 'decision');
|
|
173
|
-
expect(decision?.text).toContain('### 2026-07-04 — Chose X');
|
|
174
|
-
expect(decision?.text).toContain('**Decision:** because');
|
|
175
|
-
});
|
|
176
|
-
it('ignores placeholder and comment lines', () => {
|
|
177
|
-
const md = `## Known Gotchas\n\n<!-- hint -->\n\n_(No gotchas recorded yet.)_\n`;
|
|
178
|
-
expect(parseKnowledgeEntries(md)).toHaveLength(0);
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
// ─── Adapter-routed I/O (in-memory storage mock) ────────────────────────────
|
|
182
|
-
describe('knowledge I/O', () => {
|
|
183
|
-
const ws = new Map();
|
|
184
|
-
const base = new Map();
|
|
185
|
-
beforeEach(() => {
|
|
186
|
-
vi.clearAllMocks();
|
|
187
|
-
ws.clear();
|
|
188
|
-
base.clear();
|
|
189
|
-
vi.mocked(workspaceGit.commitExactWorkspaceArtifacts).mockResolvedValue({ committed: false });
|
|
190
|
-
vi.mocked(locks.acquireLock).mockResolvedValue(vi.fn().mockResolvedValue(undefined));
|
|
191
|
-
vi.mocked(fs.access).mockRejectedValue(missingGitRepository());
|
|
192
|
-
vi.mocked(workspace.loadFeatureConfig).mockResolvedValue({ id: 'feat', repos: ['/repos/api'] });
|
|
193
|
-
vi.mocked(generators.buildBaseKnowledgeContent).mockImplementation((repo) => `# Base Codebase Knowledge — ${repo}\n\n## Discovered Gotchas & Watch-outs\n- None recorded yet.\n\n## Architecture Decisions\n- None recorded yet.\n`);
|
|
194
|
-
vi.mocked(storage.workspaceFileExists).mockImplementation(async (_w, fid, fn) => ws.has(`${fid}/${fn}`));
|
|
195
|
-
vi.mocked(storage.readWorkspaceFile).mockImplementation(async (_w, fid, fn) => ws.get(`${fid}/${fn}`));
|
|
196
|
-
vi.mocked(storage.writeWorkspaceFile).mockImplementation(async (_w, fid, fn, c) => {
|
|
197
|
-
ws.set(`${fid}/${fn}`, c);
|
|
198
|
-
});
|
|
199
|
-
vi.mocked(storage.resolveWorkspaceFileUrl).mockImplementation((_w, fid, fn) => `ws:/${fid}/${fn}`);
|
|
200
|
-
vi.mocked(storage.baseFileExists).mockImplementation(async (_w, repo, fn) => base.has(`${repo}/${fn}`));
|
|
201
|
-
vi.mocked(storage.readBaseFile).mockImplementation(async (_w, repo, fn) => base.get(`${repo}/${fn}`));
|
|
202
|
-
vi.mocked(storage.writeBaseFile).mockImplementation(async (_w, repo, fn, c) => {
|
|
203
|
-
base.set(`${repo}/${fn}`, c);
|
|
204
|
-
});
|
|
205
|
-
vi.mocked(storage.resolveBaseFileUrl).mockImplementation((_w, repo, fn) => `base:/${repo}/${fn}`);
|
|
206
|
-
});
|
|
207
|
-
it('creates the workspace knowledge file when missing and records the entry', async () => {
|
|
208
|
-
const result = await addWorkspaceKnowledge('/wsp', {
|
|
209
|
-
type: 'decision',
|
|
210
|
-
message: 'store knowledge via the adapter',
|
|
211
|
-
title: 'Adapter routing',
|
|
212
|
-
});
|
|
213
|
-
expect(result.createdFile).toBe(true);
|
|
214
|
-
const content = ws.get('feat/nexusflow-knowledge.md');
|
|
215
|
-
expect(content).toContain('## Architecture Decisions');
|
|
216
|
-
expect(content).toContain('**Decision:** store knowledge via the adapter');
|
|
217
|
-
});
|
|
218
|
-
it('treats an identical retry as success without appending a duplicate', async () => {
|
|
219
|
-
const entry = {
|
|
220
|
-
type: 'decision',
|
|
221
|
-
message: 'store knowledge once',
|
|
222
|
-
title: 'Idempotent remember',
|
|
223
|
-
timestamp: '2026-08-26T00:00:00.000Z',
|
|
224
|
-
};
|
|
225
|
-
await addWorkspaceKnowledge('/wsp', entry);
|
|
226
|
-
const retry = await addWorkspaceKnowledge('/wsp', entry);
|
|
227
|
-
expect(retry.duplicate).toBe(true);
|
|
228
|
-
expect(ws.get('feat/nexusflow-knowledge.md').match(/### 2026-08-26 — idempotent-remember/g)).toHaveLength(1);
|
|
229
|
-
});
|
|
230
|
-
it('rejects a same-day title collision with different content', async () => {
|
|
231
|
-
await addWorkspaceKnowledge('/wsp', {
|
|
232
|
-
type: 'decision', title: 'Stable identity', message: 'first rule', timestamp: '2026-08-26T00:00:00.000Z',
|
|
233
|
-
});
|
|
234
|
-
await expect(addWorkspaceKnowledge('/wsp', {
|
|
235
|
-
type: 'decision', title: 'Stable identity', message: 'different rule', timestamp: '2026-08-26T01:00:00.000Z',
|
|
236
|
-
})).rejects.toThrow(/already exists with different content/);
|
|
237
|
-
});
|
|
238
|
-
it('reports a Git commit failure without failing the completed knowledge write', async () => {
|
|
239
|
-
vi.mocked(fs.access).mockResolvedValue(undefined);
|
|
240
|
-
vi.mocked(workspaceGit.commitExactWorkspaceArtifacts).mockRejectedValue(new Error('index locked'));
|
|
241
|
-
const result = await addWorkspaceKnowledge('/wsp', {
|
|
242
|
-
type: 'gotcha', title: 'Commit recovery', message: 'Keep the durable adapter write.',
|
|
243
|
-
timestamp: '2026-08-26T00:00:00.000Z',
|
|
244
|
-
});
|
|
245
|
-
expect(result.commit).toEqual({ status: 'failed', message: 'index locked' });
|
|
246
|
-
expect(ws.get('feat/nexusflow-knowledge.md')).toContain('Keep the durable adapter write.');
|
|
247
|
-
});
|
|
248
|
-
it('rejects an empty message', async () => {
|
|
249
|
-
await expect(addWorkspaceKnowledge('/wsp', { type: 'gotcha', message: ' ' })).rejects.toThrow(/cannot be empty/i);
|
|
250
|
-
});
|
|
251
|
-
it('adds to a repo base file, bootstrapping it from the template', async () => {
|
|
252
|
-
const result = await addBaseKnowledge('/wsp', 'api', { type: 'gotcha', title: 'Flaky CI test', message: 'flaky test on CI' });
|
|
253
|
-
expect(result.createdFile).toBe(true);
|
|
254
|
-
const content = base.get('api/nexusflow-knowledge.md');
|
|
255
|
-
expect(content).toContain('## Discovered Gotchas & Watch-outs');
|
|
256
|
-
expect(content).toContain('flaky test on CI');
|
|
257
|
-
});
|
|
258
|
-
it('rejects traversal and unknown repo names before touching base storage', async () => {
|
|
259
|
-
await expect(addBaseKnowledge('/wsp', '../outside', {
|
|
260
|
-
type: 'gotcha', title: 'Traversal', message: 'must stay contained',
|
|
261
|
-
})).rejects.toThrow(/Invalid repository name/);
|
|
262
|
-
await expect(addBaseKnowledge('/wsp', 'unknown', {
|
|
263
|
-
type: 'gotcha', title: 'Unknown', message: 'must be configured',
|
|
264
|
-
})).rejects.toThrow(/not in this workspace/);
|
|
265
|
-
expect(storage.baseFileExists).not.toHaveBeenCalled();
|
|
266
|
-
expect(storage.writeBaseFile).not.toHaveBeenCalled();
|
|
267
|
-
});
|
|
268
|
-
it('promotes a gotcha to base knowledge (copy leaves the workspace entry)', async () => {
|
|
269
|
-
ws.set('feat/nexusflow-knowledge.md', `# Workspace Knowledge — feat\n\n## Known Gotchas\n\n- **2026-07-04:** shared learning\n`);
|
|
270
|
-
const entries = parseKnowledgeEntries((await readWorkspaceKnowledge('/wsp')));
|
|
271
|
-
const result = await promoteKnowledge('/wsp', { repoName: 'api', entries, mode: 'copy' });
|
|
272
|
-
expect(result.promotedCount).toBe(1);
|
|
273
|
-
expect(base.get('api/nexusflow-knowledge.md')).toContain('- **2026-07-04:** shared learning');
|
|
274
|
-
// Copy mode keeps the original.
|
|
275
|
-
expect(ws.get('feat/nexusflow-knowledge.md')).toContain('- **2026-07-04:** shared learning');
|
|
276
|
-
});
|
|
277
|
-
it('move mode replaces the promoted workspace entry with a note', async () => {
|
|
278
|
-
ws.set('feat/nexusflow-knowledge.md', `# Workspace Knowledge — feat\n\n## Known Gotchas\n\n- **2026-07-04:** shared learning\n`);
|
|
279
|
-
const entries = parseKnowledgeEntries((await readWorkspaceKnowledge('/wsp')));
|
|
280
|
-
await promoteKnowledge('/wsp', { repoName: 'api', entries, mode: 'move' });
|
|
281
|
-
const wsContent = ws.get('feat/nexusflow-knowledge.md');
|
|
282
|
-
expect(wsContent).not.toContain('shared learning');
|
|
283
|
-
expect(wsContent).toContain('Promoted to api base knowledge');
|
|
284
|
-
expect(base.get('api/nexusflow-knowledge.md')).toContain('shared learning');
|
|
285
|
-
});
|
|
286
|
-
});
|
|
287
|
-
//# sourceMappingURL=knowledge.test.js.map
|