@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
package/src/memory/blocks.ts
DELETED
|
@@ -1,408 +0,0 @@
|
|
|
1
|
-
// Core memory: blocks. A block is a short Markdown file that is always in the context of what
|
|
2
|
-
// it is attached to, and that the model edits itself. Blocks live under `wiki/blocks/`:
|
|
3
|
-
// `shared/<label>.md` (the `user` block and custom shared blocks), `agents/<agent-id>/` (an
|
|
4
|
-
// agent's `persona` and `notes`), and `projects/<slug>/brief.md`. A block's id and scope come
|
|
5
|
-
// from where its file lives. Every edit is a revision and an undoable operation.
|
|
6
|
-
import { existsSync, readFileSync } from 'node:fs'
|
|
7
|
-
import { join, relative } from 'node:path'
|
|
8
|
-
|
|
9
|
-
import { noteChange } from '../core/changes'
|
|
10
|
-
import { HarnessError, invalid, notFound } from '../core/errors'
|
|
11
|
-
import * as frontmatter from '../core/frontmatter'
|
|
12
|
-
import { atomicWrite, newId, now, safeId, writeJson } from '../core/fs'
|
|
13
|
-
import { listProjects, projectsOrNone } from '../core/projects'
|
|
14
|
-
import { charCount, comparePaths, compareText } from '../core/text'
|
|
15
|
-
import { listOperations, undo, type Operation } from './operations'
|
|
16
|
-
import { looksSecret } from './secrets'
|
|
17
|
-
import * as store from './store'
|
|
18
|
-
|
|
19
|
-
export const DEFAULT_LIMIT = 2000
|
|
20
|
-
export const PROJECT_LIMIT = 3000
|
|
21
|
-
export const MAX_LIMIT = 20_000
|
|
22
|
-
/** An agent's prompt carries at most this many project briefs; the rest are listed by name. */
|
|
23
|
-
export const AGENT_PROJECT_BRIEFS = 2
|
|
24
|
-
const AGENT_LABELS = ['persona', 'notes']
|
|
25
|
-
|
|
26
|
-
export interface BlockFront {
|
|
27
|
-
label: string
|
|
28
|
-
/** Tells the model what belongs in the block. */
|
|
29
|
-
description: string
|
|
30
|
-
limit: number
|
|
31
|
-
/** Only the user may edit it. */
|
|
32
|
-
readOnly: boolean
|
|
33
|
-
/** Custom shared blocks: the agents it is attached to; empty means every agent. */
|
|
34
|
-
agents: string[]
|
|
35
|
-
updatedAt: string
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export type BlockScope = 'shared' | 'agent' | 'project'
|
|
39
|
-
|
|
40
|
-
export interface Block {
|
|
41
|
-
/** `blocks/shared/user`, `blocks/agents/<agent-id>/persona`, `blocks/projects/<slug>/brief`. */
|
|
42
|
-
id: string
|
|
43
|
-
scope: BlockScope
|
|
44
|
-
/** The agent id or project slug the block belongs to. */
|
|
45
|
-
owner: string | null
|
|
46
|
-
front: BlockFront
|
|
47
|
-
body: string
|
|
48
|
-
path: string
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/** Who is reading or editing blocks. */
|
|
52
|
-
export type Caller =
|
|
53
|
-
| { kind: 'user' }
|
|
54
|
-
/** An agent with blocks of its own, and the name recorded on its revisions. */
|
|
55
|
-
| { kind: 'agent'; id: string; name: string; vaultAccess?: 'self' | 'propose' | 'curator' }
|
|
56
|
-
/** A session without blocks of its own, and its project, if any. */
|
|
57
|
-
| { kind: 'session'; projectSlug: string | null }
|
|
58
|
-
|
|
59
|
-
function actorOf(caller: Caller): string {
|
|
60
|
-
return caller.kind === 'user' ? 'user' : caller.kind === 'agent' ? caller.name : 'Harness session'
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export function blocksDir(wiki: string): string {
|
|
64
|
-
return join(wiki, 'blocks')
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function locate(wiki: string, path: string): { id: string; scope: BlockScope; owner: string | null } | null {
|
|
68
|
-
const inside = relative(blocksDir(wiki), path)
|
|
69
|
-
if (inside.startsWith('..')) return null
|
|
70
|
-
const parts = inside.replace(/(?<=[^/])\.[^./]*$/, '').split('/')
|
|
71
|
-
const id = `blocks/${parts.join('/')}`
|
|
72
|
-
if (parts.length === 2 && parts[0] === 'shared') return { id, scope: 'shared', owner: null }
|
|
73
|
-
if (parts.length === 3 && parts[0] === 'agents') return { id, scope: 'agent', owner: parts[1] }
|
|
74
|
-
if (parts.length === 3 && parts[0] === 'projects' && parts[2] === 'brief') return { id, scope: 'project', owner: parts[1] }
|
|
75
|
-
return null
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function parseFront(front: Record<string, unknown>): BlockFront | null {
|
|
79
|
-
const { label, description, limit, readOnly, updatedAt } = front
|
|
80
|
-
if (typeof label !== 'string') return null
|
|
81
|
-
if (description !== undefined && typeof description !== 'string') return null
|
|
82
|
-
if (limit !== undefined && !(typeof limit === 'number' && Number.isInteger(limit) && limit >= 0)) return null
|
|
83
|
-
if (readOnly !== undefined && typeof readOnly !== 'boolean') return null
|
|
84
|
-
if (updatedAt !== undefined && typeof updatedAt !== 'string') return null
|
|
85
|
-
const agents = store.stringList(front.agents)
|
|
86
|
-
if (!agents) return null
|
|
87
|
-
return { label, description: description ?? '', limit: limit ?? DEFAULT_LIMIT, readOnly: readOnly ?? false, agents, updatedAt: updatedAt ?? '' }
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export function serializeBlock(front: BlockFront, body: string): string {
|
|
91
|
-
return frontmatter.serialize(
|
|
92
|
-
{ label: front.label, description: front.description, limit: front.limit, readOnly: front.readOnly, ...(front.agents.length ? { agents: front.agents } : {}), updatedAt: front.updatedAt },
|
|
93
|
-
body
|
|
94
|
-
)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function parse(wiki: string, path: string): Block | null {
|
|
98
|
-
const located = locate(wiki, path)
|
|
99
|
-
if (!located) return null
|
|
100
|
-
let text: string
|
|
101
|
-
try {
|
|
102
|
-
text = readFileSync(path, 'utf8')
|
|
103
|
-
} catch {
|
|
104
|
-
return null
|
|
105
|
-
}
|
|
106
|
-
const parsed = frontmatter.parse(text)
|
|
107
|
-
const front = parsed && parseFront(parsed.front)
|
|
108
|
-
if (!parsed || !front) return null
|
|
109
|
-
return { ...located, front, body: parsed.body.trimEnd(), path }
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export function loadAll(wiki: string): Block[] {
|
|
113
|
-
const files: string[] = []
|
|
114
|
-
store.markdownFiles(blocksDir(wiki), files)
|
|
115
|
-
return files.sort(comparePaths).flatMap((path) => parse(wiki, path) ?? [])
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/** A block by its id (`blocks/shared/user`). Every segment must be a safe identifier. */
|
|
119
|
-
export function find(wiki: string, id: string): Block {
|
|
120
|
-
if (!id.startsWith('blocks/')) throw notFound('Memory block')
|
|
121
|
-
const segments = id.slice('blocks/'.length).split('/')
|
|
122
|
-
try {
|
|
123
|
-
segments.forEach(safeId)
|
|
124
|
-
} catch {
|
|
125
|
-
throw notFound('Memory block')
|
|
126
|
-
}
|
|
127
|
-
const block = parse(wiki, `${join(blocksDir(wiki), ...segments)}.md`)
|
|
128
|
-
if (!block) throw notFound('Memory block')
|
|
129
|
-
return block
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function create(wiki: string, path: string, label: string, description: string, limit: number): Block {
|
|
133
|
-
const file = join(blocksDir(wiki), `${path}.md`)
|
|
134
|
-
if (!existsSync(file)) atomicWrite(file, serializeBlock({ label, description, limit, readOnly: false, agents: [], updatedAt: now() }, ''))
|
|
135
|
-
const block = parse(wiki, file)
|
|
136
|
-
if (!block) throw new HarnessError('invalid_data', `The ${label} memory block could not be read.`)
|
|
137
|
-
return block
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export function ensureUser(wiki: string): Block {
|
|
141
|
-
return create(wiki, 'shared/user', 'user', 'What you know about the user: name, role, preferences, and how they like to work. Shared with every agent and session.', DEFAULT_LIMIT)
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export function ensureAgent(wiki: string, agentId: string): Block[] {
|
|
145
|
-
const agent = safeId(agentId)
|
|
146
|
-
return [
|
|
147
|
-
create(wiki, `agents/${agent}/persona`, 'persona', 'How you work: your role for this user, your habits, and what you have learned about doing this job well.', DEFAULT_LIMIT),
|
|
148
|
-
create(wiki, `agents/${agent}/notes`, 'notes', 'Working notes to keep across turns: what you are in the middle of and what to follow up. Prune what is done.', DEFAULT_LIMIT)
|
|
149
|
-
]
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export function ensureProject(wiki: string, slug: string, name: string): Block {
|
|
153
|
-
const safe = safeId(slug)
|
|
154
|
-
return create(
|
|
155
|
-
wiki,
|
|
156
|
-
`projects/${safe}/brief`,
|
|
157
|
-
`project/${safe}`,
|
|
158
|
-
`What ${name.replaceAll('\n', ' ')} is, its stack and conventions, and its current state. Shared by everyone working in this project.`,
|
|
159
|
-
PROJECT_LIMIT
|
|
160
|
-
)
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* The blocks in a caller's context, in the order they are shown. Missing default blocks are
|
|
165
|
-
* created. `projectSlugs` are the projects whose briefs an agent carries (most recent first).
|
|
166
|
-
*/
|
|
167
|
-
export function attached(root: string, caller: Caller, projectSlugs: readonly string[]): Block[] {
|
|
168
|
-
const wiki = store.wikiDir(root)
|
|
169
|
-
const projectName = (slug: string): string | null => projectsOrNone(root).find((project) => project.slug === slug)?.name ?? null
|
|
170
|
-
if (caller.kind === 'user') return loadAll(wiki)
|
|
171
|
-
const blocks: Block[] = []
|
|
172
|
-
if (caller.kind === 'agent') {
|
|
173
|
-
blocks.push(...ensureAgent(wiki, caller.id))
|
|
174
|
-
blocks.push(ensureUser(wiki))
|
|
175
|
-
blocks.push(...loadAll(wiki).filter((block) => block.scope === 'shared' && block.front.label !== 'user' && (!block.front.agents.length || block.front.agents.includes(caller.id))))
|
|
176
|
-
// The most recently active projects are chosen, then listed in a fixed order: later activity
|
|
177
|
-
// must not reshuffle the context a prompt cache was built on.
|
|
178
|
-
for (const slug of projectSlugs.slice(0, AGENT_PROJECT_BRIEFS).sort(compareText)) {
|
|
179
|
-
const name = projectName(slug)
|
|
180
|
-
if (name !== null) blocks.push(ensureProject(wiki, slug, name))
|
|
181
|
-
}
|
|
182
|
-
} else {
|
|
183
|
-
blocks.push(ensureUser(wiki))
|
|
184
|
-
const name = caller.projectSlug ? projectName(caller.projectSlug) : null
|
|
185
|
-
if (caller.projectSlug && name !== null) blocks.push(ensureProject(wiki, caller.projectSlug, name))
|
|
186
|
-
}
|
|
187
|
-
return blocks
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/** Why `caller` may not change `block`, or `null` when it may; the text is what the model sees. */
|
|
191
|
-
export function editRefusal(caller: Caller, block: Block): string | null {
|
|
192
|
-
const label = block.front.label
|
|
193
|
-
if (caller.kind === 'user') return null
|
|
194
|
-
if (block.front.readOnly) return `The ${label} block is read-only; only the user can change it.`
|
|
195
|
-
if (caller.kind === 'agent' && caller.vaultAccess === 'propose') return 'Memory changes are proposals in this session. Submit the block change with wiki_propose; the next memory merge applies it.'
|
|
196
|
-
if (caller.kind === 'agent' && caller.vaultAccess === 'self' && (block.scope !== 'agent' || block.owner !== caller.id || !['persona', 'notes'].includes(label))) return 'This field is outside your writable memory. Submit a block change with wiki_propose for the curator to review.'
|
|
197
|
-
if (caller.kind === 'agent') {
|
|
198
|
-
if (block.scope === 'agent') return block.owner === caller.id ? null : 'That block belongs to another agent.'
|
|
199
|
-
if (block.scope === 'shared') return !block.front.agents.length || block.front.agents.includes(caller.id) ? null : `The ${label} block is not attached to you.`
|
|
200
|
-
return null
|
|
201
|
-
}
|
|
202
|
-
if (block.scope === 'project') return block.owner === caller.projectSlug ? null : "A session may edit only its own project's brief."
|
|
203
|
-
return `A Harness session can read the ${label} block but cannot edit it. Report what you learned in your result instead.`
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Finds the block a caller means by `label`: `user`, `persona`, `notes`, `project/<slug>`
|
|
208
|
-
* (or `project` for a session's own), a custom shared label, or a full block id.
|
|
209
|
-
*/
|
|
210
|
-
export function resolve(root: string, caller: Caller, rawLabel: string): Block {
|
|
211
|
-
const wiki = store.wikiDir(root)
|
|
212
|
-
const label = rawLabel.trim().replace(/^\/+/, '')
|
|
213
|
-
const unknown = () => invalid(`There is no memory block called ${label}. Use one of the labels shown in your memory blocks.`)
|
|
214
|
-
const orUnknown = (id: string): Block => {
|
|
215
|
-
try {
|
|
216
|
-
return find(wiki, id)
|
|
217
|
-
} catch {
|
|
218
|
-
throw unknown()
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
if (label.startsWith('blocks/')) return orUnknown(label)
|
|
222
|
-
if (AGENT_LABELS.includes(label)) {
|
|
223
|
-
if (caller.kind !== 'agent') throw invalid(`The ${label} block belongs to an agent, not to a session.`)
|
|
224
|
-
return ensureAgent(wiki, caller.id).find((block) => block.front.label === label)!
|
|
225
|
-
}
|
|
226
|
-
if (label === 'project' || label.startsWith('project/')) {
|
|
227
|
-
const slug = label.startsWith('project/') ? label.slice('project/'.length) : caller.kind === 'session' ? caller.projectSlug : null
|
|
228
|
-
if (slug === null) throw invalid('Name the project: project/<slug>.')
|
|
229
|
-
const project = listProjects(root).find((entry) => entry.slug === slug)
|
|
230
|
-
if (!project) throw unknown()
|
|
231
|
-
return ensureProject(wiki, project.slug, project.name)
|
|
232
|
-
}
|
|
233
|
-
if (label === 'user') return ensureUser(wiki)
|
|
234
|
-
return orUnknown(`blocks/shared/${label}`)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
export type Edit = { kind: 'append'; text: string } | { kind: 'replace'; old: string; new: string } | { kind: 'rethink'; text: string }
|
|
238
|
-
|
|
239
|
-
/** The body after an edit. Pure, so the rules are testable. Throws the reason an edit is refused. */
|
|
240
|
-
export function applyEdit(body: string, edit: Edit): string {
|
|
241
|
-
if (edit.kind === 'append') {
|
|
242
|
-
const text = edit.text.trim()
|
|
243
|
-
if (!text) throw invalid('Nothing to append.')
|
|
244
|
-
return body.trim() ? `${body.trimEnd()}\n${text}` : text
|
|
245
|
-
}
|
|
246
|
-
if (edit.kind === 'replace') {
|
|
247
|
-
if (!edit.old) throw invalid('Give the exact passage to replace.')
|
|
248
|
-
const count = body.split(edit.old).length - 1
|
|
249
|
-
if (count === 0) throw invalid('That passage is not in the block. Copy it exactly as it appears.')
|
|
250
|
-
if (count > 1) throw invalid(`That passage appears ${count} times. Include more of the surrounding text so it is unique.`)
|
|
251
|
-
return body.replace(edit.old, () => edit.new).trim()
|
|
252
|
-
}
|
|
253
|
-
return edit.text.trim()
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/** Why `body` cannot be stored in the block, or `null`. */
|
|
257
|
-
export function check(front: BlockFront, body: string): string | null {
|
|
258
|
-
const length = charCount(body)
|
|
259
|
-
if (length > front.limit) {
|
|
260
|
-
return `The ${front.label} block would be ${length} of ${front.limit} characters. Condense it with memory_rethink, or move detail to the Wiki with wiki_propose.`
|
|
261
|
-
}
|
|
262
|
-
if (looksSecret(body) || looksSecret(front.description)) return 'That text looks like it contains a credential, so it was not stored.'
|
|
263
|
-
return null
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/** Writes a block's new content with a revision before and after and an undo operation. */
|
|
267
|
-
function write(wiki: string, block: Block, front: BlockFront, body: string, actor: string, reason: string): Block {
|
|
268
|
-
let current = ''
|
|
269
|
-
try {
|
|
270
|
-
current = readFileSync(block.path, 'utf8')
|
|
271
|
-
} catch {
|
|
272
|
-
current = ''
|
|
273
|
-
}
|
|
274
|
-
const next = serializeBlock(front, body)
|
|
275
|
-
if (next === current) return block
|
|
276
|
-
// The undo target: the latest revision when it already holds the current text, else a new one.
|
|
277
|
-
const latest = store.currentRevision(wiki, block.id)
|
|
278
|
-
let before: string | null = null
|
|
279
|
-
if (latest) {
|
|
280
|
-
try {
|
|
281
|
-
if (store.revisionText(wiki, block.id, latest) === current) before = latest
|
|
282
|
-
} catch {
|
|
283
|
-
before = null
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
before ??= store.snapshot(wiki, block.id, current, actor, 'Before edit').id
|
|
287
|
-
atomicWrite(block.path, next)
|
|
288
|
-
const after = store.snapshot(wiki, block.id, next, actor, reason)
|
|
289
|
-
noteChange({ wiki, id: block.id, path: block.path, text: next, actor, reason })
|
|
290
|
-
const operation: Operation = {
|
|
291
|
-
id: newId(),
|
|
292
|
-
createdAt: now(),
|
|
293
|
-
trigger: `${actor}: ${reason} (${front.label})`,
|
|
294
|
-
pages: [{ pageId: block.id, path: block.path, beforeRevisionId: before, afterRevisionId: after.id }],
|
|
295
|
-
undone: false
|
|
296
|
-
}
|
|
297
|
-
writeJson(join(wiki, 'operations', `${operation.id}.json`), operation)
|
|
298
|
-
store.log(wiki, `- ${now()} · ${actor} · block · \`${block.id}\` ${reason} · revision \`${after.id}\``)
|
|
299
|
-
return find(wiki, block.id)
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/** A model's edit through `memory_append`, `memory_replace`, or `memory_rethink`. */
|
|
303
|
-
export function edit(root: string, caller: Caller, label: string, change: Edit): Block {
|
|
304
|
-
const wiki = store.wikiDir(root)
|
|
305
|
-
const block = resolve(root, caller, label)
|
|
306
|
-
const refusal = editRefusal(caller, block)
|
|
307
|
-
if (refusal) throw invalid(refusal)
|
|
308
|
-
const body = applyEdit(block.body, change)
|
|
309
|
-
const problem = check(block.front, body)
|
|
310
|
-
if (problem) throw invalid(problem)
|
|
311
|
-
const reason = change.kind === 'append' ? 'appended' : change.kind === 'replace' ? 'replaced a passage' : 'rewrote'
|
|
312
|
-
return write(wiki, block, { ...block.front, updatedAt: now() }, body, actorOf(caller), reason)
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
export interface BlockInput {
|
|
316
|
-
/** An existing block id, or none to create a shared block from `label`. */
|
|
317
|
-
id?: string | null
|
|
318
|
-
label?: string | null
|
|
319
|
-
body: string
|
|
320
|
-
description: string
|
|
321
|
-
limit: number
|
|
322
|
-
readOnly?: boolean
|
|
323
|
-
agents?: string[]
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/** The user's edit in the Wiki, or a new custom shared block. */
|
|
327
|
-
export function saveAsUser(wiki: string, input: BlockInput): Block {
|
|
328
|
-
if (!Number.isInteger(input.limit) || input.limit <= 0 || input.limit > MAX_LIMIT) throw invalid(`A block's limit is between 1 and ${MAX_LIMIT} characters.`)
|
|
329
|
-
let block: Block
|
|
330
|
-
if (input.id) {
|
|
331
|
-
block = find(wiki, input.id)
|
|
332
|
-
} else {
|
|
333
|
-
const label = store.slug(input.label ?? '')
|
|
334
|
-
if (!(input.label ?? '').trim() || AGENT_LABELS.includes(label) || label === 'user' || label.startsWith('project')) {
|
|
335
|
-
throw invalid('Give the block a label that is not user, persona, notes, or project.')
|
|
336
|
-
}
|
|
337
|
-
let exists = true
|
|
338
|
-
try {
|
|
339
|
-
find(wiki, `blocks/shared/${label}`)
|
|
340
|
-
} catch {
|
|
341
|
-
exists = false
|
|
342
|
-
}
|
|
343
|
-
if (exists) throw invalid(`A shared block called ${label} already exists.`)
|
|
344
|
-
block = create(wiki, `shared/${label}`, label, input.description.trim(), input.limit)
|
|
345
|
-
}
|
|
346
|
-
const front: BlockFront = { ...block.front, description: input.description.trim(), limit: input.limit, readOnly: input.readOnly ?? false, updatedAt: now() }
|
|
347
|
-
if (block.scope === 'shared' && front.label !== 'user') front.agents = input.agents ?? []
|
|
348
|
-
const body = input.body.trim()
|
|
349
|
-
const problem = check(front, body)
|
|
350
|
-
if (problem) throw invalid(problem)
|
|
351
|
-
return write(wiki, block, front, body, 'user', input.id ? 'edited' : 'created')
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
/** The most recent edit of a block that has not been undone yet. */
|
|
355
|
-
function lastEdit(wiki: string, blockId: string): Operation | null {
|
|
356
|
-
return (
|
|
357
|
-
listOperations(wiki)
|
|
358
|
-
.filter((operation) => !operation.undone && operation.pages.length === 1 && operation.pages[0].pageId === blockId)
|
|
359
|
-
.sort((left, right) => compareText(left.createdAt, right.createdAt))
|
|
360
|
-
.at(-1) ?? null
|
|
361
|
-
)
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
export function undoLast(wiki: string, blockId: string): Block {
|
|
365
|
-
const latest = lastEdit(wiki, blockId)
|
|
366
|
-
if (!latest) throw invalid('There is no edit to undo.')
|
|
367
|
-
undo(wiki, latest.id)
|
|
368
|
-
return find(wiki, blockId)
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* The memory-blocks section of a compiled prompt. `cli` names the `xagent-wiki` commands in
|
|
373
|
-
* place of the tools, for sessions that have the command and not the tools.
|
|
374
|
-
*/
|
|
375
|
-
export function render(blocks: readonly Block[], caller: Caller, cli: boolean): string {
|
|
376
|
-
if (!blocks.length) return ''
|
|
377
|
-
const how = cli
|
|
378
|
-
? '`xagent-wiki block append <label> <text>`, `block replace <label> --old <text> --new <text>`, or `block rethink <label> <text>`'
|
|
379
|
-
: 'memory_append, memory_replace, or memory_rethink'
|
|
380
|
-
return `## Memory blocks\n\nThese blocks are your memory that is always in view, and they persist across conversations. When you learn something worth keeping, edit a block you may change with ${how}. Keep each block within its limit.\n${renderItems(blocks, caller)}`
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
/** The blocks alone, each framed with its label, how full it is, and what belongs in it. */
|
|
384
|
-
export function renderItems(blocks: readonly Block[], caller: Caller): string {
|
|
385
|
-
let text = ''
|
|
386
|
-
for (const block of blocks) {
|
|
387
|
-
const editable = editRefusal(caller, block) === null
|
|
388
|
-
text += `\n<block label="${block.front.label}" chars="${charCount(block.body)}/${block.front.limit}"${editable ? '' : ' read-only="true"'}>\n${block.front.description}\n---\n${block.body.trim() || '(empty)'}\n</block>\n`
|
|
389
|
-
}
|
|
390
|
-
return text
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
export type MemoryBlock = Omit<BlockFront, 'agents'> & { agents?: string[]; id: string; scope: BlockScope; owner: string | null; body: string; path: string; revisionId: string | null; canUndo: boolean }
|
|
394
|
-
|
|
395
|
-
export function response(wiki: string, block: Block): MemoryBlock {
|
|
396
|
-
const { agents, ...front } = block.front
|
|
397
|
-
return {
|
|
398
|
-
id: block.id,
|
|
399
|
-
scope: block.scope,
|
|
400
|
-
owner: block.owner,
|
|
401
|
-
...front,
|
|
402
|
-
...(agents.length ? { agents } : {}),
|
|
403
|
-
body: block.body,
|
|
404
|
-
path: block.path,
|
|
405
|
-
revisionId: store.currentRevision(wiki, block.id),
|
|
406
|
-
canUndo: lastEdit(wiki, block.id) !== null
|
|
407
|
-
}
|
|
408
|
-
}
|
package/src/memory/caller.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
// Who is calling the memory and Wiki API. The embedding application supplies this when a
|
|
2
|
-
// session starts; the harness never looks an agent up by itself.
|
|
3
|
-
import { findProject, projectsOrNone, type Project } from '../core/projects'
|
|
4
|
-
import { invalid } from '../core/errors'
|
|
5
|
-
import type { HarnessEnv } from '../core/env'
|
|
6
|
-
import * as blocks from './blocks'
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* The current project only orders results and picks a default namespace for proposals; it
|
|
10
|
-
* never limits what can be read.
|
|
11
|
-
*/
|
|
12
|
-
export interface CallerContext {
|
|
13
|
-
/** Opaque, host-owned policy data frozen when this session starts. The harness only forwards it to the embedding app's tool policy. */
|
|
14
|
-
policyContext?: unknown
|
|
15
|
-
/**
|
|
16
|
-
* Trusted, frozen vault mutation capability supplied by an embedding host. `self` writes its own
|
|
17
|
-
* persona and notes directly and proposes the rest; `propose` writes nothing directly; `curator`
|
|
18
|
-
* applies proposals.
|
|
19
|
-
*/
|
|
20
|
-
vaultAccess?: 'self' | 'propose' | 'curator'
|
|
21
|
-
maintenanceJobId?: string | null
|
|
22
|
-
maintenanceJobIds?: string[]
|
|
23
|
-
runId?: string | null
|
|
24
|
-
sessionId?: string | null
|
|
25
|
-
projectId?: string | null
|
|
26
|
-
/** The agent calling; it decides which memory blocks are attached and editable. */
|
|
27
|
-
agentId?: string | null
|
|
28
|
-
/** Agents whose conversations this caller may not recall (opaque ids from the embedding host). */
|
|
29
|
-
recallExcludeAgents?: string[] | null
|
|
30
|
-
/** The agent's name, recorded on the revisions it makes. */
|
|
31
|
-
agentName?: string | null
|
|
32
|
-
/** Projects whose briefs the agent carries, most recently active first. */
|
|
33
|
-
briefProjectIds?: string[] | null
|
|
34
|
-
/** `Chat` for an agent's own conversation, `Code` for a session in a project. */
|
|
35
|
-
actor?: string | null
|
|
36
|
-
/** `cli` when the caller reaches the Wiki through the `xagent-wiki` command. */
|
|
37
|
-
surface?: string | null
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export const isSession = (context: CallerContext): boolean => context.actor === 'Code'
|
|
41
|
-
export const actorOf = (context: CallerContext): string => (isSession(context) ? 'Code' : 'Chat')
|
|
42
|
-
export const usesCli = (context: CallerContext): boolean => context.surface === 'cli'
|
|
43
|
-
|
|
44
|
-
export function projectOf(root: string, context: CallerContext): Project | null {
|
|
45
|
-
if (!context.projectId) return null
|
|
46
|
-
try {
|
|
47
|
-
return findProject(root, context.projectId)
|
|
48
|
-
} catch {
|
|
49
|
-
return null
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/** Who is asking, for block attachment and permissions: an agent, or a session. */
|
|
54
|
-
export function blockCaller(env: HarnessEnv, context: CallerContext): blocks.Caller {
|
|
55
|
-
if (isSession(context)) return { kind: 'session', projectSlug: projectOf(env.root, context)?.slug ?? null }
|
|
56
|
-
if (!context.agentId) throw invalid('Memory blocks need an agent or a Harness session.')
|
|
57
|
-
return { kind: 'agent', id: context.agentId, name: context.agentName ?? env.directory.agentName(context.agentId) ?? context.agentId, vaultAccess: context.vaultAccess === 'propose' ? 'propose' : context.vaultAccess ? 'self' : undefined }
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** The blocks in the caller's context: an agent also carries the briefs of its active projects. */
|
|
61
|
-
export function callerBlocks(env: HarnessEnv, context: CallerContext): { caller: blocks.Caller; attached: blocks.Block[] } {
|
|
62
|
-
const caller = blockCaller(env, context)
|
|
63
|
-
let slugs: string[] = []
|
|
64
|
-
if (caller.kind === 'agent' && context.briefProjectIds?.length) {
|
|
65
|
-
const projects = projectsOrNone(env.root)
|
|
66
|
-
slugs = context.briefProjectIds.flatMap((id) => projects.find((project) => project.id === id)?.slug ?? [])
|
|
67
|
-
}
|
|
68
|
-
return { caller, attached: blocks.attached(env.root, caller, slugs) }
|
|
69
|
-
}
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { existsSync, mkdtempSync } from 'node:fs'
|
|
2
|
-
import { join } from 'node:path'
|
|
3
|
-
import { tmpdir } from 'node:os'
|
|
4
|
-
import { afterEach, expect, test } from 'vitest'
|
|
5
|
-
|
|
6
|
-
import { createHarness, type Harness } from '../harness'
|
|
7
|
-
import { memorySecretStore } from '../accounts/secrets'
|
|
8
|
-
import type { PiSessionLike } from '../sessions/runner'
|
|
9
|
-
import { registryTools } from '../tools/registryWrite'
|
|
10
|
-
import type { ToolSession } from '../tools/types'
|
|
11
|
-
import * as blocks from './blocks'
|
|
12
|
-
import { memoryEdit, propose } from './api'
|
|
13
|
-
import { enqueueCuration } from './curation'
|
|
14
|
-
import { findMemory } from './facts'
|
|
15
|
-
import * as registry from '../skills/registry'
|
|
16
|
-
import * as attachments from '../plugins/attachments'
|
|
17
|
-
import { wikiDir } from './store'
|
|
18
|
-
|
|
19
|
-
const opened: Harness[] = []
|
|
20
|
-
afterEach(async () => { for (const harness of opened.splice(0)) await harness.close() })
|
|
21
|
-
const self = { agentId: 'nora', agentName: 'Nora', actor: 'Chat', vaultAccess: 'self' as const, runId: 'origin' }
|
|
22
|
-
const curator = { agentId: 'curator', agentName: 'Curator', actor: 'Chat', vaultAccess: 'curator' as const, runId: 'review' }
|
|
23
|
-
|
|
24
|
-
function setup(): Harness {
|
|
25
|
-
let emit: (event: unknown) => void = () => undefined
|
|
26
|
-
const session: PiSessionLike = { sessionId: 'test-session', subscribe: listener => { emit = listener as never; return () => undefined }, prompt: async () => { emit({ type: 'message_end', message: { role: 'assistant', content: [{ type: 'text', text: 'Prefer pnpm for all builds.' }] } }) }, sendCustomMessage: async () => undefined, abort: async () => undefined, dispose: () => undefined }
|
|
27
|
-
const harness = createHarness({ dataRoot: mkdtempSync(join(tmpdir(), 'curation-data-')), stateDir: mkdtempSync(join(tmpdir(), 'curation-state-')), externalMaintenance: true, secrets: memorySecretStore(), sessionFactory: async () => session, maintainerFactory: async () => { throw new Error('Hidden maintenance must not run') } })
|
|
28
|
-
opened.push(harness)
|
|
29
|
-
harness.accounts.create('Main', 'apiKey')
|
|
30
|
-
blocks.ensureAgent(wikiDir(harness.env.root), 'nora')
|
|
31
|
-
return harness
|
|
32
|
-
}
|
|
33
|
-
async function origin(harness: Harness): Promise<void> {
|
|
34
|
-
await harness.sessions.run({ run: { id: 'origin', sessionId: 'nora' }, cwd: harness.env.root, sessionDir: join(harness.env.root, 'history'), text: 'Prefer pnpm for all builds.', caller: self, tools: { allow: [] } })
|
|
35
|
-
await new Promise(resolve => setTimeout(resolve, 30))
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
test('normal callers directly write only their own persona and notes; standalone callers retain their prior scope', () => {
|
|
39
|
-
const h = setup()
|
|
40
|
-
expect(memoryEdit(h.env, self, 'memory.append', { block: 'notes', text: 'Working on release notes.' })).toContain('Updated')
|
|
41
|
-
expect(() => memoryEdit(h.env, self, 'memory.append', { block: 'user', text: 'A shared preference.' })).toThrow('outside your writable memory')
|
|
42
|
-
blocks.ensureAgent(wikiDir(h.env.root), 'other')
|
|
43
|
-
expect(() => memoryEdit(h.env, self, 'memory.append', { block: 'blocks/agents/other/notes', text: 'Not mine.' })).toThrow()
|
|
44
|
-
expect(memoryEdit(h.env, { ...self, vaultAccess: undefined }, 'memory.append', { block: 'user', text: 'Standalone scope.' })).toContain('Updated')
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
test('a shared fact is proposed without writing, then validated against its original run and applied once', async () => {
|
|
48
|
-
const h = setup(); await origin(h)
|
|
49
|
-
const submitted = propose(h.env, self, { kind: 'fact', title: 'Build tool', body: 'Use pnpm for builds.', confidence: 'high', sourceRefs: [{ kind: 'run', ref: 'current', excerpt: 'Prefer pnpm for all builds.' }] })
|
|
50
|
-
const job = h.maintenance.jobs().find(job => job.input.kind === 'proposal')!
|
|
51
|
-
expect(submitted).toContain(job.id)
|
|
52
|
-
expect(() => findMemory(wikiDir(h.env.root), 'build-tool')).toThrow()
|
|
53
|
-
expect(() => h.maintenance.readJob(self, job.id)).toThrow('curator capability')
|
|
54
|
-
const receipt = h.maintenance.applyJob(curator, job.id, undefined, 'Preserve the stated build preference.')
|
|
55
|
-
expect(receipt.status).toBe('completed')
|
|
56
|
-
expect(findMemory(wikiDir(h.env.root), 'build-tool').front.sourceIds).toContain('run:origin')
|
|
57
|
-
expect(h.maintenance.applyJob(curator, job.id, undefined, 'Retry receipt').receipt).toEqual(receipt.receipt)
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
test('invented evidence is parked and a read-only memory block is not rewritten', async () => {
|
|
61
|
-
const h = setup(); await origin(h)
|
|
62
|
-
propose(h.env, self, { kind: 'fact', title: 'Invented', body: 'Use another tool.', confidence: 'high', sourceRefs: [{ kind: 'run', ref: 'current', excerpt: 'This was never said anywhere.' }] })
|
|
63
|
-
const job = h.maintenance.jobs().find(job => job.input.kind === 'proposal')!
|
|
64
|
-
expect(h.maintenance.applyJob(curator, job.id, undefined, 'Review the claimed evidence').status).toBe('needs_user')
|
|
65
|
-
expect(() => findMemory(wikiDir(h.env.root), 'invented')).toThrow()
|
|
66
|
-
const block = blocks.find(wikiDir(h.env.root), 'blocks/agents/nora/notes')
|
|
67
|
-
blocks.saveAsUser(wikiDir(h.env.root), { id: block.id, body: '', description: block.front.description, limit: 2000, readOnly: true })
|
|
68
|
-
expect(() => propose(h.env, self, { kind: 'block', id: block.id, title: 'Notes', body: 'Changed.' })).toThrow('user-only')
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
test('text resources remain inactive until curated; undo restores attachments and preserves subsequent user edits', async () => {
|
|
72
|
-
const h = setup()
|
|
73
|
-
const tool = (await registryTools({ harness: h })({ caller: self } as ToolSession)).find(tool => tool.name === 'registry_write')!
|
|
74
|
-
await tool.execute({ kind: 'skill', name: 'release-notes', description: 'Write release notes', body: 'Summarize verified changes.', reason: 'Repeated release work.' })
|
|
75
|
-
const job = h.maintenance.jobs().find(job => job.input.kind === 'registry')!
|
|
76
|
-
expect(registry.list(h.env.root).some(item => item.id === 'skills/release-notes')).toBe(false)
|
|
77
|
-
const receipt = h.maintenance.applyJob(curator, job.id, undefined, 'Reuse the repeated release procedure.')
|
|
78
|
-
expect(attachments.attached(attachments.load(h.env.root), ['skills/release-notes'], { agentId: 'nora' }, false)).toBe(true)
|
|
79
|
-
h.maintenance.undoOperation(receipt.receipt!.operationId!)
|
|
80
|
-
expect(registry.list(h.env.root).some(item => item.id === 'skills/release-notes')).toBe(false)
|
|
81
|
-
const next = enqueueCuration(h.env.root, { kind: 'registry', caller: self, proposal: { kind: 'skill', name: 'other-notes', description: 'Notes', body: 'Write verified notes.', reason: 'Workflow improvement.' } })
|
|
82
|
-
const applied = h.maintenance.applyJob(curator, next.id, undefined, 'Apply text-only improvement.')
|
|
83
|
-
registry.writeItem(h.env.root, 'skill', 'other-notes', 'Notes', 'The user changed this.', 'User edit')
|
|
84
|
-
expect(() => h.maintenance.undoOperation(applied.receipt!.operationId!)).toThrow('changed after')
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
test('changed target versions are escalated instead of overwritten', () => {
|
|
88
|
-
const h = setup()
|
|
89
|
-
registry.writeItem(h.env.root, 'skill', 'notes', 'Notes', 'Original notes.', 'Initial')
|
|
90
|
-
const job = enqueueCuration(h.env.root, { kind: 'registry', caller: self, proposal: { kind: 'skill', name: 'notes', description: 'Notes', body: 'Proposed notes.', reason: 'Improve' } })
|
|
91
|
-
registry.writeItem(h.env.root, 'skill', 'notes', 'Notes', 'User edits win.', 'User edit')
|
|
92
|
-
expect(h.maintenance.applyJob(curator, job.id, undefined, 'Review update').status).toBe('needs_user')
|
|
93
|
-
expect(registry.list(h.env.root).find(item => item.id === 'skills/notes')).toBeDefined()
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
test('executable plugins are submitted without saving, activation or trust', async () => {
|
|
97
|
-
const h = setup()
|
|
98
|
-
const tool = (await registryTools({ harness: h })({ caller: self } as ToolSession)).find(tool => tool.name === 'plugin_write')!
|
|
99
|
-
await tool.execute({ name: 'code-change', description: 'A code plugin', files: [{ path: 'extensions/index.ts', content: 'export default () => {}' }] })
|
|
100
|
-
const job = h.maintenance.jobs().find(job => job.input.kind === 'plugin')!
|
|
101
|
-
expect(h.maintenance.applyJob(curator, job.id, undefined, 'Code needs trust').status).toBe('needs_user')
|
|
102
|
-
expect(existsSync(join(h.env.root, 'plugins/code-change'))).toBe(false)
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
test('external jobs persist and repeated schedule occurrences are distinct; no hidden provider runs', async () => {
|
|
106
|
-
const h = setup()
|
|
107
|
-
const source = h.maintenance.ingest('source.txt', Buffer.from('Prefer pnpm for all builds.'))
|
|
108
|
-
expect(h.maintenance.jobs().some(job => job.input.kind === 'ingest' && job.input.sourceId === source.id)).toBe(true)
|
|
109
|
-
h.maintenance.enqueue({ kind: 'review', requestId: 'day-one' })
|
|
110
|
-
h.maintenance.enqueue({ kind: 'review', requestId: 'day-one' })
|
|
111
|
-
h.maintenance.enqueue({ kind: 'review', requestId: 'day-two' })
|
|
112
|
-
expect(h.maintenance.jobs().filter(job => job.input.kind === 'review')).toHaveLength(2)
|
|
113
|
-
await h.maintenance.settled()
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
test('a curator run never enqueues another completed-run maintenance job', async () => {
|
|
117
|
-
const h = setup()
|
|
118
|
-
await h.sessions.run({ run: { id: 'curator-run', sessionId: 'curator' }, cwd: h.env.root, sessionDir: join(h.env.root, 'curator-history'), text: 'Review maintenance.', caller: curator, tools: { allow: [] } })
|
|
119
|
-
await new Promise(resolve => setTimeout(resolve, 30))
|
|
120
|
-
expect(h.maintenance.jobs().some(job => job.input.kind === 'run' && job.input.runId === 'curator-run')).toBe(false)
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
test('curator prose cannot become its own evidence; original source runs can support a review', async () => {
|
|
124
|
-
const h = setup(); await origin(h)
|
|
125
|
-
await h.sessions.run({ run: { id: 'review', sessionId: 'curator' }, cwd: h.env.root, sessionDir: join(h.env.root, 'curator-history'), text: 'Prefer pnpm for all builds.', caller: curator, tools: { allow: [] } })
|
|
126
|
-
await new Promise(resolve => setTimeout(resolve, 30))
|
|
127
|
-
propose(h.env, curator, { kind: 'fact', title: 'Curator claim', body: 'A claim from the review.', confidence: 'high', sourceRefs: [{ kind: 'run', ref: 'current', excerpt: 'Prefer pnpm for all builds.' }] })
|
|
128
|
-
const own = h.maintenance.jobs().find(job => job.input.kind === 'proposal')!
|
|
129
|
-
expect(h.maintenance.applyJob(curator, own.id, undefined, 'Check the original evidence.').status).toBe('needs_user')
|
|
130
|
-
expect(() => findMemory(wikiDir(h.env.root), 'curator-claim')).toThrow()
|
|
131
|
-
const review = enqueueCuration(h.env.root, { kind: 'review', requestId: 'grounded-review' })
|
|
132
|
-
const applied = h.maintenance.applyJob(curator, review.id, { memories: [{ title: 'Original preference', kind: 'preference', body: 'Prefer pnpm.', confidence: 'high', sourceRefs: [{ kind: 'run', ref: 'origin', excerpt: 'Prefer pnpm for all builds.' }] }] }, 'Retain the original recorded preference.')
|
|
133
|
-
expect(applied.status).toBe('completed')
|
|
134
|
-
expect(findMemory(wikiDir(h.env.root), 'original-preference').front.sourceIds).toContain('run:origin')
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
test('a failed evidence preparation remains attributed and can be rejected without rereading invalid input', () => {
|
|
139
|
-
const h = setup()
|
|
140
|
-
const job = enqueueCuration(h.env.root, { kind: 'consolidate', blockIds: ['missing-block'] })
|
|
141
|
-
expect(() => h.maintenance.readJob(curator, job.id)).toThrow('No writable blocks')
|
|
142
|
-
expect(h.maintenance.jobs().find(item => item.id === job.id)).toMatchObject({ status: 'failed', runId: 'review' })
|
|
143
|
-
expect(h.maintenance.decide(curator, job.id, 'reject', 'The target no longer exists.').status).toBe('rejected')
|
|
144
|
-
})
|
|
145
|
-
|
|
146
|
-
test('a propose-only caller writes no memory directly, not even its own persona and notes', () => {
|
|
147
|
-
const h = setup()
|
|
148
|
-
const proposer = { ...self, vaultAccess: 'propose' as const }
|
|
149
|
-
expect(() => memoryEdit(h.env, proposer, 'memory.append', { block: 'notes', text: 'Working on release notes.' })).toThrow('Memory changes are proposals')
|
|
150
|
-
expect(() => memoryEdit(h.env, proposer, 'memory.append', { block: 'persona', text: 'I am terse.' })).toThrow('Memory changes are proposals')
|
|
151
|
-
expect(propose(h.env, proposer, { kind: 'block', id: 'blocks/agents/nora/notes', title: 'Notes', body: 'Working on release notes.' })).toContain('Submitted proposal')
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
test('with the run trigger off, a settled run queues no consolidation of its own', async () => {
|
|
155
|
-
let emit: (event: unknown) => void = () => undefined
|
|
156
|
-
const session: PiSessionLike = { sessionId: 'quiet', subscribe: listener => { emit = listener as never; return () => undefined }, prompt: async () => { emit({ type: 'message_end', message: { role: 'assistant', content: [{ type: 'text', text: 'Prefer pnpm for all builds.' }] } }) }, sendCustomMessage: async () => undefined, abort: async () => undefined, dispose: () => undefined }
|
|
157
|
-
const h = createHarness({ dataRoot: mkdtempSync(join(tmpdir(), 'curation-data-')), stateDir: mkdtempSync(join(tmpdir(), 'curation-state-')), externalMaintenance: true, maintenanceRunTrigger: false, secrets: memorySecretStore(), sessionFactory: async () => session })
|
|
158
|
-
opened.push(h)
|
|
159
|
-
h.accounts.create('Main', 'apiKey')
|
|
160
|
-
await h.sessions.run({ run: { id: 'quiet-run', sessionId: 'nora' }, cwd: h.env.root, sessionDir: join(h.env.root, 'history'), text: 'Prefer pnpm.', caller: self, tools: { allow: [] } })
|
|
161
|
-
await new Promise(resolve => setTimeout(resolve, 30))
|
|
162
|
-
expect(h.maintenance.jobs().filter(job => job.input.kind === 'run')).toEqual([])
|
|
163
|
-
})
|