@xingular/harness 0.1.6 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +107 -0
- package/LICENSE +202 -0
- package/NOTICE.md +60 -0
- package/README.md +265 -71
- package/THIRD_PARTY_LICENSES.md +942 -0
- package/dist/cli.js +14842 -9445
- 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/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 +17 -0
- package/dist/sdk/browser/index.js +65 -0
- package/dist/sdk/browser/network.d.ts +10 -0
- package/dist/sdk/browser/network.js +59 -0
- package/dist/sdk/browser/session.d.ts +84 -0
- package/dist/sdk/browser/session.js +192 -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 +142 -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/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 +133 -0
- package/dist/sdk/harness.js +299 -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/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/index.d.ts +63 -0
- package/dist/sdk/index.js +48 -0
- package/dist/sdk/mcp/connections.d.ts +83 -0
- package/dist/sdk/mcp/connections.js +669 -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/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 +6 -0
- package/dist/sdk/plugins/builtin.js +68 -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 +187 -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 +174 -0
- package/dist/sdk/prompt/compile.js +396 -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/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 +370 -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 +534 -0
- package/dist/sdk/sessions/contracts.js +299 -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 +36 -0
- package/dist/sdk/sessions/planMode.js +84 -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 +102 -0
- package/dist/sdk/sessions/registry.js +383 -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 +335 -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 +140 -0
- package/dist/sdk/sessions/sessions.js +394 -0
- package/dist/sdk/sessions/subagentService.d.ts +41 -0
- package/dist/sdk/sessions/subagentService.js +247 -0
- package/dist/sdk/sessions/subagents.d.ts +50 -0
- package/dist/sdk/sessions/subagents.js +68 -0
- package/dist/sdk/terminal/accountsMenu.d.ts +46 -0
- package/dist/sdk/terminal/accountsMenu.js +392 -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/control.d.ts +4 -0
- package/dist/sdk/terminal/control.js +25 -0
- package/dist/sdk/terminal/controller.d.ts +72 -0
- package/dist/sdk/terminal/controller.js +351 -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/piExtension.d.ts +6 -0
- package/dist/sdk/terminal/piExtension.js +392 -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 +70 -0
- package/dist/sdk/terminal/socket.js +256 -0
- package/dist/sdk/terminal/standalone.d.ts +18 -0
- package/dist/sdk/terminal/standalone.js +146 -0
- package/dist/sdk/terminal/terminals.d.ts +176 -0
- package/dist/sdk/terminal/terminals.js +767 -0
- package/dist/sdk/terminal/trajectory.d.ts +10 -0
- package/dist/sdk/terminal/trajectory.js +30 -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 +7 -0
- package/dist/sdk/terminal/tui/commandPages.js +63 -0
- package/dist/sdk/terminal/tui/commands.d.ts +42 -0
- package/dist/sdk/terminal/tui/commands.js +276 -0
- package/dist/sdk/terminal/tui/dialogGeometry.d.ts +27 -0
- package/dist/sdk/terminal/tui/dialogGeometry.js +50 -0
- package/dist/sdk/terminal/tui/dialogs.d.ts +75 -0
- package/dist/sdk/terminal/tui/dialogs.js +363 -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 +155 -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 +14 -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 +145 -0
- package/dist/sdk/terminal/tui/pages/accountsPage.d.ts +54 -0
- package/dist/sdk/terminal/tui/pages/accountsPage.js +181 -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 +37 -0
- package/dist/sdk/terminal/tui/pages/doctorPage.js +145 -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/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 +55 -0
- package/dist/sdk/terminal/tui/pages/settingsPage.js +88 -0
- package/dist/sdk/terminal/tui/pages/trajectoryPage.d.ts +58 -0
- package/dist/sdk/terminal/tui/pages/trajectoryPage.js +377 -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/questionPicker.d.ts +20 -0
- package/dist/sdk/terminal/tui/questionPicker.js +150 -0
- package/dist/sdk/terminal/tui/questions.d.ts +19 -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 +441 -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 +12 -0
- package/dist/sdk/terminal/tui/settingsModel.js +84 -0
- package/dist/sdk/terminal/tui/sideQuestion.d.ts +53 -0
- package/dist/sdk/terminal/tui/sideQuestion.js +197 -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 +47 -0
- package/dist/sdk/terminal/tui/ui.js +148 -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 +74 -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 +6 -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 +49 -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/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/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/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 +65 -0
- package/dist/sdk/world/world.js +80 -0
- package/dist/terminal-opentui.js +13612 -0
- package/dist/terminal-pi.js +1170 -62
- package/docs/README.md +34 -0
- package/docs/architecture/00-overview.md +159 -0
- package/docs/architecture/01-extension-points.md +78 -0
- package/docs/architecture/02-sessions-and-runs.md +146 -0
- package/docs/architecture/03-variants.md +95 -0
- package/docs/architecture/04-prompt.md +102 -0
- package/docs/architecture/05-refinement.md +107 -0
- package/docs/architecture/06-plugins-and-capabilities.md +93 -0
- package/docs/architecture/07-tools-and-gate.md +88 -0
- package/docs/architecture/08-memory-and-history.md +94 -0
- package/docs/architecture/09-accounts-and-connectors.md +90 -0
- package/docs/architecture/10-server-protocol.md +84 -0
- package/docs/architecture/11-terminal.md +81 -0
- package/docs/architecture/12-storage.md +61 -0
- package/docs/architecture/13-world-tools.md +23 -0
- package/docs/architecture/README.md +114 -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 +68 -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/README.md +76 -0
- package/docs/decisions/ADR-0001-owned-terminal.md +87 -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 +38 -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 +21 -0
- package/docs/doctor.md +74 -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 +20 -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/releases/1.0.0.md +40 -0
- package/docs/releases/README.md +36 -0
- package/docs/study/00-index.md +78 -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/btw-comparison.md +37 -0
- package/docs/study/feature-gap-review.md +42 -0
- package/docs/study/insights.md +123 -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/system-prompt-design.md +196 -0
- package/docs/terminal-tui.md +671 -0
- package/package.json +48 -12
- package/src/accounts/accounts.test.ts +0 -223
- package/src/accounts/accounts.ts +0 -522
- 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 -114
- 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 -299
- package/src/index.ts +0 -70
- 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 -289
- package/src/memory/blocks.test.ts +0 -78
- package/src/memory/blocks.ts +0 -406
- package/src/memory/caller.ts +0 -57
- 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 -330
- package/src/memory/migrate.ts +0 -79
- package/src/memory/operations.ts +0 -138
- package/src/memory/proposals.test.ts +0 -168
- package/src/memory/proposals.ts +0 -576
- package/src/memory/recall.test.ts +0 -104
- package/src/memory/recall.ts +0 -271
- 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 -314
- 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 -310
- package/src/sessions/conversation.test.ts +0 -150
- 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 -32
- package/src/sessions/pricing.ts +0 -60
- package/src/sessions/reasoningSummaries.ts +0 -59
- package/src/sessions/registry.ts +0 -294
- 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 -569
- package/src/sessions/runtimeResources.test.ts +0 -61
- package/src/sessions/sessions.test.ts +0 -455
- package/src/sessions/sessions.ts +0 -295
- package/src/skills/registry.test.ts +0 -104
- package/src/skills/registry.ts +0 -407
- package/src/terminal/cli.ts +0 -149
- package/src/terminal/client.ts +0 -74
- package/src/terminal/controller.ts +0 -227
- package/src/terminal/launch.test.ts +0 -34
- package/src/terminal/launch.ts +0 -88
- package/src/terminal/piExtension.ts +0 -210
- 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 -221
- package/src/terminal/standalone.test.ts +0 -130
- package/src/terminal/standalone.ts +0 -144
- package/src/terminal/terminal.test.ts +0 -330
- package/src/terminal/terminals.ts +0 -443
- package/src/tools/askUser.ts +0 -45
- package/src/tools/definitions.ts +0 -187
- package/src/tools/memoryTools.ts +0 -22
- package/src/tools/pluginPropose.ts +0 -41
- 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,23 @@
|
|
|
1
|
+
import { type Effort } from "../core/effort.js";
|
|
2
|
+
export interface ModeChoice {
|
|
3
|
+
/** `provider/id` of the model. */
|
|
4
|
+
model?: string;
|
|
5
|
+
effort?: Effort;
|
|
6
|
+
updatedAt: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ChoicePatch {
|
|
9
|
+
model?: string;
|
|
10
|
+
effort?: Effort;
|
|
11
|
+
}
|
|
12
|
+
/** Every saved mode of the account. A missing or unreadable file, and any invalid entry, reads as nothing. */
|
|
13
|
+
export declare function readChoices(dir: string, accountId: string): Record<string, ModeChoice>;
|
|
14
|
+
/** Records one or both fields for a mode, keeping the field the patch does not name. */
|
|
15
|
+
export declare function saveChoice(dir: string, accountId: string, mode: string, patch: ChoicePatch): Record<string, ModeChoice>;
|
|
16
|
+
/**
|
|
17
|
+
* The model and effort a mode starts from: its own saved field, else the fallback mode's. The
|
|
18
|
+
* fallback itself has no further fallback.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveChoice(modes: Record<string, ModeChoice>, mode: string, fallback?: string): {
|
|
21
|
+
model?: string;
|
|
22
|
+
effort?: Effort;
|
|
23
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// The model and effort each mode last used on an account. One file per account, in the account's
|
|
2
|
+
// own folder, so removing the account removes its choices. It never holds credentials.
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { EFFORTS } from "../core/effort.js";
|
|
5
|
+
import { invalid } from "../core/errors.js";
|
|
6
|
+
import { now, readJsonOr, safeId, writeJson } from "../core/fs.js";
|
|
7
|
+
const MODE = /^[a-z][a-z0-9_-]{0,31}$/;
|
|
8
|
+
const MODEL = /^[^\s/]+\/\S+$/;
|
|
9
|
+
const MAX_MODEL = 200;
|
|
10
|
+
const choicesPath = (dir, accountId) => join(dir, safeId(accountId), 'choices.json');
|
|
11
|
+
const validModel = (model) => model.length <= MAX_MODEL && MODEL.test(model);
|
|
12
|
+
const validEffort = (effort) => typeof effort === 'string' && EFFORTS.includes(effort);
|
|
13
|
+
function validChoice(entry) {
|
|
14
|
+
const model = typeof entry.model === 'string' && validModel(entry.model) ? entry.model : undefined;
|
|
15
|
+
const effort = validEffort(entry.effort) ? entry.effort : undefined;
|
|
16
|
+
if (!model && !effort)
|
|
17
|
+
return null;
|
|
18
|
+
return { ...(model ? { model } : {}), ...(effort ? { effort } : {}), updatedAt: typeof entry.updatedAt === 'string' ? entry.updatedAt : now() };
|
|
19
|
+
}
|
|
20
|
+
/** Every saved mode of the account. A missing or unreadable file, and any invalid entry, reads as nothing. */
|
|
21
|
+
export function readChoices(dir, accountId) {
|
|
22
|
+
const stored = readJsonOr(choicesPath(dir, accountId), null);
|
|
23
|
+
const modes = {};
|
|
24
|
+
for (const [mode, entry] of Object.entries(stored?.modes ?? {})) {
|
|
25
|
+
if (!MODE.test(mode) || !entry || typeof entry !== 'object')
|
|
26
|
+
continue;
|
|
27
|
+
const choice = validChoice(entry);
|
|
28
|
+
if (choice)
|
|
29
|
+
modes[mode] = choice;
|
|
30
|
+
}
|
|
31
|
+
return modes;
|
|
32
|
+
}
|
|
33
|
+
/** Records one or both fields for a mode, keeping the field the patch does not name. */
|
|
34
|
+
export function saveChoice(dir, accountId, mode, patch) {
|
|
35
|
+
if (!MODE.test(mode))
|
|
36
|
+
throw invalid('A mode is lowercase letters, digits, - or _, starting with a letter.');
|
|
37
|
+
if (patch.model !== undefined && (typeof patch.model !== 'string' || !validModel(patch.model)))
|
|
38
|
+
throw invalid('A model is provider/id.');
|
|
39
|
+
if (patch.effort !== undefined && !validEffort(patch.effort))
|
|
40
|
+
throw invalid(`An effort is one of ${EFFORTS.join(', ')}.`);
|
|
41
|
+
const modes = readChoices(dir, accountId);
|
|
42
|
+
const current = modes[mode] ?? {};
|
|
43
|
+
const next = validChoice({
|
|
44
|
+
...(patch.model !== undefined ? { model: patch.model } : { model: current.model }),
|
|
45
|
+
...(patch.effort !== undefined ? { effort: patch.effort } : { effort: current.effort }),
|
|
46
|
+
updatedAt: now()
|
|
47
|
+
});
|
|
48
|
+
if (!next)
|
|
49
|
+
throw invalid('Choose a model or an effort.');
|
|
50
|
+
modes[mode] = next;
|
|
51
|
+
writeJson(choicesPath(dir, accountId), { modes });
|
|
52
|
+
return modes;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The model and effort a mode starts from: its own saved field, else the fallback mode's. The
|
|
56
|
+
* fallback itself has no further fallback.
|
|
57
|
+
*/
|
|
58
|
+
export function resolveChoice(modes, mode, fallback = 'normal') {
|
|
59
|
+
const own = modes[mode] ?? {};
|
|
60
|
+
const base = mode === fallback ? {} : modes[fallback] ?? {};
|
|
61
|
+
return { model: own.model ?? base.model, effort: own.effort ?? base.effort };
|
|
62
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { Account } from "./store.js";
|
|
2
|
+
/** Inherited variables that carry credentials; they would bypass the account's own sign-in. */
|
|
3
|
+
export declare function isCredentialVar(name: string): boolean;
|
|
4
|
+
/** Names of inherited variables to remove from a session's process. */
|
|
5
|
+
export declare function inheritedCredentialVars(env?: NodeJS.ProcessEnv): string[];
|
|
6
|
+
/**
|
|
7
|
+
* Makes this process safe to run Pi sessions in: credentials come only from an account's own
|
|
8
|
+
* store, so inherited credential variables are dropped, and Pi's fallback agent folder is an
|
|
9
|
+
* empty one under the state directory rather than `~/.pi`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function isolateProcess(accountsDir: string, env?: NodeJS.ProcessEnv): void;
|
|
12
|
+
export declare const homeDir: (accountsDir: string, accountId: string) => string;
|
|
13
|
+
/** Pi's agent folder for this account. */
|
|
14
|
+
export declare const configDir: (accountsDir: string, account: Pick<Account, "id">) => string;
|
|
15
|
+
/** The agent-folder entries every account shares. */
|
|
16
|
+
export declare const sharedDir: (accountsDir: string) => string;
|
|
17
|
+
export interface NativeConfig {
|
|
18
|
+
provider: string;
|
|
19
|
+
path: string;
|
|
20
|
+
entries: {
|
|
21
|
+
name: string;
|
|
22
|
+
directory: boolean;
|
|
23
|
+
present: boolean;
|
|
24
|
+
}[];
|
|
25
|
+
}
|
|
26
|
+
/** What the accounts share, and which of it exists yet. Reads only; nothing is created. */
|
|
27
|
+
export declare function nativeConfig(accountsDir: string): NativeConfig;
|
|
28
|
+
/** The shared folder, created private if no account has linked it yet. */
|
|
29
|
+
export declare function ensureSharedDir(accountsDir: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* How one shared entry is linked into an account folder. Windows refuses a symbolic link to a
|
|
32
|
+
* user without the symlink privilege, so each kind has a fallback that needs none.
|
|
33
|
+
*/
|
|
34
|
+
export interface EntryLinker {
|
|
35
|
+
/** A symbolic link to a file, or a junction to a folder (junctions need no privilege on Windows). */
|
|
36
|
+
symlink(target: string, path: string, isDir: boolean): void;
|
|
37
|
+
/** A hard link to a file on the same volume. */
|
|
38
|
+
hardLink(target: string, path: string): void;
|
|
39
|
+
}
|
|
40
|
+
/** What happened to one shared entry: linked to the shared copy, or left as the account's own. */
|
|
41
|
+
export interface SharedEntry {
|
|
42
|
+
name: string;
|
|
43
|
+
state: 'linked' | 'unshared';
|
|
44
|
+
/** Why the link was refused, when it was. */
|
|
45
|
+
reason?: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Creates the account's runtime folder and links the shared entries into it. Never throws for a
|
|
49
|
+
* refused link: each entry is reported, and the account falls back to its own copy.
|
|
50
|
+
*/
|
|
51
|
+
export declare function linkSharedEntries(accountsDir: string, account: Pick<Account, 'id'>, linker?: EntryLinker): {
|
|
52
|
+
dir: string;
|
|
53
|
+
entries: SharedEntry[];
|
|
54
|
+
};
|
|
55
|
+
/** Creates the account's runtime folder and links the shared entries into it. */
|
|
56
|
+
export declare function ensureHome(accountsDir: string, account: Pick<Account, 'id'>): string;
|
|
57
|
+
/**
|
|
58
|
+
* Refuses an agent folder that is (or is inside) a default tool folder, or that is not inside
|
|
59
|
+
* the harness's own accounts folder.
|
|
60
|
+
*/
|
|
61
|
+
export declare function assertIsolated(accountsDir: string, dir: string): void;
|
|
62
|
+
/** Variables to set, or remove (`null`), when launching a session for this account. */
|
|
63
|
+
export declare function launchEnv(accountsDir: string, account: Pick<Account, 'id'>, inherited?: NodeJS.ProcessEnv): Record<string, string | null>;
|
|
64
|
+
/** What a session needs to run for an account. */
|
|
65
|
+
export interface AccountContext {
|
|
66
|
+
id: string;
|
|
67
|
+
provider: 'pi';
|
|
68
|
+
label: string;
|
|
69
|
+
/** Variables to set; `null` removes an inherited one. */
|
|
70
|
+
env: Record<string, string | null>;
|
|
71
|
+
/** The account's own agent folder. */
|
|
72
|
+
configDir: string;
|
|
73
|
+
/** Which shared entries are linked, and which the account keeps as its own. */
|
|
74
|
+
sharing: SharedEntry[];
|
|
75
|
+
}
|
|
76
|
+
export declare function accountContext(accountsDir: string, account: Account): AccountContext;
|
|
77
|
+
/** The process environment for a `pi` process launched on behalf of this account. */
|
|
78
|
+
export declare function processEnv(account: AccountContext, inherited?: NodeJS.ProcessEnv): Record<string, string>;
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
// Isolated launch environments. Every Pi session the harness starts gets its account's own
|
|
2
|
+
// agent folder (`PI_CODING_AGENT_DIR`) under the state directory, and inherited credential
|
|
3
|
+
// variables are removed. A launch that would fall back to `~/.pi` is refused.
|
|
4
|
+
//
|
|
5
|
+
// Settings, skills, prompts, and instructions are shared by every account: the account's agent
|
|
6
|
+
// folder links those entries to `_shared/pi/`. Where the system refuses a link (Windows without
|
|
7
|
+
// the symlink privilege), the entry stays the account's own, and a shared file is copied in so
|
|
8
|
+
// its settings still load. Credentials, sessions, and history stay in the account's own folder.
|
|
9
|
+
import { chmodSync, copyFileSync, linkSync, lstatSync, mkdirSync, readlinkSync, renameSync, rmdirSync, statSync, symlinkSync, unlinkSync, utimesSync } from 'node:fs';
|
|
10
|
+
import { homedir } from 'node:os';
|
|
11
|
+
import { basename, dirname, join, resolve, sep } from 'node:path';
|
|
12
|
+
import { HarnessError } from "../core/errors.js";
|
|
13
|
+
// Config-directory variables the harness always sets itself, including those of other tools so
|
|
14
|
+
// a session can never inherit them.
|
|
15
|
+
const DIR_VARS = ['CODEX_HOME', 'CLAUDE_CONFIG_DIR', 'PI_CODING_AGENT_DIR'];
|
|
16
|
+
/** Inherited variables that carry credentials; they would bypass the account's own sign-in. */
|
|
17
|
+
export function isCredentialVar(name) {
|
|
18
|
+
const upper = name.toUpperCase();
|
|
19
|
+
return DIR_VARS.includes(upper) || ['_API_KEY', '_AUTH_TOKEN', '_OAUTH_TOKEN', '_ACCESS_TOKEN'].some((suffix) => upper.endsWith(suffix));
|
|
20
|
+
}
|
|
21
|
+
/** Names of inherited variables to remove from a session's process. */
|
|
22
|
+
export function inheritedCredentialVars(env = process.env) {
|
|
23
|
+
const names = Object.keys(env).filter(isCredentialVar);
|
|
24
|
+
for (const name of DIR_VARS)
|
|
25
|
+
if (!names.includes(name))
|
|
26
|
+
names.push(name);
|
|
27
|
+
return names;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Makes this process safe to run Pi sessions in: credentials come only from an account's own
|
|
31
|
+
* store, so inherited credential variables are dropped, and Pi's fallback agent folder is an
|
|
32
|
+
* empty one under the state directory rather than `~/.pi`.
|
|
33
|
+
*/
|
|
34
|
+
export function isolateProcess(accountsDir, env = process.env) {
|
|
35
|
+
for (const name of inheritedCredentialVars(env))
|
|
36
|
+
delete env[name];
|
|
37
|
+
const fallback = join(accountsDir, '.sidecar', 'pi');
|
|
38
|
+
mkdirSync(fallback, { recursive: true });
|
|
39
|
+
env.PI_CODING_AGENT_DIR = fallback;
|
|
40
|
+
}
|
|
41
|
+
export const homeDir = (accountsDir, accountId) => join(accountsDir, accountId, 'home');
|
|
42
|
+
/** Pi's agent folder for this account. */
|
|
43
|
+
export const configDir = (accountsDir, account) => join(homeDir(accountsDir, account.id), 'pi');
|
|
44
|
+
/** The agent-folder entries every account shares. */
|
|
45
|
+
export const sharedDir = (accountsDir) => join(accountsDir, '_shared', 'pi');
|
|
46
|
+
function makePrivate(path) {
|
|
47
|
+
mkdirSync(path, { recursive: true });
|
|
48
|
+
chmodSync(path, 0o700);
|
|
49
|
+
}
|
|
50
|
+
// Entries every account shares, and whether each is a folder. Credentials (`auth.json`),
|
|
51
|
+
// sessions, and history are never listed.
|
|
52
|
+
const SHARED_ENTRIES = [
|
|
53
|
+
['settings.json', false],
|
|
54
|
+
['models.json', false],
|
|
55
|
+
['AGENTS.md', false],
|
|
56
|
+
['SYSTEM.md', false],
|
|
57
|
+
['skills', true],
|
|
58
|
+
['prompts', true],
|
|
59
|
+
['extensions', true],
|
|
60
|
+
['themes', true],
|
|
61
|
+
// Where Pi keeps installed packages: one install serves every account.
|
|
62
|
+
['npm', true],
|
|
63
|
+
['git', true]
|
|
64
|
+
];
|
|
65
|
+
const present = (path) => {
|
|
66
|
+
try {
|
|
67
|
+
lstatSync(path);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
/** What the accounts share, and which of it exists yet. Reads only; nothing is created. */
|
|
75
|
+
export function nativeConfig(accountsDir) {
|
|
76
|
+
const shared = sharedDir(accountsDir);
|
|
77
|
+
return { provider: 'pi', path: shared, entries: SHARED_ENTRIES.map(([name, directory]) => ({ name, directory, present: present(join(shared, name)) })) };
|
|
78
|
+
}
|
|
79
|
+
/** The shared folder, created private if no account has linked it yet. */
|
|
80
|
+
export function ensureSharedDir(accountsDir) {
|
|
81
|
+
const shared = sharedDir(accountsDir);
|
|
82
|
+
makePrivate(shared);
|
|
83
|
+
return shared;
|
|
84
|
+
}
|
|
85
|
+
const modified = (path) => {
|
|
86
|
+
try {
|
|
87
|
+
return lstatSync(path).mtimeMs;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return -1;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
/** Moves a real file or folder aside so the shared link can take its place; returns where it went. */
|
|
94
|
+
function backUp(path) {
|
|
95
|
+
const backup = join(dirname(path), `${basename(path)}.xagent-backup-${Math.floor(Date.now() / 1000)}`);
|
|
96
|
+
renameSync(path, backup);
|
|
97
|
+
return backup;
|
|
98
|
+
}
|
|
99
|
+
const nodeLinker = {
|
|
100
|
+
symlink: (target, path, isDir) => symlinkSync(resolve(target), path, isDir ? 'junction' : 'file'),
|
|
101
|
+
hardLink: (target, path) => linkSync(target, path)
|
|
102
|
+
};
|
|
103
|
+
const codeOf = (error) => error.code ?? String(error);
|
|
104
|
+
const PRIVILEGE_CODES = ['EPERM', 'EACCES'];
|
|
105
|
+
function createLink(target, path, isDir, linker) {
|
|
106
|
+
try {
|
|
107
|
+
linker.symlink(target, path, isDir);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
// A file can still be hard-linked without the privilege; a folder has no such fallback.
|
|
111
|
+
if (isDir || !PRIVILEGE_CODES.includes(codeOf(error)))
|
|
112
|
+
throw error;
|
|
113
|
+
linker.hardLink(target, path);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const isLink = (path) => {
|
|
117
|
+
try {
|
|
118
|
+
return lstatSync(path).isSymbolicLink();
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
// Windows reports some link targets with the `\\?\` prefix.
|
|
125
|
+
const LONG_PREFIX = /^\\\\\?\\/;
|
|
126
|
+
function samePath(a, b) {
|
|
127
|
+
const normal = (path) => {
|
|
128
|
+
const full = resolve(path.replace(LONG_PREFIX, ''));
|
|
129
|
+
return process.platform === 'win32' ? full.toLowerCase() : full;
|
|
130
|
+
};
|
|
131
|
+
return normal(a) === normal(b);
|
|
132
|
+
}
|
|
133
|
+
/** A hard link is the same file on disk as its target, so it has the same device and inode. */
|
|
134
|
+
function sameFile(a, b) {
|
|
135
|
+
try {
|
|
136
|
+
const left = lstatSync(a);
|
|
137
|
+
const right = lstatSync(b);
|
|
138
|
+
return left.ino !== 0 && left.dev === right.dev && left.ino === right.ino;
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function isLinkTo(path, target, isDir) {
|
|
145
|
+
try {
|
|
146
|
+
const meta = lstatSync(path);
|
|
147
|
+
if (meta.isSymbolicLink())
|
|
148
|
+
return samePath(readlinkSync(path), target);
|
|
149
|
+
return !isDir && meta.isFile() && sameFile(path, target);
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/** Removes a link without touching what it points to. A Windows junction needs `rmdir`. */
|
|
156
|
+
function removeLink(path, isDir) {
|
|
157
|
+
try {
|
|
158
|
+
unlinkSync(path);
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
if (!isDir)
|
|
162
|
+
throw error;
|
|
163
|
+
rmdirSync(path);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* A file the account does not have, for an entry whose link was refused: a copy of the shared one
|
|
168
|
+
* (with its time kept, so the newest-wins rule does not move it), so the account's settings load.
|
|
169
|
+
*/
|
|
170
|
+
function keepCopy(target, path, isDir) {
|
|
171
|
+
if (isDir || present(path) || !present(target))
|
|
172
|
+
return;
|
|
173
|
+
try {
|
|
174
|
+
copyFileSync(target, path);
|
|
175
|
+
const { atime, mtime } = statSync(target);
|
|
176
|
+
utimesSync(path, atime, mtime);
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
// The account simply keeps no copy; its sign-in and its own files are not affected.
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Links one entry to its shared copy. A real entry found in the account folder (from before
|
|
184
|
+
* sharing, or a tool that replaced the link while saving) becomes the shared copy when there is
|
|
185
|
+
* none or it is newer; otherwise it is kept as a backup. If the link is then refused, every move
|
|
186
|
+
* is undone, so the account keeps what it had.
|
|
187
|
+
*/
|
|
188
|
+
function linkOne(name, target, path, isDir, linker) {
|
|
189
|
+
if (isLinkTo(path, target, isDir)) {
|
|
190
|
+
if (isDir)
|
|
191
|
+
mkdirSync(target, { recursive: true });
|
|
192
|
+
return { name, state: 'linked' };
|
|
193
|
+
}
|
|
194
|
+
const undo = [];
|
|
195
|
+
try {
|
|
196
|
+
if (isLink(path)) {
|
|
197
|
+
const previous = readlinkSync(path);
|
|
198
|
+
removeLink(path, isDir);
|
|
199
|
+
undo.push(() => nodeLinker.symlink(previous, path, isDir));
|
|
200
|
+
}
|
|
201
|
+
else if (present(path)) {
|
|
202
|
+
if (!present(target)) {
|
|
203
|
+
renameSync(path, target);
|
|
204
|
+
undo.push(() => renameSync(target, path));
|
|
205
|
+
}
|
|
206
|
+
else if (!isDir && modified(path) > modified(target)) {
|
|
207
|
+
const backup = backUp(target);
|
|
208
|
+
undo.push(() => renameSync(backup, target));
|
|
209
|
+
renameSync(path, target);
|
|
210
|
+
undo.push(() => renameSync(target, path));
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
const backup = backUp(path);
|
|
214
|
+
undo.push(() => renameSync(backup, path));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (isDir)
|
|
218
|
+
mkdirSync(target, { recursive: true });
|
|
219
|
+
createLink(target, path, isDir, linker);
|
|
220
|
+
return { name, state: 'linked' };
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
for (const step of undo.reverse()) {
|
|
224
|
+
try {
|
|
225
|
+
step();
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
// The entry stays where that step left it; nothing further can be restored safely.
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
keepCopy(target, path, isDir);
|
|
232
|
+
return { name, state: 'unshared', reason: codeOf(error) };
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Creates the account's runtime folder and links the shared entries into it. Never throws for a
|
|
237
|
+
* refused link: each entry is reported, and the account falls back to its own copy.
|
|
238
|
+
*/
|
|
239
|
+
export function linkSharedEntries(accountsDir, account, linker = nodeLinker) {
|
|
240
|
+
makePrivate(join(accountsDir, account.id));
|
|
241
|
+
makePrivate(homeDir(accountsDir, account.id));
|
|
242
|
+
const dir = configDir(accountsDir, account);
|
|
243
|
+
makePrivate(dir);
|
|
244
|
+
const shared = ensureSharedDir(accountsDir);
|
|
245
|
+
const entries = SHARED_ENTRIES.map(([name, isDir]) => linkOne(name, join(shared, name), join(dir, name), isDir, linker));
|
|
246
|
+
return { dir, entries };
|
|
247
|
+
}
|
|
248
|
+
/** Creates the account's runtime folder and links the shared entries into it. */
|
|
249
|
+
export function ensureHome(accountsDir, account) {
|
|
250
|
+
return linkSharedEntries(accountsDir, account).dir;
|
|
251
|
+
}
|
|
252
|
+
const inside = (path, parent) => path === parent || path.startsWith(parent.endsWith(sep) ? parent : `${parent}${sep}`);
|
|
253
|
+
/**
|
|
254
|
+
* Refuses an agent folder that is (or is inside) a default tool folder, or that is not inside
|
|
255
|
+
* the harness's own accounts folder.
|
|
256
|
+
*/
|
|
257
|
+
export function assertIsolated(accountsDir, dir) {
|
|
258
|
+
const defaults = ['.codex', '.claude', '.pi'].map((name) => join(homedir() || '/', name));
|
|
259
|
+
if (defaults.some((folder) => inside(dir, folder)) || !inside(dir, accountsDir)) {
|
|
260
|
+
throw new HarnessError('account_required', 'A session cannot start outside its isolated account folder.');
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
function sessionEnv(dir, inherited) {
|
|
264
|
+
const env = {};
|
|
265
|
+
for (const name of inheritedCredentialVars(inherited))
|
|
266
|
+
env[name] = null;
|
|
267
|
+
env.PI_CODING_AGENT_DIR = dir;
|
|
268
|
+
return env;
|
|
269
|
+
}
|
|
270
|
+
/** Variables to set, or remove (`null`), when launching a session for this account. */
|
|
271
|
+
export function launchEnv(accountsDir, account, inherited = process.env) {
|
|
272
|
+
const dir = ensureHome(accountsDir, account);
|
|
273
|
+
assertIsolated(accountsDir, dir);
|
|
274
|
+
return sessionEnv(dir, inherited);
|
|
275
|
+
}
|
|
276
|
+
export function accountContext(accountsDir, account) {
|
|
277
|
+
const { dir, entries } = linkSharedEntries(accountsDir, account);
|
|
278
|
+
assertIsolated(accountsDir, dir);
|
|
279
|
+
return { id: account.id, provider: 'pi', label: account.label, env: sessionEnv(dir, process.env), configDir: dir, sharing: entries };
|
|
280
|
+
}
|
|
281
|
+
/** The process environment for a `pi` process launched on behalf of this account. */
|
|
282
|
+
export function processEnv(account, inherited = process.env) {
|
|
283
|
+
const env = {};
|
|
284
|
+
for (const [name, value] of Object.entries(inherited))
|
|
285
|
+
if (value !== undefined)
|
|
286
|
+
env[name] = value;
|
|
287
|
+
for (const [name, value] of Object.entries(account.env)) {
|
|
288
|
+
if (value === null)
|
|
289
|
+
delete env[name];
|
|
290
|
+
else
|
|
291
|
+
env[name] = value;
|
|
292
|
+
}
|
|
293
|
+
return env;
|
|
294
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface SecretStore {
|
|
2
|
+
get(key: string): Promise<string | null>;
|
|
3
|
+
set(key: string, value: string): Promise<void>;
|
|
4
|
+
delete(key: string): Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
/** `<account id>/<secret name>`: the key an account's secret is stored under. */
|
|
7
|
+
export declare const secretKey: (accountId: string, name: string) => string;
|
|
8
|
+
/** Secrets held only for the life of the process. For tests and throwaway runs. */
|
|
9
|
+
export declare function memorySecretStore(initial?: Record<string, string>): SecretStore & {
|
|
10
|
+
values: Map<string, string>;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Secrets in one owner-only JSON file. For a host with no Keychain to offer; anything that can
|
|
14
|
+
* read the file can read every secret in it.
|
|
15
|
+
*/
|
|
16
|
+
export declare function fileSecretStore(path: string): SecretStore;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Where credentials live. The harness never writes a secret to its own files: it asks the
|
|
2
|
+
// store the embedding application provides (a Keychain, an encrypted vault), by key.
|
|
3
|
+
import { chmodSync, mkdirSync } from 'node:fs';
|
|
4
|
+
import { dirname } from 'node:path';
|
|
5
|
+
import { atomicWrite, readJsonOr } from "../core/fs.js";
|
|
6
|
+
/** `<account id>/<secret name>`: the key an account's secret is stored under. */
|
|
7
|
+
export const secretKey = (accountId, name) => `${accountId}/${name}`;
|
|
8
|
+
/** Secrets held only for the life of the process. For tests and throwaway runs. */
|
|
9
|
+
export function memorySecretStore(initial = {}) {
|
|
10
|
+
const values = new Map(Object.entries(initial));
|
|
11
|
+
return {
|
|
12
|
+
values,
|
|
13
|
+
get: async (key) => values.get(key) ?? null,
|
|
14
|
+
set: async (key, value) => void values.set(key, value),
|
|
15
|
+
delete: async (key) => void values.delete(key)
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Secrets in one owner-only JSON file. For a host with no Keychain to offer; anything that can
|
|
20
|
+
* read the file can read every secret in it.
|
|
21
|
+
*/
|
|
22
|
+
export function fileSecretStore(path) {
|
|
23
|
+
const read = () => readJsonOr(path, {});
|
|
24
|
+
const write = (values) => {
|
|
25
|
+
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
|
26
|
+
atomicWrite(path, `${JSON.stringify(values, null, 2)}\n`);
|
|
27
|
+
chmodSync(path, 0o600);
|
|
28
|
+
};
|
|
29
|
+
return {
|
|
30
|
+
get: async (key) => read()[key] ?? null,
|
|
31
|
+
set: async (key, value) => write({ ...read(), [key]: value }),
|
|
32
|
+
delete: async (key) => {
|
|
33
|
+
const values = read();
|
|
34
|
+
if (key in values) {
|
|
35
|
+
delete values[key];
|
|
36
|
+
write(values);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/** The only provider the harness runs. Records of other providers are kept in the file and ignored. */
|
|
2
|
+
export declare const PROVIDER = "pi";
|
|
3
|
+
export interface Account {
|
|
4
|
+
id: string;
|
|
5
|
+
provider: string;
|
|
6
|
+
label: string;
|
|
7
|
+
/** `subscription` (a provider's own sign-in) or `apiKey`. */
|
|
8
|
+
authKind: string;
|
|
9
|
+
credentialStore?: string;
|
|
10
|
+
createdAt: string;
|
|
11
|
+
}
|
|
12
|
+
export interface Pool {
|
|
13
|
+
id: string;
|
|
14
|
+
provider: string;
|
|
15
|
+
label: string;
|
|
16
|
+
accountIds: string[];
|
|
17
|
+
}
|
|
18
|
+
interface Registry {
|
|
19
|
+
accounts: Account[];
|
|
20
|
+
defaults: Record<string, string>;
|
|
21
|
+
pools: Pool[];
|
|
22
|
+
migratedProviderKeys: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface Limit {
|
|
25
|
+
id: string;
|
|
26
|
+
label: string;
|
|
27
|
+
usedPercent?: number | null;
|
|
28
|
+
resetsAt?: string | null;
|
|
29
|
+
windowMinutes?: number | null;
|
|
30
|
+
/** `allowed`, `warning`, or `rejected` when the provider reports it. */
|
|
31
|
+
status?: string | null;
|
|
32
|
+
}
|
|
33
|
+
export interface Issue {
|
|
34
|
+
/** `auth_expired`, `rate_limited`, `quota`, `network`, or `unknown`. */
|
|
35
|
+
category: string;
|
|
36
|
+
message: string;
|
|
37
|
+
at: string;
|
|
38
|
+
resetsAt: string | null;
|
|
39
|
+
}
|
|
40
|
+
export interface AccountState {
|
|
41
|
+
/** `ok`, `limited`, `auth_expired`, `signed_out`, `error`, or `unknown`. */
|
|
42
|
+
health: string;
|
|
43
|
+
signedIn: boolean | null;
|
|
44
|
+
authMethod: string | null;
|
|
45
|
+
plan: string | null;
|
|
46
|
+
identity: string | null;
|
|
47
|
+
limits: Limit[];
|
|
48
|
+
lastError: Issue | null;
|
|
49
|
+
lastCheckedAt: string | null;
|
|
50
|
+
cliVersion: string | null;
|
|
51
|
+
/** Features detected for this account, e.g. `models:12`, `provider:anthropic`. */
|
|
52
|
+
capabilities: string[];
|
|
53
|
+
/** Providers with a stored credential (names only). */
|
|
54
|
+
piProviders: string[];
|
|
55
|
+
}
|
|
56
|
+
export declare const emptyState: () => AccountState;
|
|
57
|
+
export type AccountView = Account & {
|
|
58
|
+
isDefault: boolean;
|
|
59
|
+
state: AccountState;
|
|
60
|
+
};
|
|
61
|
+
export interface AccountsOverview {
|
|
62
|
+
accounts: AccountView[];
|
|
63
|
+
pools: Pool[];
|
|
64
|
+
defaults: Record<string, string>;
|
|
65
|
+
}
|
|
66
|
+
export interface AuditEntry {
|
|
67
|
+
at: string;
|
|
68
|
+
accountId: string | null;
|
|
69
|
+
action: string;
|
|
70
|
+
detail: string;
|
|
71
|
+
}
|
|
72
|
+
export declare function loadRegistry(dir: string): Registry;
|
|
73
|
+
export declare function saveRegistry(dir: string, registry: Registry): void;
|
|
74
|
+
export declare function loadState(dir: string, accountId: string): AccountState;
|
|
75
|
+
/** Replaces anything that looks like a token so audit lines and stored errors never hold secrets. */
|
|
76
|
+
export declare function scrub(text: string): string;
|
|
77
|
+
export declare function audit(dir: string, accountId: string | null, action: string, detail: string): void;
|
|
78
|
+
/** The newest audit entries first, optionally for one account. */
|
|
79
|
+
export declare function readAudit(dir: string, accountId?: string | null, limit?: number): AuditEntry[];
|
|
80
|
+
export declare const isLimitCategory: (category: string) => boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Whether a `rate_limited` or `quota` error still counts. With a reset time it counts until
|
|
83
|
+
* then; without one it counts for a short while after it was recorded.
|
|
84
|
+
*/
|
|
85
|
+
export declare function limitErrorActive(issue: Issue): boolean;
|
|
86
|
+
export declare function deriveHealth(state: AccountState): string;
|
|
87
|
+
/** Read-modify-write on one account's state. Returns the previous health and the new state. */
|
|
88
|
+
export declare function updateState(dir: string, accountId: string, change: (state: AccountState) => void): {
|
|
89
|
+
previous: string;
|
|
90
|
+
state: AccountState;
|
|
91
|
+
};
|
|
92
|
+
export declare function find(dir: string, accountId: string): Account;
|
|
93
|
+
/**
|
|
94
|
+
* Chooses the account for a new session: the explicit account, else the pool's first usable
|
|
95
|
+
* account, else the default, else the first account. It never skips to another one silently.
|
|
96
|
+
*/
|
|
97
|
+
export declare function resolve(dir: string, accountId?: string | null, poolId?: string | null): Account;
|
|
98
|
+
/** The default account, if any exists. */
|
|
99
|
+
export declare function defaultAccount(dir: string): Account | null;
|
|
100
|
+
export declare function summaryAuthentication(dir: string): 'authenticated' | 'unauthenticated' | 'unknown';
|
|
101
|
+
export declare function overview(dir: string): AccountsOverview;
|
|
102
|
+
export declare function cleanLabel(label: string): string;
|
|
103
|
+
export declare function addAccount(dir: string, label: string, authKind: string): Account;
|
|
104
|
+
export declare function renameAccount(dir: string, accountId: string, label: string): void;
|
|
105
|
+
export declare function setDefault(dir: string, accountId: string): Account;
|
|
106
|
+
/** Drops the account from the registry, its pools, and the default. Its folder and secrets are the caller's to remove. */
|
|
107
|
+
export declare function forgetAccount(dir: string, account: Account): void;
|
|
108
|
+
export declare function savePool(dir: string, pool: {
|
|
109
|
+
id?: string;
|
|
110
|
+
label: string;
|
|
111
|
+
accountIds: string[];
|
|
112
|
+
}): Pool;
|
|
113
|
+
export declare function removePool(dir: string, poolId: string): void;
|
|
114
|
+
export {};
|