@selesai/code 0.13.0 → 0.13.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 +12 -0
- package/dist/core/agent-session.d.ts +1 -1
- package/dist/core/agent-session.js +1 -1
- package/dist/core/sdk.d.ts +2 -2
- package/dist/core/sdk.js +1 -1
- package/dist/core/system-prompt.d.ts +1 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/extensions/ascii.txt +9 -0
- package/dist/extensions/package.json +1 -2
- package/dist/extensions/pi-hermes-memory/CHANGELOG.md +371 -0
- package/dist/extensions/pi-hermes-memory/LICENSE +21 -0
- package/dist/extensions/pi-hermes-memory/README.md +643 -0
- package/dist/extensions/pi-hermes-memory/docs/0.1/TASKS.md +197 -0
- package/dist/extensions/pi-hermes-memory/docs/0.2/PLAN.md +290 -0
- package/dist/extensions/pi-hermes-memory/docs/0.2/TASKS.md +134 -0
- package/dist/extensions/pi-hermes-memory/docs/0.2/TEST-PLAN.md +216 -0
- package/dist/extensions/pi-hermes-memory/docs/0.3/PLAN.md +330 -0
- package/dist/extensions/pi-hermes-memory/docs/0.3/TASKS.md +125 -0
- package/dist/extensions/pi-hermes-memory/docs/0.4/PLAN.md +160 -0
- package/dist/extensions/pi-hermes-memory/docs/0.4/TASKS.md +113 -0
- package/dist/extensions/pi-hermes-memory/docs/0.6/CHANGELOG.md +57 -0
- package/dist/extensions/pi-hermes-memory/docs/0.6/PLAN.md +202 -0
- package/dist/extensions/pi-hermes-memory/docs/0.6/TASKS.md +144 -0
- package/dist/extensions/pi-hermes-memory/docs/0.7/PLAN.md +349 -0
- package/dist/extensions/pi-hermes-memory/docs/0.7/TASKS.md +110 -0
- package/dist/extensions/pi-hermes-memory/docs/PUBLISHING.md +149 -0
- package/dist/extensions/pi-hermes-memory/docs/ROADMAP.md +468 -0
- package/dist/extensions/pi-hermes-memory/docs/images/memory-architecture.svg +1 -0
- package/dist/extensions/pi-hermes-memory/docs/images/pi-logo.svg +22 -0
- package/dist/extensions/pi-hermes-memory/docs/images/pi_memory.png +0 -0
- package/dist/extensions/pi-hermes-memory/docs/images/pi_memory.svg +19 -0
- package/dist/extensions/pi-hermes-memory/docs/images/security-flow.svg +1 -0
- package/dist/extensions/pi-hermes-memory/docs/images/session-lifecycle.svg +1 -0
- package/dist/extensions/pi-hermes-memory/docs/images/source-architecture.svg +1 -0
- package/dist/extensions/pi-hermes-memory/docs/mermaid/memory-architecture.mmd +49 -0
- package/dist/extensions/pi-hermes-memory/docs/mermaid/security-flow.mmd +40 -0
- package/dist/extensions/pi-hermes-memory/docs/mermaid/session-lifecycle.mmd +56 -0
- package/dist/extensions/pi-hermes-memory/docs/mermaid/source-architecture.mmd +54 -0
- package/dist/extensions/pi-hermes-memory/package-lock.json +3799 -0
- package/dist/extensions/pi-hermes-memory/package.json +66 -0
- package/dist/extensions/pi-hermes-memory/scripts/check-min-sdk.mjs +99 -0
- package/dist/extensions/pi-hermes-memory/scripts/ensure-dev.mjs +57 -0
- package/dist/extensions/pi-hermes-memory/src/auto-consolidation-warning.ts +6 -0
- package/dist/extensions/pi-hermes-memory/src/config.ts +178 -0
- package/dist/extensions/pi-hermes-memory/src/constants.ts +424 -0
- package/dist/extensions/pi-hermes-memory/src/extension-root-migration.ts +639 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/auto-consolidate.ts +401 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +297 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/child-process-watchdog.mjs +90 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/correction-detector.ts +300 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/index-sessions.ts +86 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/insights.ts +78 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/interview.ts +37 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/learn-memory.ts +186 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/message-parts.ts +27 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/pi-child-process.ts +485 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/preview-context.ts +105 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +506 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +145 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/session-flush.ts +151 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/session-live-index.ts +94 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/skills-command.ts +1334 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/standing-pin.ts +111 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/switch-project.ts +75 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +266 -0
- package/dist/extensions/pi-hermes-memory/src/index.ts +378 -0
- package/dist/extensions/pi-hermes-memory/src/lifecycle-timing.ts +54 -0
- package/dist/extensions/pi-hermes-memory/src/paths.ts +61 -0
- package/dist/extensions/pi-hermes-memory/src/project-context.ts +13 -0
- package/dist/extensions/pi-hermes-memory/src/project-memory-migration.ts +93 -0
- package/dist/extensions/pi-hermes-memory/src/project.ts +157 -0
- package/dist/extensions/pi-hermes-memory/src/prompt-context.ts +55 -0
- package/dist/extensions/pi-hermes-memory/src/store/atomic-lock-coordinator.ts +375 -0
- package/dist/extensions/pi-hermes-memory/src/store/canonical-storage-path.ts +54 -0
- package/dist/extensions/pi-hermes-memory/src/store/content-scanner.ts +101 -0
- package/dist/extensions/pi-hermes-memory/src/store/db.ts +1180 -0
- package/dist/extensions/pi-hermes-memory/src/store/fts-query.ts +101 -0
- package/dist/extensions/pi-hermes-memory/src/store/markdown-mutation-lock.ts +38 -0
- package/dist/extensions/pi-hermes-memory/src/store/memory-lookup.ts +24 -0
- package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +1191 -0
- package/dist/extensions/pi-hermes-memory/src/store/recovery-maintenance.ts +66 -0
- package/dist/extensions/pi-hermes-memory/src/store/schema.ts +118 -0
- package/dist/extensions/pi-hermes-memory/src/store/session-anchor-search.ts +472 -0
- package/dist/extensions/pi-hermes-memory/src/store/session-indexer.ts +511 -0
- package/dist/extensions/pi-hermes-memory/src/store/session-parser.ts +213 -0
- package/dist/extensions/pi-hermes-memory/src/store/session-search.ts +234 -0
- package/dist/extensions/pi-hermes-memory/src/store/skill-store.ts +950 -0
- package/dist/extensions/pi-hermes-memory/src/store/skill-utils.ts +133 -0
- package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +1002 -0
- package/dist/extensions/pi-hermes-memory/src/store/sqlite-native.ts +241 -0
- package/dist/extensions/pi-hermes-memory/src/store/standing-instructions.ts +247 -0
- package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +95 -0
- package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +469 -0
- package/dist/extensions/pi-hermes-memory/src/tools/session-search-tool.ts +246 -0
- package/dist/extensions/pi-hermes-memory/src/tools/shared-output-view.ts +170 -0
- package/dist/extensions/pi-hermes-memory/src/tools/skill-tool.ts +333 -0
- package/dist/extensions/pi-hermes-memory/src/tools/tool-result-views.ts +105 -0
- package/dist/extensions/pi-hermes-memory/src/types.ts +214 -0
- package/dist/extensions/pi-hermes-memory/tests/config.test.ts +434 -0
- package/dist/extensions/pi-hermes-memory/tests/extension-root-migration.test.ts +368 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/auto-consolidate.test.ts +984 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/background-review.test.ts +950 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/correction-detector.test.ts +671 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/insights.test.ts +157 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/interview.test.ts +127 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/pi-child-process.test.ts +905 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/preview-context.test.ts +152 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/prompt-context.test.ts +166 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/resources-discover.test.ts +71 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +614 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +192 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/session-flush.test.ts +677 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/session-live-index.test.ts +225 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/skills-command.test.ts +827 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/standing-pin.test.ts +134 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/sync-markdown-memories.test.ts +491 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/system-prompt.test.ts +199 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/thinking-max.test.ts +64 -0
- package/dist/extensions/pi-hermes-memory/tests/index.test.ts +30 -0
- package/dist/extensions/pi-hermes-memory/tests/integration/flow.test.ts +126 -0
- package/dist/extensions/pi-hermes-memory/tests/lifecycle-timing.test.ts +76 -0
- package/dist/extensions/pi-hermes-memory/tests/paths.test.ts +23 -0
- package/dist/extensions/pi-hermes-memory/tests/project-memory-migration.test.ts +80 -0
- package/dist/extensions/pi-hermes-memory/tests/project-rebinding.test.ts +115 -0
- package/dist/extensions/pi-hermes-memory/tests/project.test.ts +120 -0
- package/dist/extensions/pi-hermes-memory/tests/run-all-timeout.test.ts +107 -0
- package/dist/extensions/pi-hermes-memory/tests/run-all.sh +45 -0
- package/dist/extensions/pi-hermes-memory/tests/store/atomic-lock-coordinator.test.ts +381 -0
- package/dist/extensions/pi-hermes-memory/tests/store/content-scanner.test.ts +388 -0
- package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +1046 -0
- package/dist/extensions/pi-hermes-memory/tests/store/markdown-mutation-lock.test.ts +34 -0
- package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +2150 -0
- package/dist/extensions/pi-hermes-memory/tests/store/recovery-maintenance.test.ts +170 -0
- package/dist/extensions/pi-hermes-memory/tests/store/session-anchor-search.test.ts +210 -0
- package/dist/extensions/pi-hermes-memory/tests/store/session-indexer.test.ts +643 -0
- package/dist/extensions/pi-hermes-memory/tests/store/session-parser.test.ts +282 -0
- package/dist/extensions/pi-hermes-memory/tests/store/session-search.test.ts +287 -0
- package/dist/extensions/pi-hermes-memory/tests/store/skill-store.test.ts +678 -0
- package/dist/extensions/pi-hermes-memory/tests/store/skill-utils.test.ts +21 -0
- package/dist/extensions/pi-hermes-memory/tests/store/sqlite-lazy-load.test.ts +78 -0
- package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +543 -0
- package/dist/extensions/pi-hermes-memory/tests/store/sqlite-native.test.ts +164 -0
- package/dist/extensions/pi-hermes-memory/tests/store/standing-instructions.test.ts +171 -0
- package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +84 -0
- package/dist/extensions/pi-hermes-memory/tests/tools/memory-tool.test.ts +709 -0
- package/dist/extensions/pi-hermes-memory/tests/tools/session-search-tool.test.ts +345 -0
- package/dist/extensions/pi-hermes-memory/tests/tools/shared-output-view.test.ts +362 -0
- package/dist/extensions/pi-hermes-memory/tests/tools/skill-tool.test.ts +478 -0
- package/dist/extensions/pi-hermes-memory/tests/tools/tool-result-renderer-wiring.test.ts +40 -0
- package/dist/extensions/pi-hermes-memory/tsconfig.json +19 -0
- package/dist/extensions/pi-subagents/.oxlintrc.json +43 -0
- package/dist/extensions/pi-subagents/AGENTS.md +5 -0
- package/dist/extensions/pi-subagents/CHANGELOG.md +157 -0
- package/dist/extensions/pi-subagents/README.md +12 -6
- package/dist/extensions/pi-subagents/VISION.md +81 -0
- package/dist/extensions/pi-subagents/agents/claude-code-writer.md +15 -0
- package/dist/extensions/pi-subagents/agents/claude-code.md +15 -0
- package/dist/extensions/pi-subagents/agents/codex-exec-writer.md +15 -0
- package/dist/extensions/pi-subagents/agents/codex-exec.md +15 -0
- package/dist/extensions/pi-subagents/agents/cursor-agent-writer.md +14 -0
- package/dist/extensions/pi-subagents/agents/cursor-agent.md +14 -0
- package/dist/extensions/pi-subagents/agents/reviewer.md +1 -3
- package/dist/extensions/pi-subagents/docs/agents.md +488 -0
- package/dist/extensions/pi-subagents/docs/configuration.md +46 -9
- package/dist/extensions/pi-subagents/docs/extension-api.md +42 -3
- package/dist/extensions/pi-subagents/docs/models.md +27 -4
- package/dist/extensions/pi-subagents/docs/observability.md +10 -9
- package/dist/extensions/pi-subagents/docs/tool-reference.md +102 -6
- package/dist/extensions/pi-subagents/docs/workflows.md +135 -0
- package/dist/extensions/pi-subagents/package-lock.json +389 -2
- package/dist/extensions/pi-subagents/package.json +3 -1
- package/dist/extensions/pi-subagents/prompts/review-loop.md +2 -2
- package/dist/extensions/pi-subagents/skills/council-mode/SKILL.md +1 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +3 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +7 -3
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -2
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +26 -5
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +41 -22
- package/dist/extensions/pi-subagents/src/agents/agent-refinements.ts +4 -4
- package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +9 -2
- package/dist/extensions/pi-subagents/src/agents/agents.ts +322 -75
- package/dist/extensions/pi-subagents/src/agents/builtin-names.ts +6 -0
- package/dist/extensions/pi-subagents/src/agents/runtime-agent-events.ts +70 -0
- package/dist/extensions/pi-subagents/src/agents/runtime-agent-registry.ts +27 -20
- package/dist/extensions/pi-subagents/src/api/agents.ts +10 -5
- package/dist/extensions/pi-subagents/src/api/background-work.ts +5 -1
- package/dist/extensions/pi-subagents/src/api/delegation.ts +0 -7
- package/dist/extensions/pi-subagents/src/api/preflight.ts +34 -12
- package/dist/extensions/pi-subagents/src/extension/config.ts +70 -0
- package/dist/extensions/pi-subagents/src/extension/doctor.ts +3 -3
- package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +5 -3
- package/dist/extensions/pi-subagents/src/extension/index.ts +83 -30
- package/dist/extensions/pi-subagents/src/extension/public-execution.ts +44 -15
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +55 -19
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +41 -15
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +28 -31
- package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +2 -1
- package/dist/extensions/pi-subagents/src/inspectors/herdr/inspector-runner.ts +2 -10
- package/dist/extensions/pi-subagents/src/inspectors/herdr/session-roots-codec.ts +42 -0
- package/dist/extensions/pi-subagents/src/integrations/herdr-status.ts +51 -3
- package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +2 -0
- package/dist/extensions/pi-subagents/src/profiles/profiles.ts +5 -6
- package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +77 -10
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +176 -53
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +19 -12
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +29 -27
- package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +20 -3
- package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +23 -261
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +73 -7
- package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +8 -3
- package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +74 -8
- package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +37 -21
- package/dist/extensions/pi-subagents/src/runs/background/inspect-rpc.ts +8 -8
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +184 -9
- package/dist/extensions/pi-subagents/src/runs/background/result-delivery-ownership.ts +45 -0
- package/dist/extensions/pi-subagents/src/runs/background/result-files.ts +28 -14
- package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +38 -15
- package/dist/extensions/pi-subagents/src/runs/background/resume-guidance.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +50 -13
- package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +93 -8
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +10 -4
- package/dist/extensions/pi-subagents/src/runs/background/steering.ts +4 -14
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +549 -377
- package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +58 -10
- package/dist/extensions/pi-subagents/src/runs/background/terminal-run-index.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +26 -1
- package/dist/extensions/pi-subagents/src/runs/background/wait-config.ts +23 -9
- package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +9 -2
- package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +2 -2
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +204 -129
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +9 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +23 -1
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +773 -311
- package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +140 -115
- package/dist/extensions/pi-subagents/src/runs/shared/abort-recovery.ts +119 -0
- package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +463 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +19 -4
- package/dist/extensions/pi-subagents/src/runs/shared/child-launch-plan.ts +151 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +21 -7
- package/dist/extensions/pi-subagents/src/runs/shared/claude-code-adapter.ts +129 -0
- package/dist/extensions/pi-subagents/src/runs/shared/codex-exec-adapter.ts +129 -0
- package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +89 -0
- package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +5 -4
- package/dist/extensions/pi-subagents/src/runs/shared/cursor-agent-adapter.ts +114 -0
- package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +3 -3
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-contract.ts +167 -0
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +122 -0
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-runner.ts +348 -55
- package/dist/extensions/pi-subagents/src/runs/shared/fast-mode-extension.ts +5 -5
- package/dist/extensions/pi-subagents/src/runs/shared/host-step-status.ts +230 -0
- package/dist/extensions/pi-subagents/src/runs/shared/lane-metadata.ts +105 -0
- package/dist/extensions/pi-subagents/src/runs/shared/launch-cwd.ts +16 -0
- package/dist/extensions/pi-subagents/src/runs/shared/long-running-guard.ts +2 -1
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-config-sources.ts +422 -0
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +221 -158
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-grant.ts +197 -0
- package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +69 -7
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +47 -6
- package/dist/extensions/pi-subagents/src/runs/shared/mutation-evidence.ts +7 -2
- package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +9 -3
- package/dist/extensions/pi-subagents/src/runs/shared/nested-render.ts +9 -5
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +419 -7
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +15 -1
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +81 -8
- package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +13 -0
- package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +21 -1
- package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +44 -4
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +98 -13
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +847 -0
- package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +18 -0
- package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +46 -0
- package/dist/extensions/pi-subagents/src/shared/extension-context.ts +24 -0
- package/dist/extensions/pi-subagents/src/shared/fork-context.ts +21 -0
- package/dist/extensions/pi-subagents/src/shared/formatters.ts +18 -3
- package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +5 -1
- package/dist/extensions/pi-subagents/src/shared/pruned-fork.ts +450 -0
- package/dist/extensions/pi-subagents/src/shared/session-file-trust.ts +19 -0
- package/dist/extensions/pi-subagents/src/shared/session-tokens.ts +14 -3
- package/dist/extensions/pi-subagents/src/shared/settings.ts +19 -105
- package/dist/extensions/pi-subagents/src/shared/shortcuts.ts +17 -0
- package/dist/extensions/pi-subagents/src/shared/types.ts +359 -40
- package/dist/extensions/pi-subagents/src/shared/utils.ts +41 -84
- package/dist/extensions/pi-subagents/src/shared/workflow-child-permit.ts +116 -0
- package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +1 -9
- package/dist/extensions/pi-subagents/src/slash/delegation-request.ts +0 -4
- package/dist/extensions/pi-subagents/src/slash/slash-bridge.ts +1 -2
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +378 -88
- package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +22 -11
- package/dist/extensions/pi-subagents/src/slash/subagents-admin.ts +3 -0
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +147 -79
- package/dist/extensions/pi-subagents/src/tui/fleet-transcript.ts +11 -5
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +39 -18
- package/dist/extensions/pi-subagents/src/tui/render.ts +369 -46
- package/dist/extensions/pi-subagents/src/watchdog/turn-delta.ts +1 -1
- package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +6 -3
- package/dist/extensions/pi-subagents/src/workflows/host-command.ts +230 -0
- package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +740 -58
- package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +121 -0
- package/dist/extensions/pi-subagents/src/workflows/workflow-preflight.ts +270 -0
- package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +195 -6
- package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +246 -0
- package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +1114 -260
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +34 -0
- package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +150 -3
- package/dist/extensions/pi-subagents/test/integration/claude-code-smoke.test.ts +52 -0
- package/dist/extensions/pi-subagents/test/integration/claude-code-writer-smoke.test.ts +55 -0
- package/dist/extensions/pi-subagents/test/integration/codex-exec-smoke.test.ts +53 -0
- package/dist/extensions/pi-subagents/test/integration/codex-exec-writer-smoke.test.ts +57 -0
- package/dist/extensions/pi-subagents/test/integration/cursor-agent-smoke.test.ts +59 -0
- package/dist/extensions/pi-subagents/test/integration/cursor-agent-writer-smoke.test.ts +62 -0
- package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +57 -1
- package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +1 -0
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +20 -0
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +4 -3
- package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +54 -4
- package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +482 -4
- package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +157 -9
- package/dist/extensions/pi-subagents/test/integration/session-tokens.test.ts +5 -5
- package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +1508 -291
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +423 -1
- package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +8 -0
- package/dist/extensions/pi-subagents/test/support/cursor-smoke-inputs.ts +51 -0
- package/dist/extensions/pi-subagents/test/support/helpers.ts +2 -0
- package/dist/extensions/pi-subagents/test/support/mock-pi.ts +5 -5
- package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +6 -6
- package/dist/extensions/pi-subagents/test/unit/abort-recovery.test.ts +152 -0
- package/dist/extensions/pi-subagents/test/unit/active-async-capacity.test.ts +48 -0
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +184 -6
- package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +66 -6
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +77 -0
- package/dist/extensions/pi-subagents/test/unit/agent-refinements.test.ts +18 -0
- package/dist/extensions/pi-subagents/test/unit/anti-slop-oxlint.test.ts +86 -0
- package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +101 -1
- package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +121 -0
- package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +28 -0
- package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +14 -7
- package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +53 -0
- package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +190 -0
- package/dist/extensions/pi-subagents/test/unit/async-status-snapshot.test.ts +42 -0
- package/dist/extensions/pi-subagents/test/unit/auto-drain.test.ts +8 -4
- package/dist/extensions/pi-subagents/test/unit/background-work.test.ts +23 -0
- package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +78 -1
- package/dist/extensions/pi-subagents/test/unit/child-launch-plan.test.ts +94 -0
- package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +21 -0
- package/dist/extensions/pi-subagents/test/unit/child-session-name.test.ts +50 -0
- package/dist/extensions/pi-subagents/test/unit/claude-code-adapter.test.ts +245 -0
- package/dist/extensions/pi-subagents/test/unit/codex-exec-adapter.test.ts +192 -0
- package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +27 -0
- package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +150 -0
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +21 -0
- package/dist/extensions/pi-subagents/test/unit/cursor-agent-adapter.test.ts +259 -0
- package/dist/extensions/pi-subagents/test/unit/cursor-smoke-inputs.test.ts +77 -0
- package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +1 -4
- package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/extension-context.test.ts +27 -0
- package/dist/extensions/pi-subagents/test/unit/external-cli-runner.test.ts +223 -0
- package/dist/extensions/pi-subagents/test/unit/fast-mode-extension.test.ts +27 -0
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +208 -2
- package/dist/extensions/pi-subagents/test/unit/fleet-transcript.test.ts +29 -1
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +110 -1
- package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +10 -0
- package/dist/extensions/pi-subagents/test/unit/formatters.test.ts +14 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +18 -9
- package/dist/extensions/pi-subagents/test/unit/herdr-session-roots-codec.test.ts +63 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-shell-command.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +132 -0
- package/dist/extensions/pi-subagents/test/unit/host-command.test.ts +156 -0
- package/dist/extensions/pi-subagents/test/unit/host-step-status.test.ts +98 -0
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +178 -26
- package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +2 -1
- package/dist/extensions/pi-subagents/test/unit/inspect-rpc.test.ts +21 -0
- package/dist/extensions/pi-subagents/test/unit/mcp-direct-tool-grant.test.ts +138 -0
- package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +91 -0
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +72 -7
- package/dist/extensions/pi-subagents/test/unit/mutation-evidence.test.ts +21 -0
- package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +1 -0
- package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +20 -2
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +129 -1
- package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +4 -0
- package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +358 -0
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +574 -21
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +109 -1
- package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +71 -1
- package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +7 -7
- package/dist/extensions/pi-subagents/test/unit/pruned-fork.test.ts +214 -0
- package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +29 -8
- package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +53 -0
- package/dist/extensions/pi-subagents/test/unit/result-delivery-ownership.test.ts +34 -0
- package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +101 -3
- package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +1 -0
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +10 -8
- package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +71 -1
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +41 -7
- package/dist/extensions/pi-subagents/test/unit/runtime-agent-registration.test.ts +136 -2
- package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +137 -0
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +33 -12
- package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +504 -1
- package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +8 -0
- package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +12 -1
- package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +3 -5
- package/dist/extensions/pi-subagents/test/unit/steering.test.ts +5 -6
- package/dist/extensions/pi-subagents/test/unit/subagent-action-recovery.test.ts +0 -8
- package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +5 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +157 -2
- package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +63 -4
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +27 -23
- package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +44 -0
- package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +1 -0
- package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +7 -5
- package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +106 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +484 -9
- package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +38 -4
- package/dist/extensions/pi-subagents/test/unit/workflow-preflight.test.ts +155 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +318 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-resume-hint.test.ts +365 -0
- package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +349 -0
- package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +21 -0
- package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +2 -7
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/effect/index.ts +13 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/effect/rules/no-service-constructor-imports.ts +52 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/index.ts +41 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-chained-type-assertions.ts +77 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-conditional-empty-object-spread.ts +49 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-known-value-widening.ts +247 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-module-mocking.ts +91 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-object-parameters.ts +126 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-reflect-apply.ts +28 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-reflect-get.ts +28 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-runtime-typeof.ts +67 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-shape-in-symbol-names.ts +39 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unknown-parameters.ts +83 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unknown-returns.ts +115 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unknown-type-aliases.ts +72 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unsafe-dictionary-type.ts +134 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-widen-then-assert.ts +366 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/require-safety-comment-for-type-assertion.ts +62 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/shared/dictionary-types.ts +502 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/shared/lexical-type-parameters.ts +60 -0
- package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/shared/reflect-method.ts +35 -0
- package/dist/extensions/pi-tool-display/tests/capabilities.test.ts +1 -1
- package/dist/extensions/pi-tool-display/tests/settings-inspector.test.ts +2 -2
- package/dist/extensions/pi-tool-display/tests/tool-overrides-mcp.test.ts +1 -1
- package/dist/modes/interactive/interactive-mode.js +7 -7
- package/dist/skills/workflow/SKILL.md +65 -50
- package/package.json +112 -110
- package/dist/extensions/enable-readonly-tools.test.ts +0 -63
- package/dist/extensions/enable-readonly-tools.ts +0 -24
- package/dist/extensions/model-prompt-injector/config.json +0 -16
- package/dist/extensions/model-prompt-injector/index.test.ts +0 -102
- package/dist/extensions/model-prompt-injector/index.ts +0 -148
- package/dist/extensions/pi-subagents/src/runs/shared/turn-budget.ts +0 -98
- package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +0 -250
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill manager tool — registers the LLM-callable `skill_manage` tool for procedural memory.
|
|
3
|
+
* Complements the `memory` tool (declarative knowledge) with procedural knowledge.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
7
|
+
import { Type } from "typebox";
|
|
8
|
+
import { StringEnum } from "@earendil-works/pi-ai";
|
|
9
|
+
import { SkillStore } from "../store/skill-store.js";
|
|
10
|
+
import { SKILL_TOOL_DESCRIPTION } from "../constants.js";
|
|
11
|
+
import { createSharedToolResultRenderer } from "./shared-output-view.js";
|
|
12
|
+
import { skillResultView } from "./tool-result-views.js";
|
|
13
|
+
|
|
14
|
+
function normalizeTextList(value: unknown): string[] {
|
|
15
|
+
if (!Array.isArray(value)) return [];
|
|
16
|
+
return value
|
|
17
|
+
.filter((item): item is string => typeof item === "string")
|
|
18
|
+
.map((item) => item.trim())
|
|
19
|
+
.filter(Boolean);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function formatOrderedList(items: string[]): string {
|
|
23
|
+
return items.map((item, index) => `${index + 1}. ${item}`).join("\n");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function formatBulletList(items: string[], fallback: string): string {
|
|
27
|
+
if (items.length === 0) return `- ${fallback}`;
|
|
28
|
+
return items.map((item) => `- ${item}`).join("\n");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function buildStructuredSkillBody(
|
|
32
|
+
whenToUse: string,
|
|
33
|
+
procedureSteps: string[],
|
|
34
|
+
pitfalls: string[],
|
|
35
|
+
verificationSteps: string[],
|
|
36
|
+
): string {
|
|
37
|
+
return [
|
|
38
|
+
"## When to Use",
|
|
39
|
+
whenToUse,
|
|
40
|
+
"",
|
|
41
|
+
"## Procedure",
|
|
42
|
+
formatOrderedList(procedureSteps),
|
|
43
|
+
"",
|
|
44
|
+
"## Pitfalls",
|
|
45
|
+
formatBulletList(pitfalls, "No notable pitfalls recorded yet."),
|
|
46
|
+
"",
|
|
47
|
+
"## Verification",
|
|
48
|
+
formatOrderedList(verificationSteps),
|
|
49
|
+
].join("\n");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const SKILL_ID_PARAM = Type.String({
|
|
53
|
+
description: "Stable skill id for view/patch/update/delete. e.g., 'global:debug-typescript-errors' or 'project:my-repo:release-app'. Legacy alias 'edit' also accepts this field.",
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const SKILL_TOOL_PARAMETERS = Type.Object({
|
|
57
|
+
action: StringEnum(["create", "view", "patch", "update", "edit", "delete"] as const, {
|
|
58
|
+
description: "The skill action to perform.",
|
|
59
|
+
}),
|
|
60
|
+
name: Type.Optional(Type.String({
|
|
61
|
+
description: "Skill name for create. e.g., 'debug-typescript-errors'.",
|
|
62
|
+
})),
|
|
63
|
+
skill_id: Type.Optional(SKILL_ID_PARAM),
|
|
64
|
+
description: Type.Optional(Type.String({
|
|
65
|
+
description: "One-line description of when to use this skill. Required for create; optional for update/edit.",
|
|
66
|
+
})),
|
|
67
|
+
scope: Type.Optional(StringEnum(["global", "project"] as const, {
|
|
68
|
+
description: "Required for create. Use 'global' for portable procedures and 'project' for repo-specific workflows.",
|
|
69
|
+
})),
|
|
70
|
+
section: Type.Optional(Type.String({
|
|
71
|
+
description: "Required for patch. Section header to patch. e.g., 'Procedure', 'Pitfalls', 'Verification', 'When to Use'.",
|
|
72
|
+
})),
|
|
73
|
+
content: Type.Optional(Type.String({
|
|
74
|
+
description: "Raw markdown body for create/update/edit, or Markdown section body for patch. Prefer structured fields over free-form content when possible. For patch, JSON arrays are auto-coerced for list sections; JSON objects are rejected.",
|
|
75
|
+
})),
|
|
76
|
+
when_to_use: Type.Optional(Type.String({
|
|
77
|
+
description: "Structured create/update/edit field, or structured patch body when section is 'When to Use'.",
|
|
78
|
+
})),
|
|
79
|
+
procedure_steps: Type.Optional(Type.Array(Type.String(), {
|
|
80
|
+
description: "Structured create/update/edit field, or structured patch body when section is 'Procedure'. Ordered concrete steps.",
|
|
81
|
+
})),
|
|
82
|
+
pitfalls: Type.Optional(Type.Array(Type.String(), {
|
|
83
|
+
description: "Structured create/update/edit field, or structured patch body when section is 'Pitfalls'.",
|
|
84
|
+
})),
|
|
85
|
+
verification_steps: Type.Optional(Type.Array(Type.String(), {
|
|
86
|
+
description: "Structured create/update/edit field, or structured patch body when section is 'Verification'.",
|
|
87
|
+
})),
|
|
88
|
+
}, { additionalProperties: false });
|
|
89
|
+
|
|
90
|
+
export const SKILL_MANAGE_TOOL_NAME = "skill_manage";
|
|
91
|
+
|
|
92
|
+
export function registerSkillTool(pi: ExtensionAPI, store: SkillStore): void {
|
|
93
|
+
pi.registerTool({
|
|
94
|
+
name: SKILL_MANAGE_TOOL_NAME,
|
|
95
|
+
label: "Skill Manager",
|
|
96
|
+
description: SKILL_TOOL_DESCRIPTION,
|
|
97
|
+
promptSnippet: "Create, inspect, and update reusable procedures and patterns",
|
|
98
|
+
promptGuidelines: [
|
|
99
|
+
"Use the skill_manage tool after completing complex tasks that required trial and error or multiple tool calls.",
|
|
100
|
+
"Use 'create' to save a new reusable procedure, 'patch' to update a section of an existing skill by skill_id, and 'update' for a full rewrite.",
|
|
101
|
+
"Scope is required on create: choose scope='global' for transferable procedures and scope='project' when the workflow depends on this repo's paths, scripts, conventions, or deploy steps.",
|
|
102
|
+
"Prefer structured fields for create/update/patch: when_to_use, procedure_steps, pitfalls, and verification_steps. The tool renders valid SKILL.md sections for you.",
|
|
103
|
+
"For patch, pass section plus the matching structured field (e.g. section='Procedure' with procedure_steps). Avoid free-form content that is a JSON array/object string.",
|
|
104
|
+
"Prefer 'update' for multi-section rewrites when patch content would be large or format-unstable.",
|
|
105
|
+
"Use 'view' before patching or updating when you need to inspect an existing skill.",
|
|
106
|
+
"Do NOT use skills for temporary task state — only for durable, reusable procedures.",
|
|
107
|
+
],
|
|
108
|
+
renderResult: createSharedToolResultRenderer(skillResultView),
|
|
109
|
+
parameters: SKILL_TOOL_PARAMETERS,
|
|
110
|
+
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
111
|
+
const skillParams = params as {
|
|
112
|
+
action: "create" | "view" | "patch" | "update" | "edit" | "delete";
|
|
113
|
+
name?: string;
|
|
114
|
+
skill_id?: string;
|
|
115
|
+
description?: string;
|
|
116
|
+
scope?: "global" | "project";
|
|
117
|
+
section?: string;
|
|
118
|
+
content?: string;
|
|
119
|
+
when_to_use?: string;
|
|
120
|
+
procedure_steps?: unknown;
|
|
121
|
+
pitfalls?: unknown;
|
|
122
|
+
verification_steps?: unknown;
|
|
123
|
+
};
|
|
124
|
+
const {
|
|
125
|
+
action,
|
|
126
|
+
name,
|
|
127
|
+
skill_id,
|
|
128
|
+
description,
|
|
129
|
+
scope,
|
|
130
|
+
section,
|
|
131
|
+
content,
|
|
132
|
+
when_to_use,
|
|
133
|
+
procedure_steps,
|
|
134
|
+
pitfalls,
|
|
135
|
+
verification_steps,
|
|
136
|
+
} = skillParams;
|
|
137
|
+
|
|
138
|
+
const whenToUse = typeof when_to_use === "string" ? when_to_use.trim() : "";
|
|
139
|
+
const procedureSteps = normalizeTextList(procedure_steps);
|
|
140
|
+
const pitfallItems = normalizeTextList(pitfalls);
|
|
141
|
+
const verificationSteps = normalizeTextList(verification_steps);
|
|
142
|
+
const hasStructuredBody = Boolean(whenToUse) || procedureSteps.length > 0 || pitfallItems.length > 0 || verificationSteps.length > 0;
|
|
143
|
+
|
|
144
|
+
const buildBodyOrError = () => {
|
|
145
|
+
if (content?.trim()) return { body: content.trim() };
|
|
146
|
+
if (!hasStructuredBody) {
|
|
147
|
+
return {
|
|
148
|
+
error: "Either content or structured fields are required. Prefer when_to_use, procedure_steps, pitfalls, and verification_steps for create/update.",
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
if (!whenToUse) {
|
|
152
|
+
return { error: "when_to_use is required when content is omitted." };
|
|
153
|
+
}
|
|
154
|
+
if (procedureSteps.length === 0) {
|
|
155
|
+
return { error: "procedure_steps is required when content is omitted." };
|
|
156
|
+
}
|
|
157
|
+
if (verificationSteps.length === 0) {
|
|
158
|
+
return { error: "verification_steps is required when content is omitted." };
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
body: buildStructuredSkillBody(whenToUse, procedureSteps, pitfallItems, verificationSteps),
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
let result;
|
|
166
|
+
switch (action) {
|
|
167
|
+
case "create":
|
|
168
|
+
if (!name) {
|
|
169
|
+
return {
|
|
170
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: "name is required for 'create' action." }) }],
|
|
171
|
+
details: {},
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
if (!description) {
|
|
175
|
+
return {
|
|
176
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: "description is required for 'create' action." }) }],
|
|
177
|
+
details: {},
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
const createBodyResult = buildBodyOrError();
|
|
181
|
+
if (!createBodyResult.body) {
|
|
182
|
+
return {
|
|
183
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: createBodyResult.error }) }],
|
|
184
|
+
details: {},
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
if (!scope) {
|
|
188
|
+
return {
|
|
189
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: "scope is required for 'create' action. Use 'global' or 'project'." }) }],
|
|
190
|
+
details: {},
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
result = await store.create(name, description, createBodyResult.body, scope);
|
|
194
|
+
break;
|
|
195
|
+
|
|
196
|
+
case "view":
|
|
197
|
+
if (!skill_id) {
|
|
198
|
+
const index = await store.loadIndex();
|
|
199
|
+
return {
|
|
200
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, skills: index }) }],
|
|
201
|
+
details: { skills: index },
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
const doc = await store.loadSkill(skill_id);
|
|
205
|
+
if (!doc) {
|
|
206
|
+
return {
|
|
207
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: `Skill '${skill_id}' not found.` }) }],
|
|
208
|
+
details: {},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
result = { success: true, ...doc };
|
|
212
|
+
break;
|
|
213
|
+
|
|
214
|
+
case "patch": {
|
|
215
|
+
if (!skill_id) {
|
|
216
|
+
return {
|
|
217
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: "skill_id is required for 'patch' action." }) }],
|
|
218
|
+
details: {},
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
if (!section) {
|
|
222
|
+
return {
|
|
223
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: "section is required for 'patch' action." }) }],
|
|
224
|
+
details: {},
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const sectionKey = section.replace(/^#+\s*/, "").trim().toLowerCase();
|
|
229
|
+
let patchContent = content?.trim() ?? "";
|
|
230
|
+
|
|
231
|
+
// Prefer structured fields matching the target section so the LLM
|
|
232
|
+
// does not have to invent Markdown list formatting.
|
|
233
|
+
if (sectionKey === "procedure" && procedureSteps.length > 0) {
|
|
234
|
+
patchContent = formatOrderedList(procedureSteps);
|
|
235
|
+
} else if (sectionKey === "pitfalls" && pitfallItems.length > 0) {
|
|
236
|
+
patchContent = formatBulletList(pitfallItems, "No notable pitfalls recorded yet.");
|
|
237
|
+
} else if (sectionKey === "verification" && verificationSteps.length > 0) {
|
|
238
|
+
patchContent = formatOrderedList(verificationSteps);
|
|
239
|
+
} else if ((sectionKey === "when to use" || sectionKey === "when_to_use") && whenToUse) {
|
|
240
|
+
patchContent = whenToUse;
|
|
241
|
+
} else if (!patchContent && hasStructuredBody) {
|
|
242
|
+
// Allow a single structured field even if section name is non-standard.
|
|
243
|
+
if (procedureSteps.length > 0 && pitfallItems.length === 0 && verificationSteps.length === 0 && !whenToUse) {
|
|
244
|
+
patchContent = formatOrderedList(procedureSteps);
|
|
245
|
+
} else if (pitfallItems.length > 0 && procedureSteps.length === 0 && verificationSteps.length === 0 && !whenToUse) {
|
|
246
|
+
patchContent = formatBulletList(pitfallItems, "No notable pitfalls recorded yet.");
|
|
247
|
+
} else if (verificationSteps.length > 0 && procedureSteps.length === 0 && pitfallItems.length === 0 && !whenToUse) {
|
|
248
|
+
patchContent = formatOrderedList(verificationSteps);
|
|
249
|
+
} else if (whenToUse && procedureSteps.length === 0 && pitfallItems.length === 0 && verificationSteps.length === 0) {
|
|
250
|
+
patchContent = whenToUse;
|
|
251
|
+
} else {
|
|
252
|
+
return {
|
|
253
|
+
content: [{
|
|
254
|
+
type: "text",
|
|
255
|
+
text: JSON.stringify({
|
|
256
|
+
success: false,
|
|
257
|
+
error: "For patch, provide content or exactly one structured field matching the target section (procedure_steps, pitfalls, verification_steps, or when_to_use). Use update for multi-section rewrites.",
|
|
258
|
+
}),
|
|
259
|
+
}],
|
|
260
|
+
details: {},
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (!patchContent) {
|
|
266
|
+
return {
|
|
267
|
+
content: [{
|
|
268
|
+
type: "text",
|
|
269
|
+
text: JSON.stringify({
|
|
270
|
+
success: false,
|
|
271
|
+
error: "content or a matching structured field is required for 'patch' action. Prefer procedure_steps/pitfalls/verification_steps/when_to_use.",
|
|
272
|
+
}),
|
|
273
|
+
}],
|
|
274
|
+
details: {},
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
result = await store.patch(skill_id, section, patchContent);
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
case "update":
|
|
283
|
+
case "edit": {
|
|
284
|
+
const updateActionLabel = action === "edit" ? "edit" : "update";
|
|
285
|
+
if (!skill_id) {
|
|
286
|
+
return {
|
|
287
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: `skill_id is required for '${updateActionLabel}' action.` }) }],
|
|
288
|
+
details: {},
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
const updateBodyResult = buildBodyOrError();
|
|
292
|
+
const nextDescription = description?.trim() || "";
|
|
293
|
+
const nextBody = updateBodyResult.body ?? content?.trim() ?? "";
|
|
294
|
+
if (!nextDescription && !nextBody) {
|
|
295
|
+
return {
|
|
296
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: `Provide description, content, or structured fields for '${updateActionLabel}'.` }) }],
|
|
297
|
+
details: {},
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
if (hasStructuredBody && !updateBodyResult.body) {
|
|
301
|
+
return {
|
|
302
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: updateBodyResult.error }) }],
|
|
303
|
+
details: {},
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
result = await store.edit(skill_id, nextDescription, nextBody);
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
case "delete":
|
|
311
|
+
if (!skill_id) {
|
|
312
|
+
return {
|
|
313
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: "skill_id is required for 'delete' action." }) }],
|
|
314
|
+
details: {},
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
result = await store.delete(skill_id);
|
|
318
|
+
break;
|
|
319
|
+
|
|
320
|
+
default:
|
|
321
|
+
result = {
|
|
322
|
+
success: false,
|
|
323
|
+
error: `Unknown action '${action}'. Use: create, view, patch, update, delete`,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return {
|
|
328
|
+
content: [{ type: "text", text: JSON.stringify(result) }],
|
|
329
|
+
details: result,
|
|
330
|
+
};
|
|
331
|
+
},
|
|
332
|
+
});
|
|
333
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { SharedOutputView } from "./shared-output-view.js";
|
|
2
|
+
import { normalizeSharedOutputView } from "./shared-output-view.js";
|
|
3
|
+
|
|
4
|
+
function record(value: unknown): Record<string, any> | null {
|
|
5
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
6
|
+
? value as Record<string, any>
|
|
7
|
+
: null;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function resultData(result: unknown): Record<string, any> | null {
|
|
11
|
+
const resultRecord = record(result);
|
|
12
|
+
const details = record(resultRecord?.details);
|
|
13
|
+
if (details && Object.keys(details).length > 0) return details;
|
|
14
|
+
|
|
15
|
+
const content = resultRecord?.content;
|
|
16
|
+
if (!Array.isArray(content) || content.length !== 1) return null;
|
|
17
|
+
const text = record(content[0])?.text;
|
|
18
|
+
if (typeof text !== "string" || !text.trimStart().startsWith("{")) return null;
|
|
19
|
+
try {
|
|
20
|
+
return record(JSON.parse(text));
|
|
21
|
+
} catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function firstText(...values: unknown[]): string | null {
|
|
27
|
+
for (const value of values) {
|
|
28
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function warningText(data: Record<string, any>): string | null {
|
|
34
|
+
const warnings = Array.isArray(data.warnings)
|
|
35
|
+
? data.warnings.filter((value: unknown) => typeof value === "string" && value.trim())
|
|
36
|
+
: [];
|
|
37
|
+
return firstText(data.warning, ...warnings);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function memoryResultView(result: unknown): SharedOutputView {
|
|
41
|
+
const base = normalizeSharedOutputView(result);
|
|
42
|
+
const data = resultData(result);
|
|
43
|
+
if (!data) return base;
|
|
44
|
+
|
|
45
|
+
if (data.success === false || (data.success !== true && firstText(data.error))) {
|
|
46
|
+
const failureReason = firstText(data.error, data.message);
|
|
47
|
+
return { ...base, status: "failure", summary: failureReason ? `Error · ${failureReason}` : "Error" };
|
|
48
|
+
}
|
|
49
|
+
if (data.success !== true) return base;
|
|
50
|
+
|
|
51
|
+
const primaryMessage = (firstText(data.message) ?? "").split(/\s*\bWarning:/)[0].trim();
|
|
52
|
+
const evicted = typeof data.evicted_count === "number"
|
|
53
|
+
? data.evicted_count
|
|
54
|
+
: Array.isArray(data.evicted_entries)
|
|
55
|
+
? data.evicted_entries.length
|
|
56
|
+
: 0;
|
|
57
|
+
const outcome = /^Entry added\.$/.test(primaryMessage) || /^Failure memory saved:/.test(primaryMessage) || evicted > 0
|
|
58
|
+
? "Saved"
|
|
59
|
+
: /^Entry replaced\.$/.test(primaryMessage)
|
|
60
|
+
? "Replaced"
|
|
61
|
+
: /^Entry removed\.$/.test(primaryMessage)
|
|
62
|
+
? "Removed"
|
|
63
|
+
: /^Entry already exists/.test(primaryMessage)
|
|
64
|
+
? "Unchanged"
|
|
65
|
+
: "Updated";
|
|
66
|
+
const parts = [outcome];
|
|
67
|
+
if (typeof data.target === "string" && data.target.trim()) parts.push(`target: ${data.target.trim()}`);
|
|
68
|
+
const category = typeof data.category === "string" && data.category.trim()
|
|
69
|
+
? data.category.trim()
|
|
70
|
+
: data.target === "failure"
|
|
71
|
+
? primaryMessage.match(/^Failure memory saved:\s*(\S+)/i)?.[1] ?? null
|
|
72
|
+
: null;
|
|
73
|
+
if (category) parts.push(`category: ${category}`);
|
|
74
|
+
if (evicted > 0) parts.push(`evicted: ${evicted}`);
|
|
75
|
+
if (typeof data.entry_count === "number") parts.push(`${data.entry_count} ${data.entry_count === 1 ? "entry" : "entries"}`);
|
|
76
|
+
if (typeof data.usage === "string" && data.usage.trim()) parts.push(data.usage.trim());
|
|
77
|
+
const warning = warningText(data);
|
|
78
|
+
if (warning) parts.push(`Warning: ${warning}`);
|
|
79
|
+
return { ...base, status: "success", summary: parts.join(" · ") };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function searchResultView(result: unknown): SharedOutputView {
|
|
83
|
+
const base = normalizeSharedOutputView(result);
|
|
84
|
+
const data = resultData(result);
|
|
85
|
+
if (!data || data.success === false) return base;
|
|
86
|
+
if (typeof data.count === "number") {
|
|
87
|
+
return { ...base, summary: data.count === 1 ? "Found 1 result" : `Found ${data.count} results` };
|
|
88
|
+
}
|
|
89
|
+
return base;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function skillResultView(result: unknown): SharedOutputView {
|
|
93
|
+
const base = normalizeSharedOutputView(result);
|
|
94
|
+
const data = resultData(result);
|
|
95
|
+
if (!data) return base;
|
|
96
|
+
if (data.success === false) {
|
|
97
|
+
const failureReason = firstText(data.error, data.message);
|
|
98
|
+
return { ...base, status: "failure", summary: failureReason ? `Error · ${failureReason}` : "Error" };
|
|
99
|
+
}
|
|
100
|
+
if (Array.isArray(data.skills)) return { ...base, summary: `Skills: ${data.skills.length} available` };
|
|
101
|
+
|
|
102
|
+
const name = firstText(data.displayName, data.name, data.skillId, data.skill_id);
|
|
103
|
+
if (name) return { ...base, summary: `Skill: ${name}` };
|
|
104
|
+
return { ...base, summary: firstText(data.message) ?? "Skill updated" };
|
|
105
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared TypeScript types for the Hermes Memory extension.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { ModelThinkingLevel, TextContent } from "@earendil-works/pi-ai";
|
|
6
|
+
|
|
7
|
+
export type MemoryOverflowStrategy = "auto-consolidate" | "reject" | "fifo-evict";
|
|
8
|
+
|
|
9
|
+
export type SessionSearchVariant = "legacy" | "anchors";
|
|
10
|
+
|
|
11
|
+
export type ThinkingLevel = ModelThinkingLevel;
|
|
12
|
+
|
|
13
|
+
export type ReviewTransport = "direct" | "subprocess";
|
|
14
|
+
|
|
15
|
+
export interface SessionSearchConfig {
|
|
16
|
+
/** Session search implementation variant. Default: legacy */
|
|
17
|
+
variant: SessionSearchVariant;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface MemoryConfig {
|
|
21
|
+
/** Prompt memory mode. Default: policy-only */
|
|
22
|
+
memoryMode: "policy-only" | "legacy-inject";
|
|
23
|
+
/** Policy prompt style used when memoryMode is policy-only. Default: full */
|
|
24
|
+
memoryPolicyStyle?: "full" | "compact" | "custom" | "none";
|
|
25
|
+
/** Custom policy prompt text used when memoryPolicyStyle is custom */
|
|
26
|
+
memoryPolicyCustomText?: string;
|
|
27
|
+
/** Max chars for MEMORY.md (agent notes). Default: 5000 */
|
|
28
|
+
memoryCharLimit: number;
|
|
29
|
+
/** Max chars for USER.md (user profile). Default: 5000 */
|
|
30
|
+
userCharLimit: number;
|
|
31
|
+
/** Max chars for project-level MEMORY.md. Default: 5000 */
|
|
32
|
+
projectCharLimit: number;
|
|
33
|
+
/** Turns between background auto-reviews. Default: 10 */
|
|
34
|
+
nudgeInterval: number;
|
|
35
|
+
/** Recent conversation messages included in background review. 0 = all. Default: 0 */
|
|
36
|
+
reviewRecentMessages?: number;
|
|
37
|
+
/** Enable background learning loop. Default: true */
|
|
38
|
+
reviewEnabled: boolean;
|
|
39
|
+
/** How background review invokes the LLM. Default: direct */
|
|
40
|
+
reviewTransport?: ReviewTransport;
|
|
41
|
+
/** Flush memories before compaction. Default: true */
|
|
42
|
+
flushOnCompact: boolean;
|
|
43
|
+
/** Flush memories on session shutdown. Default: true */
|
|
44
|
+
flushOnShutdown: boolean;
|
|
45
|
+
/** Minimum user turns before flush triggers. Default: 6 */
|
|
46
|
+
flushMinTurns: number;
|
|
47
|
+
/** Recent conversation messages included in session flush. 0 = all. Default: 0 */
|
|
48
|
+
flushRecentMessages?: number;
|
|
49
|
+
/** Override extension storage directory. Default: ~/.selesai/agent/pi-hermes-memory */
|
|
50
|
+
memoryDir?: string;
|
|
51
|
+
/** Directory for project-scoped memory (relative to ~/.selesai/agent). Default: "projects-memory" */
|
|
52
|
+
projectsMemoryDir?: string;
|
|
53
|
+
/** Session search configuration. Default: { variant: "legacy" } */
|
|
54
|
+
sessionSearch?: SessionSearchConfig;
|
|
55
|
+
/** Override model used for child pi -p subprocess LLM calls. Default: unset */
|
|
56
|
+
llmModelOverride?: string;
|
|
57
|
+
/** Override thinking level used for child pi -p subprocess LLM calls. Default: unset */
|
|
58
|
+
llmThinkingOverride?: ThinkingLevel;
|
|
59
|
+
/** Trusted Pi extension sources required by child processes, such as custom providers or auth adapters. */
|
|
60
|
+
childExtensionPaths?: string[];
|
|
61
|
+
/** Strategy when memory is full. Default: auto-consolidate */
|
|
62
|
+
memoryOverflowStrategy?: MemoryOverflowStrategy;
|
|
63
|
+
/** Wall-clock grace after overflow before automatic consolidation. Default: 180000 */
|
|
64
|
+
overflowGraceMs?: number;
|
|
65
|
+
/** Legacy alias for memoryOverflowStrategy. Default: true */
|
|
66
|
+
autoConsolidate: boolean;
|
|
67
|
+
/** Detect user corrections and trigger immediate memory save. Default: true */
|
|
68
|
+
correctionDetection: boolean;
|
|
69
|
+
/** Override strong correction regex sources. Missing = defaults; [] = none. */
|
|
70
|
+
correctionStrongPatterns?: string[];
|
|
71
|
+
/** Override weak correction regex sources. Missing = defaults; [] = none. */
|
|
72
|
+
correctionWeakPatterns?: string[];
|
|
73
|
+
/** Override negative correction regex sources. Missing = defaults; [] = none. */
|
|
74
|
+
correctionNegativePatterns?: string[];
|
|
75
|
+
/** Override directive words used after weak correction patterns. Missing = defaults; [] = none. */
|
|
76
|
+
correctionDirectiveWords?: string[];
|
|
77
|
+
/** Inject recent failure memories into the system prompt. Default: true */
|
|
78
|
+
failureInjectionEnabled: boolean;
|
|
79
|
+
/** Maximum age in days for injected failure memories. Default: 7 */
|
|
80
|
+
failureInjectionMaxAgeDays: number;
|
|
81
|
+
/** Maximum number of failure memories to inject. Default: 5 */
|
|
82
|
+
failureInjectionMaxEntries: number;
|
|
83
|
+
/** Tool calls before triggering background review (in addition to turn count). Default: 15 */
|
|
84
|
+
nudgeToolCalls: number;
|
|
85
|
+
/** Maximum time in milliseconds for a consolidation run, auto or manual. Default: 180000 */
|
|
86
|
+
consolidationTimeoutMs: number;
|
|
87
|
+
/** Log failed auto-consolidation attempts to the session console. Default: true */
|
|
88
|
+
autoConsolidationWarnOnFailure: boolean;
|
|
89
|
+
/** Inject pinned STANDING.md instructions into every session. Default: true */
|
|
90
|
+
standingInstructionsEnabled: boolean;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export type MemoryCategory =
|
|
94
|
+
| "failure"
|
|
95
|
+
| "correction"
|
|
96
|
+
| "insight"
|
|
97
|
+
| "preference"
|
|
98
|
+
| "convention"
|
|
99
|
+
| "tool-quirk";
|
|
100
|
+
|
|
101
|
+
export interface MemoryResult {
|
|
102
|
+
success: boolean;
|
|
103
|
+
error?: string;
|
|
104
|
+
message?: string;
|
|
105
|
+
warning?: string;
|
|
106
|
+
warnings?: string[];
|
|
107
|
+
target?: "memory" | "user" | "failure" | "project";
|
|
108
|
+
entries?: string[];
|
|
109
|
+
usage?: string;
|
|
110
|
+
entry_count?: number;
|
|
111
|
+
evicted_entries?: string[];
|
|
112
|
+
evicted_count?: number;
|
|
113
|
+
matches?: string[];
|
|
114
|
+
/** Targets that contain old_text when a replace/remove was sent to the wrong one. */
|
|
115
|
+
matching_targets?: Array<"memory" | "user" | "failure" | "project">;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface MemoryMutationOperation {
|
|
119
|
+
action: "add" | "replace" | "remove";
|
|
120
|
+
content?: string;
|
|
121
|
+
oldText?: string;
|
|
122
|
+
category?: MemoryCategory;
|
|
123
|
+
failureReason?: string;
|
|
124
|
+
project?: string;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export interface MemorySnapshot {
|
|
128
|
+
memory: string;
|
|
129
|
+
user: string;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface ConsolidationResult {
|
|
133
|
+
/** Whether consolidation succeeded */
|
|
134
|
+
consolidated: boolean;
|
|
135
|
+
/** Error message if consolidation failed */
|
|
136
|
+
error?: string;
|
|
137
|
+
/**
|
|
138
|
+
* Set when another session already holds the consolidation lock for this
|
|
139
|
+
* target. Nothing is broken — the work is happening elsewhere — so callers
|
|
140
|
+
* should tell the user to retry rather than report a failed consolidation.
|
|
141
|
+
*/
|
|
142
|
+
deferred?: boolean;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export type SkillScope = "global" | "project";
|
|
146
|
+
|
|
147
|
+
export interface SkillIndex {
|
|
148
|
+
/** Stable id for read/update/delete operations */
|
|
149
|
+
skillId: string;
|
|
150
|
+
/** Whether the skill is global or project-scoped */
|
|
151
|
+
scope: SkillScope;
|
|
152
|
+
/** File name on disk (usually SKILL.md) */
|
|
153
|
+
fileName: string;
|
|
154
|
+
/** Absolute path to the skill file */
|
|
155
|
+
path: string;
|
|
156
|
+
/** Active project name for project-scoped skills */
|
|
157
|
+
projectName?: string;
|
|
158
|
+
/** Pi skill slug stored in frontmatter and folder name */
|
|
159
|
+
name: string;
|
|
160
|
+
/** Optional human-friendly title preserved for UI output */
|
|
161
|
+
displayName?: string;
|
|
162
|
+
/** Short description shown in skill listings */
|
|
163
|
+
description: string;
|
|
164
|
+
/** ISO date created */
|
|
165
|
+
created: string;
|
|
166
|
+
/** ISO date last updated */
|
|
167
|
+
updated: string;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface SkillDocument extends SkillIndex {
|
|
171
|
+
/** Full markdown body (after frontmatter) */
|
|
172
|
+
body: string;
|
|
173
|
+
/** Version number */
|
|
174
|
+
version: number;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export interface SkillResult {
|
|
178
|
+
success: boolean;
|
|
179
|
+
error?: string;
|
|
180
|
+
message?: string;
|
|
181
|
+
fileName?: string;
|
|
182
|
+
skillId?: string;
|
|
183
|
+
scope?: SkillScope;
|
|
184
|
+
path?: string;
|
|
185
|
+
conflictType?: "duplicate" | "similar" | "name-collision" | "scope-conflict";
|
|
186
|
+
similarSkillIds?: string[];
|
|
187
|
+
suggestedAction?: "patch" | "update" | "rename";
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Extract displayable text from a Pi session entry message.
|
|
192
|
+
*
|
|
193
|
+
* Accepts any value — returns null for non-message entries (BashExecutionMessage,
|
|
194
|
+
* NotificationMessage, etc.) that lack a `content` property.
|
|
195
|
+
*
|
|
196
|
+
* Returns the concatenated text, truncated to `maxLength` chars.
|
|
197
|
+
*/
|
|
198
|
+
export function getMessageText(msg: unknown, maxLength = 500): string | null {
|
|
199
|
+
if (typeof msg !== "object" || msg === null) return null;
|
|
200
|
+
const { role, content } = msg as Record<string, unknown>;
|
|
201
|
+
if (typeof role !== "string") return null;
|
|
202
|
+
|
|
203
|
+
if (typeof content === "string") {
|
|
204
|
+
return content.slice(0, maxLength);
|
|
205
|
+
}
|
|
206
|
+
if (Array.isArray(content)) {
|
|
207
|
+
const text = (content as TextContent[])
|
|
208
|
+
.filter((block): block is TextContent => block.type === "text" && typeof block.text === "string")
|
|
209
|
+
.map((block) => block.text)
|
|
210
|
+
.join("\n");
|
|
211
|
+
return text.length > 0 ? text.slice(0, maxLength) : null;
|
|
212
|
+
}
|
|
213
|
+
return null;
|
|
214
|
+
}
|