@xingular/harness 0.1.7 → 1.1.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/CHANGELOG.md +125 -1
- package/LICENSE +202 -0
- package/NOTICE.md +22 -0
- package/README.md +239 -86
- package/THIRD_PARTY_LICENSES.md +942 -0
- package/dist/cli.js +17853 -13114
- package/dist/sdk/accounts/accounts.d.ts +165 -0
- package/dist/sdk/accounts/accounts.js +730 -0
- package/dist/sdk/accounts/choices.d.ts +23 -0
- package/dist/sdk/accounts/choices.js +62 -0
- package/dist/sdk/accounts/env.d.ts +78 -0
- package/dist/sdk/accounts/env.js +294 -0
- package/dist/sdk/accounts/secrets.d.ts +16 -0
- package/dist/sdk/accounts/secrets.js +40 -0
- package/dist/sdk/accounts/store.d.ts +114 -0
- package/dist/sdk/accounts/store.js +255 -0
- package/dist/sdk/agents/builtin.d.ts +2 -0
- package/dist/sdk/agents/builtin.js +34 -0
- package/dist/sdk/agents/narrow.d.ts +13 -0
- package/dist/sdk/agents/narrow.js +29 -0
- package/dist/sdk/agents/profiles.d.ts +80 -0
- package/dist/sdk/agents/profiles.js +221 -0
- package/dist/sdk/annotations/bridge.d.ts +42 -0
- package/dist/sdk/annotations/bridge.js +264 -0
- package/dist/sdk/annotations/capture.d.ts +116 -0
- package/dist/sdk/annotations/capture.js +308 -0
- package/dist/sdk/annotations/delivery.d.ts +72 -0
- package/dist/sdk/annotations/delivery.js +130 -0
- package/dist/sdk/annotations/inspect.d.ts +10 -0
- package/dist/sdk/annotations/inspect.js +33 -0
- package/dist/sdk/annotations/isolated.d.ts +6 -0
- package/dist/sdk/annotations/isolated.js +51 -0
- package/dist/sdk/annotations/pageScript.d.ts +28 -0
- package/dist/sdk/annotations/pageScript.js +570 -0
- package/dist/sdk/annotations/part.d.ts +10 -0
- package/dist/sdk/annotations/part.js +144 -0
- package/dist/sdk/annotations/queue.d.ts +4 -0
- package/dist/sdk/annotations/queue.js +40 -0
- package/dist/sdk/annotations/serverMethods.d.ts +3 -0
- package/dist/sdk/annotations/serverMethods.js +62 -0
- package/dist/sdk/annotations/store.d.ts +160 -0
- package/dist/sdk/annotations/store.js +386 -0
- package/dist/sdk/browser/config.d.ts +16 -0
- package/dist/sdk/browser/config.js +22 -0
- package/dist/sdk/browser/diagnostics.d.ts +4 -0
- package/dist/sdk/browser/diagnostics.js +38 -0
- package/dist/sdk/browser/index.d.ts +28 -0
- package/dist/sdk/browser/index.js +72 -0
- package/dist/sdk/browser/network.d.ts +10 -0
- package/dist/sdk/browser/network.js +59 -0
- package/dist/sdk/browser/serverMethods.d.ts +3 -0
- package/dist/sdk/browser/serverMethods.js +7 -0
- package/dist/sdk/browser/session.d.ts +85 -0
- package/dist/sdk/browser/session.js +228 -0
- package/dist/sdk/browser/tools.d.ts +8 -0
- package/dist/sdk/browser/tools.js +329 -0
- package/dist/sdk/capabilities/api.d.ts +22 -0
- package/dist/sdk/capabilities/api.js +54 -0
- package/dist/sdk/capabilities/runSnapshot.d.ts +18 -0
- package/dist/sdk/capabilities/runSnapshot.js +47 -0
- package/dist/sdk/capabilities/types.d.ts +29 -0
- package/dist/sdk/capabilities/types.js +1 -0
- package/dist/sdk/cli.d.ts +2 -0
- package/dist/sdk/cli.js +150 -0
- package/dist/sdk/core/bus.d.ts +23 -0
- package/dist/sdk/core/bus.js +76 -0
- package/dist/sdk/core/caller.d.ts +22 -0
- package/dist/sdk/core/caller.js +16 -0
- package/dist/sdk/core/changes.d.ts +15 -0
- package/dist/sdk/core/changes.js +15 -0
- package/dist/sdk/core/effort.d.ts +2 -0
- package/dist/sdk/core/effort.js +1 -0
- package/dist/sdk/core/env.d.ts +18 -0
- package/dist/sdk/core/env.js +8 -0
- package/dist/sdk/core/errors.d.ts +15 -0
- package/dist/sdk/core/errors.js +24 -0
- package/dist/sdk/core/frontmatter.d.ts +12 -0
- package/dist/sdk/core/frontmatter.js +50 -0
- package/dist/sdk/core/fs.d.ts +18 -0
- package/dist/sdk/core/fs.js +106 -0
- package/dist/sdk/core/index.d.ts +24 -0
- package/dist/sdk/core/index.js +187 -0
- package/dist/sdk/core/path.d.ts +7 -0
- package/dist/sdk/core/path.js +79 -0
- package/dist/sdk/core/projects.d.ts +18 -0
- package/dist/sdk/core/projects.js +67 -0
- package/dist/sdk/core/secrets.d.ts +2 -0
- package/dist/sdk/core/secrets.js +5 -0
- package/dist/sdk/core/text.d.ts +7 -0
- package/dist/sdk/core/text.js +40 -0
- package/dist/sdk/doctor/checks.d.ts +5 -0
- package/dist/sdk/doctor/checks.js +208 -0
- package/dist/sdk/doctor/probe.d.ts +4 -0
- package/dist/sdk/doctor/probe.js +92 -0
- package/dist/sdk/doctor/serverMethods.d.ts +3 -0
- package/dist/sdk/doctor/serverMethods.js +8 -0
- package/dist/sdk/doctor/service.d.ts +23 -0
- package/dist/sdk/doctor/service.js +144 -0
- package/dist/sdk/doctor/types.d.ts +141 -0
- package/dist/sdk/doctor/types.js +29 -0
- package/dist/sdk/harness.d.ts +148 -0
- package/dist/sdk/harness.js +338 -0
- package/dist/sdk/history/lessonPrompt.d.ts +2 -0
- package/dist/sdk/history/lessonPrompt.js +15 -0
- package/dist/sdk/history/lessons.d.ts +52 -0
- package/dist/sdk/history/lessons.js +173 -0
- package/dist/sdk/history/recall.d.ts +68 -0
- package/dist/sdk/history/recall.js +199 -0
- package/dist/sdk/history/serverMethods.d.ts +3 -0
- package/dist/sdk/history/serverMethods.js +8 -0
- package/dist/sdk/history/trajectory.d.ts +7 -0
- package/dist/sdk/history/trajectory.js +216 -0
- package/dist/sdk/hub/catalog.json +123 -0
- package/dist/sdk/hub/cli.d.ts +7 -0
- package/dist/sdk/hub/cli.js +81 -0
- package/dist/sdk/hub/hub.d.ts +74 -0
- package/dist/sdk/hub/hub.js +474 -0
- package/dist/sdk/hub/schema.d.ts +280 -0
- package/dist/sdk/hub/schema.js +78 -0
- package/dist/sdk/hub/serverMethods.d.ts +3 -0
- package/dist/sdk/hub/serverMethods.js +11 -0
- package/dist/sdk/index.d.ts +73 -0
- package/dist/sdk/index.js +55 -0
- package/dist/sdk/mcp/connections.d.ts +83 -0
- package/dist/sdk/mcp/connections.js +676 -0
- package/dist/sdk/mcp/manager.d.ts +26 -0
- package/dist/sdk/mcp/manager.js +124 -0
- package/dist/sdk/mcp/oauth.d.ts +35 -0
- package/dist/sdk/mcp/oauth.js +171 -0
- package/dist/sdk/mcp/scopeMigration.d.ts +19 -0
- package/dist/sdk/mcp/scopeMigration.js +198 -0
- package/dist/sdk/mcp/serverMethods.d.ts +3 -0
- package/dist/sdk/mcp/serverMethods.js +22 -0
- package/dist/sdk/mcp/service.d.ts +160 -0
- package/dist/sdk/mcp/service.js +510 -0
- package/dist/sdk/mcp/types.d.ts +131 -0
- package/dist/sdk/mcp/types.js +49 -0
- package/dist/sdk/pi/runtime.d.ts +13 -0
- package/dist/sdk/pi/runtime.js +31 -0
- package/dist/sdk/plugins/api.d.ts +66 -0
- package/dist/sdk/plugins/api.js +155 -0
- package/dist/sdk/plugins/attachments.d.ts +46 -0
- package/dist/sdk/plugins/attachments.js +111 -0
- package/dist/sdk/plugins/builtin.d.ts +7 -0
- package/dist/sdk/plugins/builtin.js +163 -0
- package/dist/sdk/plugins/builtinRegistry.d.ts +53 -0
- package/dist/sdk/plugins/builtinRegistry.js +49 -0
- package/dist/sdk/plugins/catalogue.d.ts +29 -0
- package/dist/sdk/plugins/catalogue.js +196 -0
- package/dist/sdk/plugins/cli.d.ts +13 -0
- package/dist/sdk/plugins/cli.js +188 -0
- package/dist/sdk/plugins/discover.d.ts +42 -0
- package/dist/sdk/plugins/discover.js +115 -0
- package/dist/sdk/plugins/firstParty.d.ts +50 -0
- package/dist/sdk/plugins/firstParty.js +113 -0
- package/dist/sdk/plugins/hooks.d.ts +94 -0
- package/dist/sdk/plugins/hooks.js +162 -0
- package/dist/sdk/plugins/identity.d.ts +19 -0
- package/dist/sdk/plugins/identity.js +48 -0
- package/dist/sdk/plugins/install.d.ts +20 -0
- package/dist/sdk/plugins/install.js +110 -0
- package/dist/sdk/plugins/inventory.d.ts +22 -0
- package/dist/sdk/plugins/inventory.js +110 -0
- package/dist/sdk/plugins/manifest.d.ts +13 -0
- package/dist/sdk/plugins/manifest.js +56 -0
- package/dist/sdk/plugins/plugins.d.ts +104 -0
- package/dist/sdk/plugins/plugins.js +164 -0
- package/dist/sdk/plugins/runtime.d.ts +9 -0
- package/dist/sdk/plugins/runtime.js +95 -0
- package/dist/sdk/plugins/trust.d.ts +44 -0
- package/dist/sdk/plugins/trust.js +120 -0
- package/dist/sdk/plugins/types.d.ts +159 -0
- package/dist/sdk/plugins/types.js +7 -0
- package/dist/sdk/prompt/compile.d.ts +177 -0
- package/dist/sdk/prompt/compile.js +413 -0
- package/dist/sdk/refine/cli.d.ts +4 -0
- package/dist/sdk/refine/cli.js +186 -0
- package/dist/sdk/refine/demo.d.ts +21 -0
- package/dist/sdk/refine/demo.js +114 -0
- package/dist/sdk/refine/evidence.d.ts +55 -0
- package/dist/sdk/refine/evidence.js +330 -0
- package/dist/sdk/refine/host.d.ts +51 -0
- package/dist/sdk/refine/host.js +76 -0
- package/dist/sdk/refine/ledger.d.ts +48 -0
- package/dist/sdk/refine/ledger.js +76 -0
- package/dist/sdk/refine/library.d.ts +55 -0
- package/dist/sdk/refine/library.js +177 -0
- package/dist/sdk/refine/pi.d.ts +72 -0
- package/dist/sdk/refine/pi.js +248 -0
- package/dist/sdk/refine/prompts.d.ts +45 -0
- package/dist/sdk/refine/prompts.js +390 -0
- package/dist/sdk/refine/recursion.d.ts +113 -0
- package/dist/sdk/refine/recursion.js +258 -0
- package/dist/sdk/refine/runner.d.ts +81 -0
- package/dist/sdk/refine/runner.js +150 -0
- package/dist/sdk/refine/selection.d.ts +57 -0
- package/dist/sdk/refine/selection.js +251 -0
- package/dist/sdk/refine/serverMethods.d.ts +3 -0
- package/dist/sdk/refine/serverMethods.js +20 -0
- package/dist/sdk/refine/service.d.ts +84 -0
- package/dist/sdk/refine/service.js +165 -0
- package/dist/sdk/refine/suite.d.ts +67 -0
- package/dist/sdk/refine/suite.js +174 -0
- package/dist/sdk/refine/trajectory.d.ts +9 -0
- package/dist/sdk/refine/trajectory.js +68 -0
- package/dist/sdk/refine/types.d.ts +77 -0
- package/dist/sdk/refine/types.js +10 -0
- package/dist/sdk/server/methods.d.ts +3 -0
- package/dist/sdk/server/methods.js +293 -0
- package/dist/sdk/server/params.d.ts +4 -0
- package/dist/sdk/server/params.js +11 -0
- package/dist/sdk/server/remote.d.ts +19 -0
- package/dist/sdk/server/remote.js +84 -0
- package/dist/sdk/server/rpc.d.ts +20 -0
- package/dist/sdk/server/rpc.js +102 -0
- package/dist/sdk/server/serve.d.ts +10 -0
- package/dist/sdk/server/serve.js +18 -0
- package/dist/sdk/sessions/approvals.d.ts +47 -0
- package/dist/sdk/sessions/approvals.js +119 -0
- package/dist/sdk/sessions/continuation.d.ts +48 -0
- package/dist/sdk/sessions/continuation.js +85 -0
- package/dist/sdk/sessions/contracts.d.ts +551 -0
- package/dist/sdk/sessions/contracts.js +338 -0
- package/dist/sdk/sessions/extensionUi.d.ts +19 -0
- package/dist/sdk/sessions/extensionUi.js +64 -0
- package/dist/sdk/sessions/history.d.ts +16 -0
- package/dist/sdk/sessions/history.js +68 -0
- package/dist/sdk/sessions/lineageJoin.d.ts +2 -0
- package/dist/sdk/sessions/lineageJoin.js +61 -0
- package/dist/sdk/sessions/planMode.d.ts +39 -0
- package/dist/sdk/sessions/planMode.js +93 -0
- package/dist/sdk/sessions/policy.d.ts +43 -0
- package/dist/sdk/sessions/policy.js +1 -0
- package/dist/sdk/sessions/pricing.d.ts +34 -0
- package/dist/sdk/sessions/pricing.js +40 -0
- package/dist/sdk/sessions/reasoningSummaries.d.ts +11 -0
- package/dist/sdk/sessions/reasoningSummaries.js +61 -0
- package/dist/sdk/sessions/registry.d.ts +103 -0
- package/dist/sdk/sessions/registry.js +386 -0
- package/dist/sdk/sessions/runIndex.d.ts +21 -0
- package/dist/sdk/sessions/runIndex.js +65 -0
- package/dist/sdk/sessions/runStore.d.ts +66 -0
- package/dist/sdk/sessions/runStore.js +337 -0
- package/dist/sdk/sessions/runner.d.ts +213 -0
- package/dist/sdk/sessions/runner.js +589 -0
- package/dist/sdk/sessions/sessions.d.ts +152 -0
- package/dist/sdk/sessions/sessions.js +461 -0
- package/dist/sdk/sessions/sideQuestionServerMethods.d.ts +3 -0
- package/dist/sdk/sessions/sideQuestionServerMethods.js +19 -0
- package/dist/sdk/sessions/sideQuestions.d.ts +66 -0
- package/dist/sdk/sessions/sideQuestions.js +290 -0
- package/dist/sdk/sessions/subagentServerMethods.d.ts +3 -0
- package/dist/sdk/sessions/subagentServerMethods.js +41 -0
- package/dist/sdk/sessions/subagentService.d.ts +52 -0
- package/dist/sdk/sessions/subagentService.js +265 -0
- package/dist/sdk/sessions/subagents.d.ts +58 -0
- package/dist/sdk/sessions/subagents.js +87 -0
- package/dist/sdk/terminal/accountsMenu.d.ts +46 -0
- package/dist/sdk/terminal/accountsMenu.js +392 -0
- package/dist/sdk/terminal/browser.d.ts +62 -0
- package/dist/sdk/terminal/browser.js +41 -0
- package/dist/sdk/terminal/browserControl.d.ts +29 -0
- package/dist/sdk/terminal/browserControl.js +186 -0
- package/dist/sdk/terminal/cli.d.ts +20 -0
- package/dist/sdk/terminal/cli.js +121 -0
- package/dist/sdk/terminal/client.d.ts +15 -0
- package/dist/sdk/terminal/client.js +126 -0
- package/dist/sdk/terminal/commandHelp.d.ts +17 -0
- package/dist/sdk/terminal/commandHelp.js +20 -0
- package/dist/sdk/terminal/control.d.ts +4 -0
- package/dist/sdk/terminal/control.js +25 -0
- package/dist/sdk/terminal/controller.d.ts +78 -0
- package/dist/sdk/terminal/controller.js +383 -0
- package/dist/sdk/terminal/hubMenu.d.ts +10 -0
- package/dist/sdk/terminal/hubMenu.js +34 -0
- package/dist/sdk/terminal/launch.d.ts +5 -0
- package/dist/sdk/terminal/launch.js +27 -0
- package/dist/sdk/terminal/logs.d.ts +14 -0
- package/dist/sdk/terminal/logs.js +59 -0
- package/dist/sdk/terminal/opentui/subagentsWidget.d.ts +28 -0
- package/dist/sdk/terminal/opentui/subagentsWidget.js +52 -0
- package/dist/sdk/terminal/piExtension.d.ts +6 -0
- package/dist/sdk/terminal/piExtension.js +377 -0
- package/dist/sdk/terminal/pluginMenu.d.ts +34 -0
- package/dist/sdk/terminal/pluginMenu.js +101 -0
- package/dist/sdk/terminal/socket.d.ts +73 -0
- package/dist/sdk/terminal/socket.js +287 -0
- package/dist/sdk/terminal/standalone.d.ts +20 -0
- package/dist/sdk/terminal/standalone.js +186 -0
- package/dist/sdk/terminal/subagentMonitor.d.ts +38 -0
- package/dist/sdk/terminal/subagentMonitor.js +121 -0
- package/dist/sdk/terminal/terminals.d.ts +212 -0
- package/dist/sdk/terminal/terminals.js +1108 -0
- package/dist/sdk/terminal/trajectory.d.ts +10 -0
- package/dist/sdk/terminal/trajectory.js +30 -0
- package/dist/sdk/terminal/tui/annotateCommand.d.ts +3 -0
- package/dist/sdk/terminal/tui/annotateCommand.js +22 -0
- package/dist/sdk/terminal/tui/chrome.d.ts +64 -0
- package/dist/sdk/terminal/tui/chrome.js +169 -0
- package/dist/sdk/terminal/tui/clipboardFiles.d.ts +11 -0
- package/dist/sdk/terminal/tui/clipboardFiles.js +74 -0
- package/dist/sdk/terminal/tui/commandPages.d.ts +11 -0
- package/dist/sdk/terminal/tui/commandPages.js +111 -0
- package/dist/sdk/terminal/tui/commands.d.ts +46 -0
- package/dist/sdk/terminal/tui/commands.js +399 -0
- package/dist/sdk/terminal/tui/dialogGeometry.d.ts +27 -0
- package/dist/sdk/terminal/tui/dialogGeometry.js +52 -0
- package/dist/sdk/terminal/tui/dialogs.d.ts +80 -0
- package/dist/sdk/terminal/tui/dialogs.js +370 -0
- package/dist/sdk/terminal/tui/keybindings.d.ts +11 -0
- package/dist/sdk/terminal/tui/keybindings.js +49 -0
- package/dist/sdk/terminal/tui/list.d.ts +73 -0
- package/dist/sdk/terminal/tui/list.js +196 -0
- package/dist/sdk/terminal/tui/modeChoices.d.ts +42 -0
- package/dist/sdk/terminal/tui/modeChoices.js +70 -0
- package/dist/sdk/terminal/tui/modelPicker.d.ts +55 -0
- package/dist/sdk/terminal/tui/modelPicker.js +150 -0
- package/dist/sdk/terminal/tui/mouse.d.ts +3 -0
- package/dist/sdk/terminal/tui/mouse.js +3 -0
- package/dist/sdk/terminal/tui/page.d.ts +17 -0
- package/dist/sdk/terminal/tui/page.js +1 -0
- package/dist/sdk/terminal/tui/pageOverlay.d.ts +27 -0
- package/dist/sdk/terminal/tui/pageOverlay.js +156 -0
- package/dist/sdk/terminal/tui/pages/accountsPage.d.ts +76 -0
- package/dist/sdk/terminal/tui/pages/accountsPage.js +409 -0
- package/dist/sdk/terminal/tui/pages/agentsPage.d.ts +74 -0
- package/dist/sdk/terminal/tui/pages/agentsPage.js +190 -0
- package/dist/sdk/terminal/tui/pages/annotatePage.d.ts +94 -0
- package/dist/sdk/terminal/tui/pages/annotatePage.js +341 -0
- package/dist/sdk/terminal/tui/pages/browserPage.d.ts +87 -0
- package/dist/sdk/terminal/tui/pages/browserPage.js +738 -0
- package/dist/sdk/terminal/tui/pages/componentsPage.d.ts +47 -0
- package/dist/sdk/terminal/tui/pages/componentsPage.js +119 -0
- package/dist/sdk/terminal/tui/pages/doctorPage.d.ts +39 -0
- package/dist/sdk/terminal/tui/pages/doctorPage.js +233 -0
- package/dist/sdk/terminal/tui/pages/hubPage.d.ts +39 -0
- package/dist/sdk/terminal/tui/pages/hubPage.js +128 -0
- package/dist/sdk/terminal/tui/pages/logPage.d.ts +38 -0
- package/dist/sdk/terminal/tui/pages/logPage.js +189 -0
- package/dist/sdk/terminal/tui/pages/notesPage.d.ts +75 -0
- package/dist/sdk/terminal/tui/pages/notesPage.js +201 -0
- package/dist/sdk/terminal/tui/pages/permissionsPage.d.ts +44 -0
- package/dist/sdk/terminal/tui/pages/permissionsPage.js +124 -0
- package/dist/sdk/terminal/tui/pages/pluginsPage.d.ts +57 -0
- package/dist/sdk/terminal/tui/pages/pluginsPage.js +243 -0
- package/dist/sdk/terminal/tui/pages/settingsPage.d.ts +63 -0
- package/dist/sdk/terminal/tui/pages/settingsPage.js +103 -0
- package/dist/sdk/terminal/tui/pages/subagentsPage.d.ts +23 -0
- package/dist/sdk/terminal/tui/pages/subagentsPage.js +70 -0
- package/dist/sdk/terminal/tui/pages/trajectoryPage.d.ts +65 -0
- package/dist/sdk/terminal/tui/pages/trajectoryPage.js +450 -0
- package/dist/sdk/terminal/tui/pages/worktreesPage.d.ts +72 -0
- package/dist/sdk/terminal/tui/pages/worktreesPage.js +203 -0
- package/dist/sdk/terminal/tui/piAdapter.d.ts +18 -0
- package/dist/sdk/terminal/tui/piAdapter.js +48 -0
- package/dist/sdk/terminal/tui/planMode.d.ts +2 -0
- package/dist/sdk/terminal/tui/planMode.js +2 -0
- package/dist/sdk/terminal/tui/pluginCommands.d.ts +14 -0
- package/dist/sdk/terminal/tui/pluginCommands.js +27 -0
- package/dist/sdk/terminal/tui/questionPicker.d.ts +20 -0
- package/dist/sdk/terminal/tui/questionPicker.js +150 -0
- package/dist/sdk/terminal/tui/questions.d.ts +21 -0
- package/dist/sdk/terminal/tui/questions.js +42 -0
- package/dist/sdk/terminal/tui/runtime.d.ts +114 -0
- package/dist/sdk/terminal/tui/runtime.js +443 -0
- package/dist/sdk/terminal/tui/search.d.ts +22 -0
- package/dist/sdk/terminal/tui/search.js +60 -0
- package/dist/sdk/terminal/tui/selection.d.ts +16 -0
- package/dist/sdk/terminal/tui/selection.js +16 -0
- package/dist/sdk/terminal/tui/sessionUi.d.ts +3 -0
- package/dist/sdk/terminal/tui/sessionUi.js +30 -0
- package/dist/sdk/terminal/tui/settingsModel.d.ts +14 -0
- package/dist/sdk/terminal/tui/settingsModel.js +114 -0
- package/dist/sdk/terminal/tui/sideQuestion.d.ts +53 -0
- package/dist/sdk/terminal/tui/sideQuestion.js +230 -0
- package/dist/sdk/terminal/tui/skillInvocation.d.ts +9 -0
- package/dist/sdk/terminal/tui/skillInvocation.js +43 -0
- package/dist/sdk/terminal/tui/status.d.ts +18 -0
- package/dist/sdk/terminal/tui/status.js +67 -0
- package/dist/sdk/terminal/tui/theme.d.ts +45 -0
- package/dist/sdk/terminal/tui/theme.js +176 -0
- package/dist/sdk/terminal/tui/treeModel.d.ts +79 -0
- package/dist/sdk/terminal/tui/treeModel.js +483 -0
- package/dist/sdk/terminal/tui/treePicker.d.ts +49 -0
- package/dist/sdk/terminal/tui/treePicker.js +251 -0
- package/dist/sdk/terminal/tui/ui.d.ts +49 -0
- package/dist/sdk/terminal/tui/ui.js +149 -0
- package/dist/sdk/terminal/tui/workingStatus.d.ts +9 -0
- package/dist/sdk/terminal/tui/workingStatus.js +229 -0
- package/dist/sdk/tools/askUser.d.ts +6 -0
- package/dist/sdk/tools/askUser.js +92 -0
- package/dist/sdk/tools/checklist.d.ts +9 -0
- package/dist/sdk/tools/checklist.js +54 -0
- package/dist/sdk/tools/definitions.d.ts +30 -0
- package/dist/sdk/tools/definitions.js +117 -0
- package/dist/sdk/tools/dispatch.d.ts +16 -0
- package/dist/sdk/tools/dispatch.js +67 -0
- package/dist/sdk/tools/harnessTools.d.ts +8 -0
- package/dist/sdk/tools/harnessTools.js +20 -0
- package/dist/sdk/tools/sessionName.d.ts +7 -0
- package/dist/sdk/tools/sessionName.js +31 -0
- package/dist/sdk/tools/spawnSubagent.d.ts +4 -0
- package/dist/sdk/tools/spawnSubagent.js +58 -0
- package/dist/sdk/tools/types.d.ts +48 -0
- package/dist/sdk/tools/types.js +1 -0
- package/dist/sdk/variant/components.d.ts +34 -0
- package/dist/sdk/variant/components.js +230 -0
- package/dist/sdk/variant/materialise.d.ts +66 -0
- package/dist/sdk/variant/materialise.js +81 -0
- package/dist/sdk/variant/migrate.d.ts +4 -0
- package/dist/sdk/variant/migrate.js +41 -0
- package/dist/sdk/variant/seed.d.ts +20 -0
- package/dist/sdk/variant/seed.js +116 -0
- package/dist/sdk/variant/store.d.ts +82 -0
- package/dist/sdk/variant/store.js +151 -0
- package/dist/sdk/variant/surface.d.ts +56 -0
- package/dist/sdk/variant/surface.js +81 -0
- package/dist/sdk/variant/trust.d.ts +27 -0
- package/dist/sdk/variant/trust.js +64 -0
- package/dist/sdk/variant/variant.d.ts +71 -0
- package/dist/sdk/variant/variant.js +331 -0
- package/dist/sdk/web/markdown.d.ts +10 -0
- package/dist/sdk/web/markdown.js +66 -0
- package/dist/sdk/web/part.d.ts +10 -0
- package/dist/sdk/web/part.js +6 -0
- package/dist/sdk/web/safeRequest.d.ts +34 -0
- package/dist/sdk/web/safeRequest.js +175 -0
- package/dist/sdk/web/search.d.ts +53 -0
- package/dist/sdk/web/search.js +168 -0
- package/dist/sdk/web/serverMethods.d.ts +3 -0
- package/dist/sdk/web/serverMethods.js +7 -0
- package/dist/sdk/web/text.d.ts +2 -0
- package/dist/sdk/web/text.js +7 -0
- package/dist/sdk/web/tools.d.ts +22 -0
- package/dist/sdk/web/tools.js +195 -0
- package/dist/sdk/web/turndown-plugin-gfm.d.ts +4 -0
- package/dist/sdk/wiki/notes.d.ts +68 -0
- package/dist/sdk/wiki/notes.js +297 -0
- package/dist/sdk/wiki/serverMethods.d.ts +3 -0
- package/dist/sdk/wiki/serverMethods.js +26 -0
- package/dist/sdk/worktrees/cli.d.ts +11 -0
- package/dist/sdk/worktrees/cli.js +146 -0
- package/dist/sdk/worktrees/copy.d.ts +9 -0
- package/dist/sdk/worktrees/copy.js +111 -0
- package/dist/sdk/worktrees/git.d.ts +16 -0
- package/dist/sdk/worktrees/git.js +81 -0
- package/dist/sdk/worktrees/serverMethods.d.ts +3 -0
- package/dist/sdk/worktrees/serverMethods.js +30 -0
- package/dist/sdk/worktrees/service.d.ts +73 -0
- package/dist/sdk/worktrees/service.js +483 -0
- package/dist/sdk/worktrees/setup.d.ts +23 -0
- package/dist/sdk/worktrees/setup.js +65 -0
- package/dist/sdk/worktrees/types.d.ts +91 -0
- package/dist/sdk/worktrees/types.js +1 -0
- package/dist/sdk/world/actions.d.ts +23 -0
- package/dist/sdk/world/actions.js +31 -0
- package/dist/sdk/world/cli.d.ts +12 -0
- package/dist/sdk/world/cli.js +166 -0
- package/dist/sdk/world/images.d.ts +20 -0
- package/dist/sdk/world/images.js +48 -0
- package/dist/sdk/world/untrusted.d.ts +12 -0
- package/dist/sdk/world/untrusted.js +20 -0
- package/dist/sdk/world/world.d.ts +67 -0
- package/dist/sdk/world/world.js +79 -0
- package/dist/terminal-opentui.js +20778 -0
- package/dist/terminal-pi.js +794 -518
- package/docs/README.md +42 -0
- package/docs/architecture/00-overview.md +171 -0
- package/docs/architecture/01-extension-points.md +78 -0
- package/docs/architecture/02-sessions-and-runs.md +203 -0
- package/docs/architecture/03-variants.md +103 -0
- package/docs/architecture/04-prompt.md +122 -0
- package/docs/architecture/05-refinement.md +107 -0
- package/docs/architecture/06-plugins-and-capabilities.md +129 -0
- package/docs/architecture/07-tools-and-gate.md +103 -0
- package/docs/architecture/08-memory-and-history.md +94 -0
- package/docs/architecture/09-accounts-and-connectors.md +98 -0
- package/docs/architecture/10-server-protocol.md +193 -0
- package/docs/architecture/11-terminal.md +261 -0
- package/docs/architecture/12-storage.md +75 -0
- package/docs/architecture/13-world-tools.md +45 -0
- package/docs/architecture/14-surfaces-and-parity.md +89 -0
- package/docs/architecture/README.md +125 -0
- package/docs/architecture/proposals/PROP-0001-reporting-section.md +106 -0
- package/docs/architecture/proposals/PROP-0002-retain-rollout-workspaces.md +104 -0
- package/docs/architecture/proposals/PROP-0003-executor-settings.md +81 -0
- package/docs/architecture/proposals/PROP-0004-flexible-reporting-guidance.md +71 -0
- package/docs/architecture/proposals/PROP-0005-xharness-cli-name.md +78 -0
- package/docs/architecture/proposals/PROP-0006-run-checklist.md +70 -0
- package/docs/architecture/proposals/PROP-0007-run-continuation.md +80 -0
- package/docs/architecture/proposals/PROP-0008-lessons-from-runs.md +80 -0
- package/docs/architecture/proposals/PROP-0009-foundation-and-variants.md +78 -0
- package/docs/architecture/proposals/PROP-0010-session-names.md +73 -0
- package/docs/architecture/proposals/PROP-0011-doctor.md +63 -0
- package/docs/architecture/proposals/PROP-0012-release-baseline.md +56 -0
- package/docs/architecture/proposals/PROP-0013-resource-browser.md +58 -0
- package/docs/architecture/proposals/PROP-0014-fullscreen-browser-tabs.md +58 -0
- package/docs/architecture/proposals/PROP-0015-one-capability-surface.md +88 -0
- package/docs/architecture/proposals/PROP-0016-managed-worktrees.md +156 -0
- package/docs/architecture/proposals/PROP-0017-page-annotations.md +127 -0
- package/docs/architecture/proposals/PROP-0018-annotation-queue-and-app-targets.md +179 -0
- package/docs/architecture/proposals/PROP-0019-contextual-side-questions.md +122 -0
- package/docs/architecture/proposals/PROP-0020-builtin-feature-plugins.md +105 -0
- package/docs/architecture/proposals/PROP-0021-command-namespaces-and-duplicates.md +99 -0
- package/docs/architecture/proposals/PROP-0022-plan-only-questions.md +102 -0
- package/docs/architecture/proposals/PROP-0023-xagent-cli-name.md +61 -0
- package/docs/architecture/proposals/PROP-0024-question-sketch-previews.md +130 -0
- package/docs/architecture/proposals/PROP-0025-contextual-question-wireframes.md +49 -0
- package/docs/architecture/proposals/PROP-0026-connected-sketch-display.md +94 -0
- package/docs/architecture/proposals/PROP-0027-xingular-agent-product-identity.md +60 -0
- package/docs/architecture/proposals/PROP-0028-normalize-question-wireframes.md +55 -0
- package/docs/architecture/proposals/PROP-0029-agent-profiles.md +124 -0
- package/docs/architecture/proposals/PROP-0030-subagent-title.md +86 -0
- package/docs/architecture/proposals/README.md +101 -0
- package/docs/decisions/ADR-0002-native-subagent-lifecycle.md +49 -0
- package/docs/decisions/ADR-0003-shared-asynchronous-subagents.md +70 -0
- package/docs/decisions/ADR-0004-fullscreen-terminal-layout.md +50 -0
- package/docs/decisions/ADR-0005-app-provided-oauth-clients.md +54 -0
- package/docs/decisions/ADR-0006-opentui-only-terminal.md +47 -0
- package/docs/decisions/ADR-0007-reporting-section.md +33 -0
- package/docs/decisions/ADR-0008-flexible-reporting-guidance.md +38 -0
- package/docs/decisions/ADR-0009-xharness-command.md +39 -0
- package/docs/decisions/ADR-0010-lessons-in-the-wiki.md +31 -0
- package/docs/decisions/ADR-0011-foundation-and-variants.md +28 -0
- package/docs/decisions/ADR-0012-native-session-names.md +34 -0
- package/docs/decisions/ADR-0013-doctor.md +27 -0
- package/docs/decisions/ADR-0014-public-release-baseline.md +22 -0
- package/docs/decisions/ADR-0015-resource-browser.md +28 -0
- package/docs/decisions/ADR-0016-fullscreen-browser-tabs.md +31 -0
- package/docs/decisions/ADR-0017-one-capability-surface.md +34 -0
- package/docs/decisions/ADR-0018-builtin-feature-plugins.md +35 -0
- package/docs/decisions/ADR-0019-managed-git-worktrees.md +31 -0
- package/docs/decisions/ADR-0020-page-annotations.md +37 -0
- package/docs/decisions/ADR-0021-required-command-namespaces.md +40 -0
- package/docs/decisions/ADR-0022-plan-only-question-tools.md +34 -0
- package/docs/decisions/ADR-0023-contextual-side-question-runs.md +35 -0
- package/docs/decisions/ADR-0024-xagent-command.md +40 -0
- package/docs/decisions/ADR-0025-question-choice-sketches.md +49 -0
- package/docs/decisions/ADR-0026-contextual-question-wireframes.md +58 -0
- package/docs/decisions/ADR-0027-connected-sketch-display.md +60 -0
- package/docs/decisions/ADR-0028-xingular-agent-product-identity.md +56 -0
- package/docs/decisions/ADR-0029-normalized-question-wireframe-borders.md +33 -0
- package/docs/decisions/ADR-0030-agent-profiles.md +43 -0
- package/docs/doctor.md +80 -0
- package/docs/experiments/EXP-0001-terminal-input-latency/plan.md +81 -0
- package/docs/experiments/EXP-0001-terminal-input-latency/results.md +46 -0
- package/docs/experiments/EXP-0002-opentui-typing-latency/plan.md +70 -0
- package/docs/experiments/EXP-0002-opentui-typing-latency/results.md +92 -0
- package/docs/features/README.md +46 -0
- package/docs/features/automations/README.md +41 -0
- package/docs/features/cores/README.md +39 -0
- package/docs/features/google-harness2/README.md +52 -0
- package/docs/features/integrations/README.md +40 -0
- package/docs/features/interfaces/README.md +29 -0
- package/docs/features/memory/README.md +28 -0
- package/docs/future-work.md +48 -0
- package/docs/parity.md +78 -0
- package/docs/releases/1.0.0.md +40 -0
- package/docs/releases/4.0.0.md +46 -0
- package/docs/releases/README.md +41 -0
- package/docs/study/00-index.md +83 -0
- package/docs/study/arms/00-matrix.md +20 -0
- package/docs/study/arms/01-system-prompt.md +211 -0
- package/docs/study/arms/02-tools.md +79 -0
- package/docs/study/arms/03-subagents.md +90 -0
- package/docs/study/arms/04-skills.md +75 -0
- package/docs/study/arms/05-context-management.md +90 -0
- package/docs/study/arms/06-memory.md +90 -0
- package/docs/study/arms/07-governance.md +71 -0
- package/docs/study/arms/08-execution.md +69 -0
- package/docs/study/arms/09-observability.md +60 -0
- package/docs/study/arms/10-refinement.md +110 -0
- package/docs/study/autonomous-engineering-sources.md +277 -0
- package/docs/study/autonomy-sources.md +147 -0
- package/docs/study/btw-comparison.md +37 -0
- package/docs/study/feature-gap-review.md +42 -0
- package/docs/study/insights.md +123 -0
- package/docs/study/proactive-autonomy.md +408 -0
- package/docs/study/roadmap.md +72 -0
- package/docs/study/sources/claude-code.md +44 -0
- package/docs/study/sources/deepseek-harness.md +102 -0
- package/docs/study/sources/harness2.md +50 -0
- package/docs/study/sources/kimi-cli.md +42 -0
- package/docs/study/sources/omp.md +93 -0
- package/docs/study/sources/opencode.md +43 -0
- package/docs/study/sources/openhands.md +46 -0
- package/docs/study/sources/smolagents.md +40 -0
- package/docs/study/sources/swe-agent.md +34 -0
- package/docs/study/tui-resource-browser.md +78 -0
- package/docs/system-prompt-design.md +196 -0
- package/docs/terminal-tui.md +707 -58
- package/package.json +43 -13
- package/docs/evidence/terminal-2026-10-17/120x40-completed-transcript.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17/40x20-settings-interaction.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17/40x20-settings-keyboard.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17/40x20-welcome.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17/80x24-approval-0.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17/80x24-question.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17/verification.json +0 -130
- package/docs/evidence/terminal-2026-10-17-followup/120x40-completed-transcript.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/40x20-settings-interaction.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/40x20-settings-keyboard.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/40x20-welcome.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/80x24-approval-0.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/80x24-plugin-light.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/80x24-question-batch.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/80x24-question.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-approval-0.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-plugin-light.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-question-batch.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-question.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/app-bundle/verification.json +0 -95
- package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-approval-0.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-plugin-light.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-question-batch.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-question.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/global-install/README.md +0 -27
- package/docs/evidence/terminal-2026-10-17-followup/global-install/shell-command-80x24.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/global-install/shell-command.json +0 -18
- package/docs/evidence/terminal-2026-10-17-followup/global-install/verification.json +0 -95
- package/docs/evidence/terminal-2026-10-17-followup/harness-reference-80x24.json.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/harness-reference-final-80x24.json.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/harness-reference-scenario.json +0 -60
- package/docs/evidence/terminal-2026-10-17-followup/live-codex/README.md +0 -24
- package/docs/evidence/terminal-2026-10-17-followup/live-codex/complete-80x24.ansi.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/live-codex/verification.json +0 -57
- package/docs/evidence/terminal-2026-10-17-followup/omp-reference-80x24-early.json.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/omp-reference-80x24.json.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/omp-reference-scenario.json +0 -58
- package/docs/evidence/terminal-2026-10-17-followup/omp-supplemental-static.json.gz +0 -0
- package/docs/evidence/terminal-2026-10-17-followup/rea-artifacts.json +0 -320
- package/docs/evidence/terminal-2026-10-17-followup/reference-comparison.json +0 -30
- package/docs/evidence/terminal-2026-10-17-followup/reference-comparison.md +0 -133
- package/docs/evidence/terminal-2026-10-17-followup/reference-source-observations.json +0 -20
- package/docs/evidence/terminal-2026-10-17-followup/verification.json +0 -207
- package/src/accounts/accounts.test.ts +0 -333
- package/src/accounts/accounts.ts +0 -658
- package/src/accounts/env.test.ts +0 -95
- package/src/accounts/env.ts +0 -338
- package/src/accounts/secrets.ts +0 -50
- package/src/accounts/store.ts +0 -338
- package/src/capabilities/api.ts +0 -75
- package/src/capabilities/runSnapshot.ts +0 -59
- package/src/capabilities/types.ts +0 -34
- package/src/cli.ts +0 -118
- package/src/core/bus.ts +0 -34
- package/src/core/changes.ts +0 -33
- package/src/core/env.ts +0 -27
- package/src/core/errors.ts +0 -32
- package/src/core/frontmatter.ts +0 -47
- package/src/core/fs.test.ts +0 -38
- package/src/core/fs.ts +0 -92
- package/src/core/index.ts +0 -193
- package/src/core/path.test.ts +0 -14
- package/src/core/path.ts +0 -79
- package/src/core/projects.ts +0 -90
- package/src/core/text.ts +0 -39
- package/src/harness.ts +0 -312
- package/src/hub/catalog.json +0 -123
- package/src/hub/cli.ts +0 -59
- package/src/hub/hub.test.ts +0 -205
- package/src/hub/hub.ts +0 -256
- package/src/hub/schema.ts +0 -81
- package/src/index.ts +0 -75
- package/src/mcp/connections.ts +0 -614
- package/src/mcp/manager.ts +0 -130
- package/src/mcp/oauth.ts +0 -195
- package/src/mcp/scopeMigration.test.ts +0 -79
- package/src/mcp/scopeMigration.ts +0 -204
- package/src/mcp/service.test.ts +0 -376
- package/src/mcp/service.ts +0 -549
- package/src/mcp/types.ts +0 -108
- package/src/memory/api.test.ts +0 -82
- package/src/memory/api.ts +0 -303
- package/src/memory/blocks.test.ts +0 -78
- package/src/memory/blocks.ts +0 -408
- package/src/memory/caller.ts +0 -69
- package/src/memory/curation.test.ts +0 -163
- package/src/memory/curation.ts +0 -64
- package/src/memory/dispatch.ts +0 -59
- package/src/memory/facts.test.ts +0 -41
- package/src/memory/facts.ts +0 -248
- package/src/memory/graph.ts +0 -103
- package/src/memory/health.test.ts +0 -130
- package/src/memory/health.ts +0 -74
- package/src/memory/maintainer.ts +0 -272
- package/src/memory/maintenance.test.ts +0 -176
- package/src/memory/maintenance.ts +0 -518
- package/src/memory/migrate.ts +0 -79
- package/src/memory/operations.ts +0 -150
- package/src/memory/proposals.test.ts +0 -168
- package/src/memory/proposals.ts +0 -584
- package/src/memory/recall.test.ts +0 -115
- package/src/memory/recall.ts +0 -278
- package/src/memory/references.ts +0 -77
- package/src/memory/runContext.ts +0 -93
- package/src/memory/secrets.ts +0 -6
- package/src/memory/store.test.ts +0 -66
- package/src/memory/store.ts +0 -385
- package/src/memory/wiki.test.ts +0 -47
- package/src/memory/wiki.ts +0 -422
- package/src/memory/wikiIndex.test.ts +0 -88
- package/src/memory/wikiIndex.ts +0 -116
- package/src/plugins/api.ts +0 -181
- package/src/plugins/attachments.test.ts +0 -84
- package/src/plugins/attachments.ts +0 -141
- package/src/plugins/builtin.ts +0 -82
- package/src/plugins/catalogue.test.ts +0 -254
- package/src/plugins/catalogue.ts +0 -251
- package/src/plugins/cli.ts +0 -184
- package/src/plugins/discover.ts +0 -151
- package/src/plugins/firstParty.test.ts +0 -143
- package/src/plugins/firstParty.ts +0 -129
- package/src/plugins/hooks.test.ts +0 -250
- package/src/plugins/hooks.ts +0 -239
- package/src/plugins/identity.ts +0 -37
- package/src/plugins/install.test.ts +0 -107
- package/src/plugins/install.ts +0 -106
- package/src/plugins/inventory.ts +0 -123
- package/src/plugins/manifest.ts +0 -76
- package/src/plugins/plugins.test.ts +0 -205
- package/src/plugins/plugins.ts +0 -189
- package/src/plugins/proposal.ts +0 -121
- package/src/plugins/runtime.test.ts +0 -40
- package/src/plugins/runtime.ts +0 -82
- package/src/plugins/trust.ts +0 -142
- package/src/plugins/types.ts +0 -149
- package/src/prompt/compile.test.ts +0 -261
- package/src/prompt/compile.ts +0 -732
- package/src/server/methods.ts +0 -349
- package/src/server/remote.ts +0 -77
- package/src/server/rpc.ts +0 -116
- package/src/server/serve.ts +0 -28
- package/src/server/server.test.ts +0 -174
- package/src/sessions/approvals.ts +0 -118
- package/src/sessions/contracts.ts +0 -336
- package/src/sessions/conversation.test.ts +0 -177
- package/src/sessions/extensionSession.test.ts +0 -74
- package/src/sessions/extensionUi.test.ts +0 -65
- package/src/sessions/extensionUi.ts +0 -102
- package/src/sessions/history.ts +0 -51
- package/src/sessions/lineageJoin.ts +0 -75
- package/src/sessions/policy.ts +0 -36
- package/src/sessions/pricing.ts +0 -60
- package/src/sessions/questionBatches.test.ts +0 -110
- package/src/sessions/reasoningSummaries.ts +0 -59
- package/src/sessions/registry.ts +0 -381
- package/src/sessions/runIndex.ts +0 -99
- package/src/sessions/runStore.test.ts +0 -152
- package/src/sessions/runStore.ts +0 -332
- package/src/sessions/runner.ts +0 -604
- package/src/sessions/runtimeResources.test.ts +0 -61
- package/src/sessions/sessions.test.ts +0 -549
- package/src/sessions/sessions.ts +0 -339
- package/src/skills/registry.test.ts +0 -104
- package/src/skills/registry.ts +0 -413
- package/src/terminal/accountsMenu.test.ts +0 -225
- package/src/terminal/accountsMenu.ts +0 -382
- package/src/terminal/cli.ts +0 -149
- package/src/terminal/client.ts +0 -74
- package/src/terminal/control.test.ts +0 -23
- package/src/terminal/control.ts +0 -23
- package/src/terminal/controller.ts +0 -291
- package/src/terminal/hubMenu.ts +0 -24
- package/src/terminal/launch.test.ts +0 -25
- package/src/terminal/launch.ts +0 -48
- package/src/terminal/piExtension.lifecycle.test.ts +0 -55
- package/src/terminal/piExtension.ts +0 -259
- package/src/terminal/pluginControl.test.ts +0 -146
- package/src/terminal/pluginMenu.ts +0 -112
- package/src/terminal/socket.test.ts +0 -71
- package/src/terminal/socket.ts +0 -232
- package/src/terminal/standalone.test.ts +0 -167
- package/src/terminal/standalone.ts +0 -153
- package/src/terminal/terminal.test.ts +0 -399
- package/src/terminal/terminals.ts +0 -553
- package/src/terminal/tui/application.test.ts +0 -114
- package/src/terminal/tui/application.ts +0 -491
- package/src/terminal/tui/commands.test.ts +0 -218
- package/src/terminal/tui/commands.ts +0 -361
- package/src/terminal/tui/dialogs.ts +0 -301
- package/src/terminal/tui/editor.test.ts +0 -84
- package/src/terminal/tui/editor.ts +0 -79
- package/src/terminal/tui/keybindings.test.ts +0 -22
- package/src/terminal/tui/keybindings.ts +0 -50
- package/src/terminal/tui/piAdapter.ts +0 -62
- package/src/terminal/tui/presentation.test.ts +0 -79
- package/src/terminal/tui/questions.test.ts +0 -41
- package/src/terminal/tui/questions.ts +0 -47
- package/src/terminal/tui/runtime.socket.test.ts +0 -104
- package/src/terminal/tui/runtime.test.ts +0 -215
- package/src/terminal/tui/runtime.ts +0 -388
- package/src/terminal/tui/sessionUi.ts +0 -24
- package/src/terminal/tui/settings.test.ts +0 -150
- package/src/terminal/tui/settings.ts +0 -188
- package/src/terminal/tui/status.test.ts +0 -70
- package/src/terminal/tui/status.ts +0 -109
- package/src/terminal/tui/theme.ts +0 -174
- package/src/terminal/tui/tools.test.ts +0 -145
- package/src/terminal/tui/tools.ts +0 -142
- package/src/terminal/tui/transcript.test.ts +0 -25
- package/src/terminal/tui/transcript.ts +0 -124
- package/src/terminal/tui/ui.test.ts +0 -313
- package/src/terminal/tui/ui.ts +0 -166
- package/src/terminal/tui/welcome.ts +0 -102
- package/src/tools/askUser.test.ts +0 -69
- package/src/tools/askUser.ts +0 -59
- package/src/tools/definitions.ts +0 -187
- package/src/tools/maintenance.ts +0 -24
- package/src/tools/memoryTools.ts +0 -22
- package/src/tools/pluginPropose.ts +0 -41
- package/src/tools/registryWrite.test.ts +0 -101
- package/src/tools/registryWrite.ts +0 -182
- package/src/tools/spawnSubagent.ts +0 -92
- package/src/tools/types.ts +0 -39
- package/src/web/safeRequest.ts +0 -171
- package/src/web/text.ts +0 -53
- package/src/web/tools.ts +0 -134
- package/src/web/web.test.ts +0 -141
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
// The Wiki: plain Markdown notes about projects, linked to each other. It is reference material
|
|
2
|
+
// a person and agents read and write; it is not what shapes an agent (that is the variant).
|
|
3
|
+
//
|
|
4
|
+
// <data>/wiki/home.md
|
|
5
|
+
// <data>/wiki/library/**.md notes that belong to no project
|
|
6
|
+
// <data>/wiki/projects/<slug>/**.md a project's notes
|
|
7
|
+
// <data>/wiki-history/<path>/<time>.md earlier versions, one file per save
|
|
8
|
+
//
|
|
9
|
+
// A note's path is its file path without `.md`. Links are `[[path]]`, `[[path|label]]`, or a
|
|
10
|
+
// Markdown link to a relative `.md` file.
|
|
11
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync } from 'node:fs';
|
|
12
|
+
import { dirname, join, relative, sep } from 'node:path';
|
|
13
|
+
import { noteChange } from "../core/changes.js";
|
|
14
|
+
import { HarnessError, invalid, notFound } from "../core/errors.js";
|
|
15
|
+
import * as frontmatter from "../core/frontmatter.js";
|
|
16
|
+
import { atomicWrite, now } from "../core/fs.js";
|
|
17
|
+
import { projectsOrNone } from "../core/projects.js";
|
|
18
|
+
import { looksSecret } from "../core/secrets.js";
|
|
19
|
+
/** Folders an earlier Wiki kept beside its pages. They are moved aside, never read as notes. */
|
|
20
|
+
export const LEGACY_FOLDERS = ['blocks', 'facts', 'raw', 'revisions', 'inbox', 'operations', 'trash'];
|
|
21
|
+
const MAX_NOTE = 400_000;
|
|
22
|
+
export function wikiDir(root) {
|
|
23
|
+
return join(root, 'wiki');
|
|
24
|
+
}
|
|
25
|
+
function historyDir(root) {
|
|
26
|
+
return join(root, 'wiki-history');
|
|
27
|
+
}
|
|
28
|
+
/** Accepts a note path such as `projects/app/decisions` or `library/glossary`. */
|
|
29
|
+
export function cleanPath(path) {
|
|
30
|
+
const clean = String(path ?? '').trim().replace(/\\/g, '/').replace(/^\/+|\/+$/g, '').replace(/\.md$/i, '');
|
|
31
|
+
const parts = clean.split('/');
|
|
32
|
+
if (!clean || parts.some((part) => !part || part === '.' || part === '..' || part.startsWith('.')))
|
|
33
|
+
throw invalid('A note path is a relative path such as projects/<slug>/<name>.');
|
|
34
|
+
if (parts.length === 1 && clean !== 'home')
|
|
35
|
+
throw invalid('A note lives under library/ or projects/<slug>/.');
|
|
36
|
+
if (parts.length > 1 && parts[0] !== 'library' && parts[0] !== 'projects')
|
|
37
|
+
throw invalid('A note lives under library/ or projects/<slug>/.');
|
|
38
|
+
if (parts[0] === 'projects' && parts.length < 3)
|
|
39
|
+
throw invalid('A project note is projects/<slug>/<name>.');
|
|
40
|
+
if (LEGACY_FOLDERS.includes(parts[0]))
|
|
41
|
+
throw invalid('That folder is not part of the Wiki.');
|
|
42
|
+
return clean;
|
|
43
|
+
}
|
|
44
|
+
function fileOf(root, path) {
|
|
45
|
+
return join(wikiDir(root), `${cleanPath(path)}.md`);
|
|
46
|
+
}
|
|
47
|
+
function projectOfPath(path) {
|
|
48
|
+
const parts = path.split('/');
|
|
49
|
+
return parts[0] === 'projects' ? parts[1] ?? null : null;
|
|
50
|
+
}
|
|
51
|
+
function titleOf(path, text) {
|
|
52
|
+
const parsed = safeParse(text);
|
|
53
|
+
const declared = parsed.front?.title;
|
|
54
|
+
if (typeof declared === 'string' && declared.trim())
|
|
55
|
+
return declared.trim();
|
|
56
|
+
const heading = /^#\s+(.+)$/m.exec(parsed.body)?.[1]?.trim();
|
|
57
|
+
return heading || path.split('/').pop().replace(/[-_]/g, ' ');
|
|
58
|
+
}
|
|
59
|
+
function safeParse(text) {
|
|
60
|
+
try {
|
|
61
|
+
const parsed = frontmatter.parse(text);
|
|
62
|
+
return parsed ? { front: parsed.front, body: parsed.body } : { front: null, body: text };
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return { front: null, body: text };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function walk(dir, into) {
|
|
69
|
+
let names;
|
|
70
|
+
try {
|
|
71
|
+
names = readdirSync(dir);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
for (const name of names.sort()) {
|
|
77
|
+
if (name.startsWith('.'))
|
|
78
|
+
continue;
|
|
79
|
+
const path = join(dir, name);
|
|
80
|
+
let isDir = false;
|
|
81
|
+
try {
|
|
82
|
+
isDir = statSync(path).isDirectory();
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (isDir)
|
|
88
|
+
walk(path, into);
|
|
89
|
+
else if (name.endsWith('.md'))
|
|
90
|
+
into.push(path);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/** Every note path, Home first, then the Library, then projects. */
|
|
94
|
+
export function paths(root) {
|
|
95
|
+
const wiki = wikiDir(root);
|
|
96
|
+
const files = [];
|
|
97
|
+
if (existsSync(join(wiki, 'home.md')))
|
|
98
|
+
files.push(join(wiki, 'home.md'));
|
|
99
|
+
walk(join(wiki, 'library'), files);
|
|
100
|
+
walk(join(wiki, 'projects'), files);
|
|
101
|
+
return files.map((file) => relative(wiki, file).split(sep).join('/').replace(/\.md$/, ''));
|
|
102
|
+
}
|
|
103
|
+
function summary(root, path) {
|
|
104
|
+
const file = fileOf(root, path);
|
|
105
|
+
const text = readFileSync(file, 'utf8');
|
|
106
|
+
return { path, title: titleOf(path, text), project: projectOfPath(path), updatedAt: statSync(file).mtime.toISOString(), size: text.length };
|
|
107
|
+
}
|
|
108
|
+
export function list(root, options = {}) {
|
|
109
|
+
return paths(root)
|
|
110
|
+
.filter((path) => options.project === undefined || projectOfPath(path) === options.project)
|
|
111
|
+
.map((path) => summary(root, path));
|
|
112
|
+
}
|
|
113
|
+
const WIKI_LINK = /\[\[([^\]|#]+)(?:#[^\]|]*)?(?:\|[^\]]*)?\]\]/g;
|
|
114
|
+
const MD_LINK = /\[[^\]]*\]\(([^)\s]+\.md)(?:#[^)]*)?\)/g;
|
|
115
|
+
/** Resolves a link written in `from` to a note path, or null when it points nowhere known. */
|
|
116
|
+
export function resolveLink(target, from, known, titles) {
|
|
117
|
+
const raw = target.trim().replace(/\.md$/i, '');
|
|
118
|
+
if (!raw || /^[a-z]+:/i.test(raw))
|
|
119
|
+
return null;
|
|
120
|
+
const candidates = [raw.replace(/^\/+/, '')];
|
|
121
|
+
if (!raw.startsWith('/')) {
|
|
122
|
+
const base = from.split('/').slice(0, -1);
|
|
123
|
+
const parts = [...base];
|
|
124
|
+
for (const part of raw.split('/')) {
|
|
125
|
+
if (part === '..')
|
|
126
|
+
parts.pop();
|
|
127
|
+
else if (part && part !== '.')
|
|
128
|
+
parts.push(part);
|
|
129
|
+
}
|
|
130
|
+
candidates.unshift(parts.join('/'));
|
|
131
|
+
const project = projectOfPath(from);
|
|
132
|
+
if (project)
|
|
133
|
+
candidates.push(`projects/${project}/${raw}`);
|
|
134
|
+
candidates.push(`library/${raw}`);
|
|
135
|
+
}
|
|
136
|
+
for (const candidate of candidates)
|
|
137
|
+
if (known.has(candidate))
|
|
138
|
+
return candidate;
|
|
139
|
+
return titles.get(raw.toLowerCase()) ?? null;
|
|
140
|
+
}
|
|
141
|
+
function linksIn(body, from, known, titles) {
|
|
142
|
+
const out = new Set();
|
|
143
|
+
for (const match of body.matchAll(WIKI_LINK)) {
|
|
144
|
+
const found = resolveLink(match[1], from, known, titles);
|
|
145
|
+
if (found && found !== from)
|
|
146
|
+
out.add(found);
|
|
147
|
+
}
|
|
148
|
+
for (const match of body.matchAll(MD_LINK)) {
|
|
149
|
+
const found = resolveLink(match[1], from, known, titles);
|
|
150
|
+
if (found && found !== from)
|
|
151
|
+
out.add(found);
|
|
152
|
+
}
|
|
153
|
+
return [...out].sort();
|
|
154
|
+
}
|
|
155
|
+
/** Every note and every resolved link between notes. */
|
|
156
|
+
export function graph(root) {
|
|
157
|
+
const nodes = list(root);
|
|
158
|
+
const known = new Set(nodes.map((node) => node.path));
|
|
159
|
+
const titles = new Map(nodes.map((node) => [node.title.toLowerCase(), node.path]));
|
|
160
|
+
const edges = [];
|
|
161
|
+
for (const node of nodes) {
|
|
162
|
+
const body = readFileSync(fileOf(root, node.path), 'utf8');
|
|
163
|
+
for (const to of linksIn(body, node.path, known, titles))
|
|
164
|
+
edges.push({ from: node.path, to });
|
|
165
|
+
}
|
|
166
|
+
return { nodes, edges };
|
|
167
|
+
}
|
|
168
|
+
export function read(root, path) {
|
|
169
|
+
const clean = cleanPath(path);
|
|
170
|
+
const file = fileOf(root, clean);
|
|
171
|
+
if (!existsSync(file))
|
|
172
|
+
throw notFound(`The note ${clean}`);
|
|
173
|
+
const text = readFileSync(file, 'utf8');
|
|
174
|
+
const { nodes, edges } = graph(root);
|
|
175
|
+
const known = new Set(nodes.map((node) => node.path));
|
|
176
|
+
const titles = new Map(nodes.map((node) => [node.title.toLowerCase(), node.path]));
|
|
177
|
+
return {
|
|
178
|
+
...summary(root, clean),
|
|
179
|
+
body: text,
|
|
180
|
+
links: linksIn(text, clean, known, titles),
|
|
181
|
+
backlinks: edges.filter((edge) => edge.to === clean).map((edge) => edge.from).sort()
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
/** Writes a note, keeping the earlier text as a version. Returns the note as saved. */
|
|
185
|
+
export function write(root, path, body, options = {}) {
|
|
186
|
+
const clean = cleanPath(path);
|
|
187
|
+
if (typeof body !== 'string')
|
|
188
|
+
throw invalid('A note needs text.');
|
|
189
|
+
if (body.length > MAX_NOTE)
|
|
190
|
+
throw invalid(`A note may hold at most ${MAX_NOTE.toLocaleString('en-US')} characters.`);
|
|
191
|
+
if (looksSecret(body))
|
|
192
|
+
throw new HarnessError('secret_refused', 'That text looks like it contains a credential, so it was not saved.');
|
|
193
|
+
const project = projectOfPath(clean);
|
|
194
|
+
if (project && !projectsOrNone(root).some((known) => known.slug === project))
|
|
195
|
+
throw invalid(`There is no project with the slug ${project}.`);
|
|
196
|
+
const file = fileOf(root, clean);
|
|
197
|
+
if (existsSync(file)) {
|
|
198
|
+
const current = statSync(file).mtime.toISOString();
|
|
199
|
+
if (options.expectedUpdatedAt && options.expectedUpdatedAt !== current)
|
|
200
|
+
throw new HarnessError('conflict', 'The note changed since it was opened. Reload it and try again.');
|
|
201
|
+
const previous = readFileSync(file, 'utf8');
|
|
202
|
+
if (previous === body)
|
|
203
|
+
return read(root, clean);
|
|
204
|
+
atomicWrite(join(historyDir(root), clean, `${now().replace(/[:.]/g, '-')}.md`), previous);
|
|
205
|
+
}
|
|
206
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
207
|
+
atomicWrite(file, body);
|
|
208
|
+
noteChange({ wiki: wikiDir(root), id: clean, path: file, text: body, actor: options.actor ?? 'user', reason: options.reason ?? 'Saved' });
|
|
209
|
+
return read(root, clean);
|
|
210
|
+
}
|
|
211
|
+
/** Removes a note; its last text is kept as a version. */
|
|
212
|
+
export function remove(root, path) {
|
|
213
|
+
const clean = cleanPath(path);
|
|
214
|
+
const file = fileOf(root, clean);
|
|
215
|
+
if (!existsSync(file))
|
|
216
|
+
throw notFound(`The note ${clean}`);
|
|
217
|
+
atomicWrite(join(historyDir(root), clean, `${now().replace(/[:.]/g, '-')}.md`), readFileSync(file, 'utf8'));
|
|
218
|
+
rmSync(file);
|
|
219
|
+
}
|
|
220
|
+
export function versions(root, path) {
|
|
221
|
+
const dir = join(historyDir(root), cleanPath(path));
|
|
222
|
+
try {
|
|
223
|
+
return readdirSync(dir).filter((name) => name.endsWith('.md')).sort().reverse().map((name) => ({ id: name.replace(/\.md$/, ''), savedAt: statSync(join(dir, name)).mtime.toISOString() }));
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
return [];
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
export function version(root, path, id) {
|
|
230
|
+
if (!/^[0-9A-Za-z-]+$/.test(id))
|
|
231
|
+
throw invalid('Invalid version.');
|
|
232
|
+
const file = join(historyDir(root), cleanPath(path), `${id}.md`);
|
|
233
|
+
if (!existsSync(file))
|
|
234
|
+
throw notFound('That version');
|
|
235
|
+
return readFileSync(file, 'utf8');
|
|
236
|
+
}
|
|
237
|
+
/** Notes that contain the query's words, best first. The current project's notes rank higher. */
|
|
238
|
+
export function search(root, query, options = {}) {
|
|
239
|
+
const words = [...new Set(String(query ?? '').toLowerCase().split(/[^\p{L}\p{N}]+/u).filter((word) => word.length > 1))].slice(0, 16);
|
|
240
|
+
if (!words.length)
|
|
241
|
+
return [];
|
|
242
|
+
const hits = [];
|
|
243
|
+
for (const path of paths(root)) {
|
|
244
|
+
const text = readFileSync(fileOf(root, path), 'utf8');
|
|
245
|
+
const lower = text.toLowerCase();
|
|
246
|
+
const title = titleOf(path, text);
|
|
247
|
+
let score = 0;
|
|
248
|
+
for (const word of words) {
|
|
249
|
+
if (title.toLowerCase().includes(word))
|
|
250
|
+
score += 5;
|
|
251
|
+
if (path.toLowerCase().includes(word))
|
|
252
|
+
score += 2;
|
|
253
|
+
let at = lower.indexOf(word);
|
|
254
|
+
let count = 0;
|
|
255
|
+
while (at >= 0 && count < 20) {
|
|
256
|
+
count++;
|
|
257
|
+
at = lower.indexOf(word, at + word.length);
|
|
258
|
+
}
|
|
259
|
+
score += count;
|
|
260
|
+
}
|
|
261
|
+
if (!score)
|
|
262
|
+
continue;
|
|
263
|
+
const project = projectOfPath(path);
|
|
264
|
+
if (options.project && project === options.project)
|
|
265
|
+
score *= 1.5;
|
|
266
|
+
const first = Math.max(0, Math.min(...words.map((word) => lower.indexOf(word)).filter((at) => at >= 0)));
|
|
267
|
+
const excerpt = text.slice(Math.max(0, first - 80), first + 160).replace(/\s+/g, ' ').trim();
|
|
268
|
+
hits.push({ path, title, project, excerpt, score });
|
|
269
|
+
}
|
|
270
|
+
return hits.sort((a, b) => b.score - a.score || a.path.localeCompare(b.path)).slice(0, Math.min(Math.max(options.limit ?? 10, 1), 50));
|
|
271
|
+
}
|
|
272
|
+
/** Creates the Wiki's folders and Home note. Existing files are never replaced. */
|
|
273
|
+
export function ensureLayout(root, productName) {
|
|
274
|
+
const wiki = wikiDir(root);
|
|
275
|
+
mkdirSync(join(wiki, 'library'), { recursive: true });
|
|
276
|
+
mkdirSync(join(wiki, 'projects'), { recursive: true });
|
|
277
|
+
if (!existsSync(join(wiki, 'home.md')))
|
|
278
|
+
atomicWrite(join(wiki, 'home.md'), `# Home\n\nNotes about your projects for ${productName}. Link notes with [[library/name]] or [[projects/<slug>/name]].\n`);
|
|
279
|
+
for (const project of projectsOrNone(root))
|
|
280
|
+
mkdirSync(join(wiki, 'projects', project.slug), { recursive: true });
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Moves what an earlier Wiki kept beside its notes (memory blocks, facts, sources, revisions,
|
|
284
|
+
* the Inbox) to `<data>/legacy/wiki-<time>/`, once. Nothing is deleted. Returns where it went.
|
|
285
|
+
*/
|
|
286
|
+
export function moveLegacy(root) {
|
|
287
|
+
const wiki = wikiDir(root);
|
|
288
|
+
const found = LEGACY_FOLDERS.filter((name) => existsSync(join(wiki, name)));
|
|
289
|
+
const loose = ['index.md', 'log.md', 'schema.md'].filter((name) => existsSync(join(wiki, name)));
|
|
290
|
+
if (!found.length && !loose.length)
|
|
291
|
+
return null;
|
|
292
|
+
const dest = join(root, 'legacy', `wiki-${now().replace(/[:.]/g, '-')}`);
|
|
293
|
+
mkdirSync(dest, { recursive: true });
|
|
294
|
+
for (const name of [...found, ...loose])
|
|
295
|
+
renameSync(join(wiki, name), join(dest, name));
|
|
296
|
+
return dest;
|
|
297
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { optional, text } from "../server/params.js";
|
|
2
|
+
import * as notes from "./notes.js";
|
|
3
|
+
export function wikiServerMethods(harness) {
|
|
4
|
+
const root = () => harness.env.root;
|
|
5
|
+
return {
|
|
6
|
+
'wiki.list': (params) => notes.list(root(), params.project === undefined ? {} : { project: optional(params, 'project') }),
|
|
7
|
+
'wiki.read': (params) => notes.read(root(), text(params, 'path')),
|
|
8
|
+
'wiki.write': (params) => {
|
|
9
|
+
const note = notes.write(root(), text(params, 'path'), typeof params.text === 'string' ? params.text : '', { expectedUpdatedAt: optional(params, 'expectedUpdatedAt') });
|
|
10
|
+
harness.bus.emit({ type: 'wiki.changed' });
|
|
11
|
+
return note;
|
|
12
|
+
},
|
|
13
|
+
'wiki.remove': (params) => {
|
|
14
|
+
notes.remove(root(), text(params, 'path'));
|
|
15
|
+
harness.bus.emit({ type: 'wiki.changed' });
|
|
16
|
+
},
|
|
17
|
+
'wiki.search': (params) => notes.search(root(), typeof params.query === 'string' ? params.query : '', { project: optional(params, 'project'), limit: typeof params.limit === 'number' ? params.limit : undefined }),
|
|
18
|
+
'wiki.graph': () => notes.graph(root()),
|
|
19
|
+
'wiki.versions': (params) => notes.versions(root(), text(params, 'path')),
|
|
20
|
+
'wiki.version': (params) => notes.version(root(), text(params, 'path'), text(params, 'id')),
|
|
21
|
+
'wiki.ensureProject': () => {
|
|
22
|
+
notes.ensureLayout(root(), harness.env.productName);
|
|
23
|
+
harness.bus.emit({ type: 'wiki.changed' });
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Worktrees } from "./service.js";
|
|
2
|
+
import type { WorktreeRecord } from "./types.js";
|
|
3
|
+
export declare const WORKTREE_USAGE = "Usage: xagent worktree <command> [--state <dir>]\n\n list Worktrees of the repository you are in\n new [name] [--branch <b>] [--permanent] [--from <ref>] [--no-carry]\n Make a worktree (default: managed, detached, with your\n uncommitted changes carried over)\n status <name|id> Changes and commits since it started\n branch <name|id> <branch> Give a detached worktree a branch\n handoff <name|id> to-main|to-worktree [--copy]\n Move changes between it and your main checkout\n (--copy leaves the origin as it was)\n rm <name|id> [--force] Remove it; with --force, keep a snapshot of unsaved work\n restore <name|id> Bring back a removed worktree, with its snapshot\n prune [--keep <n>] Keep the most recent managed worktrees (default 15)\n adopt <path> Manage an existing linked worktree\n trust-setup Trust this repository's .xharness/worktree-setup as it is now\n path <name|id> Print its folder (cd \"$(xagent worktree path name)\")\n\nStart the terminal in a new managed worktree with: xagent --worktree [name]\n";
|
|
4
|
+
interface Dependencies {
|
|
5
|
+
home?: string;
|
|
6
|
+
cwd?: string;
|
|
7
|
+
write?: (text: string) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function findWorktree(worktrees: Worktrees, cwd: string, key: string, removed?: boolean): Promise<WorktreeRecord>;
|
|
10
|
+
export declare function runWorktreeCli(argv: string[], dependencies?: Dependencies): Promise<number>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// `xagent worktree`: managed worktrees of the repository you are in, from a shell.
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join, resolve } from 'node:path';
|
|
4
|
+
import { Worktrees } from "./service.js";
|
|
5
|
+
export const WORKTREE_USAGE = `Usage: xagent worktree <command> [--state <dir>]
|
|
6
|
+
|
|
7
|
+
list Worktrees of the repository you are in
|
|
8
|
+
new [name] [--branch <b>] [--permanent] [--from <ref>] [--no-carry]
|
|
9
|
+
Make a worktree (default: managed, detached, with your
|
|
10
|
+
uncommitted changes carried over)
|
|
11
|
+
status <name|id> Changes and commits since it started
|
|
12
|
+
branch <name|id> <branch> Give a detached worktree a branch
|
|
13
|
+
handoff <name|id> to-main|to-worktree [--copy]
|
|
14
|
+
Move changes between it and your main checkout
|
|
15
|
+
(--copy leaves the origin as it was)
|
|
16
|
+
rm <name|id> [--force] Remove it; with --force, keep a snapshot of unsaved work
|
|
17
|
+
restore <name|id> Bring back a removed worktree, with its snapshot
|
|
18
|
+
prune [--keep <n>] Keep the most recent managed worktrees (default 15)
|
|
19
|
+
adopt <path> Manage an existing linked worktree
|
|
20
|
+
trust-setup Trust this repository's .xharness/worktree-setup as it is now
|
|
21
|
+
path <name|id> Print its folder (cd "$(xagent worktree path name)")
|
|
22
|
+
|
|
23
|
+
Start the terminal in a new managed worktree with: xagent --worktree [name]
|
|
24
|
+
`;
|
|
25
|
+
function describe(record) {
|
|
26
|
+
const state = record.branch ?? 'detached';
|
|
27
|
+
const lease = record.lease ? ' · in use' : '';
|
|
28
|
+
return `${record.name.padEnd(20)} ${record.kind.padEnd(9)} ${state.padEnd(24)} ${record.path}${lease}`;
|
|
29
|
+
}
|
|
30
|
+
export async function findWorktree(worktrees, cwd, key, removed = false) {
|
|
31
|
+
const repo = await worktrees.repositoryOf(cwd);
|
|
32
|
+
const pool = removed ? worktrees.removed(repo) : await worktrees.list(repo);
|
|
33
|
+
const match = pool.find((record) => record.id === key || record.name === key);
|
|
34
|
+
if (!match)
|
|
35
|
+
throw new Error(`No ${removed ? 'removed ' : ''}worktree named ${key} in this repository.`);
|
|
36
|
+
return match;
|
|
37
|
+
}
|
|
38
|
+
export async function runWorktreeCli(argv, dependencies = {}) {
|
|
39
|
+
const write = dependencies.write ?? ((text) => void process.stdout.write(text));
|
|
40
|
+
const cwd = resolve(dependencies.cwd ?? process.cwd());
|
|
41
|
+
const args = [];
|
|
42
|
+
let stateDir = join(dependencies.home ?? homedir(), '.xingular-harness', 'state');
|
|
43
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
44
|
+
if (argv[index] === '--state')
|
|
45
|
+
stateDir = resolve(argv[++index] ?? stateDir);
|
|
46
|
+
else
|
|
47
|
+
args.push(argv[index]);
|
|
48
|
+
}
|
|
49
|
+
const [command, ...rest] = args;
|
|
50
|
+
const flag = (name) => rest.includes(name);
|
|
51
|
+
const value = (name) => {
|
|
52
|
+
const index = rest.indexOf(name);
|
|
53
|
+
return index >= 0 ? rest[index + 1] : undefined;
|
|
54
|
+
};
|
|
55
|
+
const positional = rest.filter((item, index) => !item.startsWith('--') && !(index > 0 && ['--branch', '--from', '--keep'].includes(rest[index - 1])));
|
|
56
|
+
const worktrees = new Worktrees(stateDir);
|
|
57
|
+
switch (command) {
|
|
58
|
+
case 'list': {
|
|
59
|
+
const records = await worktrees.list(cwd);
|
|
60
|
+
write(records.length ? `${records.map(describe).join('\n')}\n` : 'No worktrees for this repository.\n');
|
|
61
|
+
return 0;
|
|
62
|
+
}
|
|
63
|
+
case 'new': {
|
|
64
|
+
const result = await worktrees.create({
|
|
65
|
+
repo: cwd,
|
|
66
|
+
...(positional[0] ? { name: positional[0] } : {}),
|
|
67
|
+
...(value('--branch') ? { branch: value('--branch') } : {}),
|
|
68
|
+
...(value('--from') ? { baseRef: value('--from') } : {}),
|
|
69
|
+
kind: flag('--permanent') ? 'permanent' : 'managed',
|
|
70
|
+
...(flag('--no-carry') ? { carryChanges: false } : {})
|
|
71
|
+
});
|
|
72
|
+
write(`${describe(result.worktree)}\n`);
|
|
73
|
+
if (result.carried.copied.length || result.carried.patched)
|
|
74
|
+
write(`Carried your uncommitted changes${result.carried.copied.length ? ` and ${result.carried.copied.length} untracked file(s)` : ''}.\n`);
|
|
75
|
+
if (result.included.copied.length)
|
|
76
|
+
write(`Copied ${result.included.copied.length} file(s) named in .worktreeinclude.\n`);
|
|
77
|
+
if (result.setup.state === 'untrusted')
|
|
78
|
+
write('The repository has a setup script you have not trusted. Read .xharness/worktree-setup, then run: xagent worktree trust-setup\n');
|
|
79
|
+
if (result.setup.state === 'failed')
|
|
80
|
+
write(`The setup script failed; see ${result.setup.log}.\n`);
|
|
81
|
+
return 0;
|
|
82
|
+
}
|
|
83
|
+
case 'status': {
|
|
84
|
+
const status = await worktrees.status((await findWorktree(worktrees, cwd, positional[0] ?? '')).id);
|
|
85
|
+
write(`${describe(status.record)}\n${status.changes} changed path(s), ${status.ahead} commit(s) since it started.\n`);
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
88
|
+
case 'branch': {
|
|
89
|
+
const record = await worktrees.branch((await findWorktree(worktrees, cwd, positional[0] ?? '')).id, positional[1] ?? '');
|
|
90
|
+
write(`${describe(record)}\n`);
|
|
91
|
+
return 0;
|
|
92
|
+
}
|
|
93
|
+
case 'handoff': {
|
|
94
|
+
const direction = positional[1] === 'to-main' ? 'toSource' : positional[1] === 'to-worktree' ? 'toWorktree' : null;
|
|
95
|
+
if (!direction) {
|
|
96
|
+
write(WORKTREE_USAGE);
|
|
97
|
+
return 2;
|
|
98
|
+
}
|
|
99
|
+
const result = await worktrees.handoff((await findWorktree(worktrees, cwd, positional[0] ?? '')).id, direction, { move: !flag('--copy') });
|
|
100
|
+
write(result.patched || result.copied.length ? `Handed off${result.copied.length ? ` (and ${result.copied.length} untracked file(s))` : ''}.${result.stash ? ` The origin's copy is kept in git stash ${result.stash.slice(0, 12)}.` : ''}\n` : 'Nothing to hand off.\n');
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
case 'rm': {
|
|
104
|
+
const { worktree, snapshot } = await worktrees.remove((await findWorktree(worktrees, cwd, positional[0] ?? '')).id, { force: flag('--force') });
|
|
105
|
+
write(`Removed ${worktree.name}.${snapshot ? ` Its unsaved work is kept; xagent worktree restore ${worktree.name} brings it back.` : ''}\n`);
|
|
106
|
+
return 0;
|
|
107
|
+
}
|
|
108
|
+
case 'restore': {
|
|
109
|
+
const record = await worktrees.restore((await findWorktree(worktrees, cwd, positional[0] ?? '', true)).id);
|
|
110
|
+
write(`${describe(record)}\n`);
|
|
111
|
+
return 0;
|
|
112
|
+
}
|
|
113
|
+
case 'prune': {
|
|
114
|
+
const keep = value('--keep') ? Number(value('--keep')) : undefined;
|
|
115
|
+
const result = await worktrees.prune({ repo: cwd, ...(keep !== undefined && Number.isFinite(keep) ? { keep } : {}) });
|
|
116
|
+
write(`Removed ${result.removed.length} worktree(s)${result.removed.some((entry) => entry.snapshot) ? ', keeping snapshots of unsaved work' : ''}.\n`);
|
|
117
|
+
for (const failure of result.failed)
|
|
118
|
+
write(`Could not remove ${failure.id}: ${failure.error}\n`);
|
|
119
|
+
return result.failed.length ? 1 : 0;
|
|
120
|
+
}
|
|
121
|
+
case 'adopt': {
|
|
122
|
+
const record = await worktrees.adopt(resolve(cwd, positional[0] ?? ''));
|
|
123
|
+
write(`${describe(record)}\n`);
|
|
124
|
+
return 0;
|
|
125
|
+
}
|
|
126
|
+
case 'trust-setup': {
|
|
127
|
+
const { setupScript } = await import("./setup.js");
|
|
128
|
+
const repo = await worktrees.repositoryOf(cwd);
|
|
129
|
+
const script = setupScript(repo);
|
|
130
|
+
if (!script) {
|
|
131
|
+
write('This repository has no .xharness/worktree-setup.\n');
|
|
132
|
+
return 1;
|
|
133
|
+
}
|
|
134
|
+
await worktrees.trustSetup(repo, script.hash);
|
|
135
|
+
write(`Trusted the setup script (sha256 ${script.hash.slice(0, 12)}…). A changed script asks again.\n`);
|
|
136
|
+
return 0;
|
|
137
|
+
}
|
|
138
|
+
case 'path': {
|
|
139
|
+
write(`${(await findWorktree(worktrees, cwd, positional[0] ?? '')).path}\n`);
|
|
140
|
+
return 0;
|
|
141
|
+
}
|
|
142
|
+
default:
|
|
143
|
+
write(WORKTREE_USAGE);
|
|
144
|
+
return command && command !== 'help' ? 2 : 0;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CopyReport } from "./types.js";
|
|
2
|
+
export declare const INCLUDE_FILE = ".worktreeinclude";
|
|
3
|
+
export declare function copyFiles(from: string, to: string, paths: readonly string[]): CopyReport;
|
|
4
|
+
/** Untracked files that are not ignored: new work a person has not added yet. */
|
|
5
|
+
export declare function untrackedFiles(checkout: string): Promise<string[]>;
|
|
6
|
+
/** All ignored user files that must be bounded and captured before a worktree is removed. */
|
|
7
|
+
export declare function ignoredFiles(checkout: string): Promise<string[]>;
|
|
8
|
+
/** Ignored files that match `.worktreeinclude`, matched by git itself. */
|
|
9
|
+
export declare function includedFiles(checkout: string): Promise<string[]>;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// Copies files git does not track into a worktree: untracked work carried from the source, and the
|
|
2
|
+
// ignored files `.worktreeinclude` names (local settings, `.env`). A file is never overwritten, a
|
|
3
|
+
// symlink is never followed, and sizes are capped.
|
|
4
|
+
import { copyFileSync, existsSync, lstatSync, mkdirSync } from 'node:fs';
|
|
5
|
+
import { dirname, join } from 'node:path';
|
|
6
|
+
import { HarnessError } from "../core/errors.js";
|
|
7
|
+
import { safeRelative } from "../core/fs.js";
|
|
8
|
+
import { git, nulList } from "./git.js";
|
|
9
|
+
export const INCLUDE_FILE = '.worktreeinclude';
|
|
10
|
+
const FILE_CAP = 5 * 1024 * 1024;
|
|
11
|
+
const TOTAL_CAP = 100 * 1024 * 1024;
|
|
12
|
+
const IGNORED_FILE_COUNT_CAP = 10_000;
|
|
13
|
+
const IGNORED_PATH_BYTES_CAP = 1024 * 1024;
|
|
14
|
+
export function copyFiles(from, to, paths) {
|
|
15
|
+
const report = { copied: [], skipped: [] };
|
|
16
|
+
let total = 0;
|
|
17
|
+
for (const path of paths) {
|
|
18
|
+
let relative;
|
|
19
|
+
try {
|
|
20
|
+
relative = safeRelative(path);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const source = join(from, relative);
|
|
26
|
+
const target = join(to, relative);
|
|
27
|
+
if (existsSync(target)) {
|
|
28
|
+
report.skipped.push({ path: relative, reason: 'exists' });
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
let stat;
|
|
32
|
+
try {
|
|
33
|
+
stat = lstatSync(source);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (stat.isSymbolicLink()) {
|
|
39
|
+
report.skipped.push({ path: relative, reason: 'symlink' });
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (!stat.isFile()) {
|
|
43
|
+
report.skipped.push({ path: relative, reason: 'not_file' });
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (stat.size > FILE_CAP) {
|
|
47
|
+
report.skipped.push({ path: relative, reason: 'too_large' });
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (total + stat.size > TOTAL_CAP) {
|
|
51
|
+
report.skipped.push({ path: relative, reason: 'over_total' });
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
55
|
+
copyFileSync(source, target);
|
|
56
|
+
total += stat.size;
|
|
57
|
+
report.copied.push(relative);
|
|
58
|
+
}
|
|
59
|
+
return report;
|
|
60
|
+
}
|
|
61
|
+
/** Untracked files that are not ignored: new work a person has not added yet. */
|
|
62
|
+
export async function untrackedFiles(checkout) {
|
|
63
|
+
return nulList((await git(checkout, ['ls-files', '--others', '--exclude-standard', '-z'])).stdout);
|
|
64
|
+
}
|
|
65
|
+
/** All ignored user files that must be bounded and captured before a worktree is removed. */
|
|
66
|
+
export async function ignoredFiles(checkout) {
|
|
67
|
+
const paths = nulList((await git(checkout, ['ls-files', '--others', '--ignored', '--exclude-standard', '-z'])).stdout);
|
|
68
|
+
if (paths.length > IGNORED_FILE_COUNT_CAP)
|
|
69
|
+
throw ignoredFilesError(`there are more than ${IGNORED_FILE_COUNT_CAP} ignored files`);
|
|
70
|
+
let total = 0;
|
|
71
|
+
let pathBytes = 0;
|
|
72
|
+
return paths.map((path) => {
|
|
73
|
+
let relative;
|
|
74
|
+
try {
|
|
75
|
+
relative = safeRelative(path);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
throw ignoredFilesError('an ignored path is unsafe');
|
|
79
|
+
}
|
|
80
|
+
pathBytes += Buffer.byteLength(relative) + 10;
|
|
81
|
+
if (pathBytes > IGNORED_PATH_BYTES_CAP)
|
|
82
|
+
throw ignoredFilesError('the ignored paths exceed the snapshot limit');
|
|
83
|
+
let stat;
|
|
84
|
+
try {
|
|
85
|
+
stat = lstatSync(join(checkout, relative));
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
throw ignoredFilesError(`could not inspect ${relative}`);
|
|
89
|
+
}
|
|
90
|
+
if (!stat.isFile() && !stat.isSymbolicLink())
|
|
91
|
+
throw ignoredFilesError(`${relative} is not a regular file or symlink`);
|
|
92
|
+
if (stat.size > FILE_CAP)
|
|
93
|
+
throw ignoredFilesError(`${relative} exceeds the ${FILE_CAP}-byte per-file limit`);
|
|
94
|
+
total += stat.size;
|
|
95
|
+
if (total > TOTAL_CAP)
|
|
96
|
+
throw ignoredFilesError(`ignored files exceed the ${TOTAL_CAP}-byte total limit`);
|
|
97
|
+
return relative;
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
function ignoredFilesError(reason) {
|
|
101
|
+
return new HarnessError('worktree_has_work', `Ignored files cannot be safely preserved: ${reason}.`, 'Move or remove those files, then try again.');
|
|
102
|
+
}
|
|
103
|
+
/** Ignored files that match `.worktreeinclude`, matched by git itself. */
|
|
104
|
+
export async function includedFiles(checkout) {
|
|
105
|
+
const patterns = join(checkout, INCLUDE_FILE);
|
|
106
|
+
if (!existsSync(patterns))
|
|
107
|
+
return [];
|
|
108
|
+
const ignored = new Set(nulList((await git(checkout, ['ls-files', '--others', '--ignored', '--exclude-standard', '-z'])).stdout));
|
|
109
|
+
const matching = nulList((await git(checkout, ['ls-files', '--others', '--ignored', `--exclude-from=${patterns}`, '-z'])).stdout);
|
|
110
|
+
return matching.filter((path) => ignored.has(path));
|
|
111
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface GitResult {
|
|
2
|
+
code: number;
|
|
3
|
+
stdout: string;
|
|
4
|
+
stderr: string;
|
|
5
|
+
}
|
|
6
|
+
export interface GitOptions {
|
|
7
|
+
input?: string | Buffer;
|
|
8
|
+
env?: Record<string, string>;
|
|
9
|
+
/** Return a failed result instead of throwing. */
|
|
10
|
+
allowFail?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare function git(cwd: string, args: readonly string[], options?: GitOptions): Promise<GitResult>;
|
|
13
|
+
/** The trimmed standard output of a git command that must succeed. */
|
|
14
|
+
export declare function gitText(cwd: string, args: readonly string[], options?: GitOptions): Promise<string>;
|
|
15
|
+
/** NUL-separated output as a list, without the empty last entry. */
|
|
16
|
+
export declare function nulList(text: string): string[];
|