@herbertgao/pi-extensions 2026.9.6 → 2026.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -8
- package/THIRD_PARTY_NOTICES.md +0 -4
- package/node_modules/@narumitw/pi-btw/README.md +2 -0
- package/node_modules/@narumitw/pi-btw/dist/index.ts +284 -365
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +3 -3
- package/node_modules/@narumitw/pi-btw/package.json +52 -53
- package/node_modules/@narumitw/pi-btw/src/bring-to-main.ts +494 -547
- package/node_modules/@narumitw/pi-btw/src/btw.ts +814 -856
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +673 -674
- package/node_modules/@narumitw/pi-btw/src/keybindings.ts +228 -270
- package/node_modules/@narumitw/pi-btw/src/main-tree-picker.ts +309 -318
- package/node_modules/@narumitw/pi-btw/src/menu.ts +416 -454
- package/node_modules/@narumitw/pi-btw/src/settings.ts +203 -219
- package/node_modules/@narumitw/pi-btw/src/side-thread.ts +173 -201
- package/node_modules/@narumitw/pi-btw/src/text.ts +21 -23
- package/node_modules/@narumitw/pi-btw/src/transcript-markdown.ts +65 -0
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +611 -662
- package/node_modules/pi-lens/CHANGELOG.md +239 -0
- package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +3 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +30 -4
- package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +2 -0
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +26 -0
- package/node_modules/pi-lens/dist/clients/biome-client.js +1 -1
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +403 -35
- package/node_modules/pi-lens/dist/clients/bootstrap.js +6 -1
- package/node_modules/pi-lens/dist/clients/cascade-format.js +200 -4
- package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +10 -2
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +16 -1
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +12 -1
- package/node_modules/pi-lens/dist/clients/dispatch/ast-grep-catalog.js +65 -0
- package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +28 -0
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +9 -2
- package/node_modules/pi-lens/dist/clients/dispatch/finding-policy.js +222 -0
- package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +389 -13
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +175 -25
- package/node_modules/pi-lens/dist/clients/dispatch/rule-ignores.js +62 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +21 -41
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +6 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +7 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -12
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +2 -21
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/types.js +4 -1
- package/node_modules/pi-lens/dist/clients/disposition-publish.js +1 -0
- package/node_modules/pi-lens/dist/clients/effective-config.js +1 -1
- package/node_modules/pi-lens/dist/clients/file-kinds.js +26 -1
- package/node_modules/pi-lens/dist/clients/file-role.js +21 -21
- package/node_modules/pi-lens/dist/clients/file-utils.js +156 -10
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +56 -9
- package/node_modules/pi-lens/dist/clients/format-service.js +39 -21
- package/node_modules/pi-lens/dist/clients/formatters.js +60 -13
- package/node_modules/pi-lens/dist/clients/generation-guard.js +2 -2
- package/node_modules/pi-lens/dist/clients/git-guard.js +11 -3
- package/node_modules/pi-lens/dist/clients/indent-retarget.js +78 -8
- package/node_modules/pi-lens/dist/clients/installer/index.js +333 -114
- package/node_modules/pi-lens/dist/clients/instance-reaper-state.js +7 -0
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +20 -10
- package/node_modules/pi-lens/dist/clients/language-profile.js +23 -1
- package/node_modules/pi-lens/dist/clients/language-registry.js +5 -1
- package/node_modules/pi-lens/dist/clients/latency-logger.js +4 -1
- package/node_modules/pi-lens/dist/clients/lens-engine.js +12 -3
- package/node_modules/pi-lens/dist/clients/lens-events.js +2 -1
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +79 -0
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/client.js +25 -21
- package/node_modules/pi-lens/dist/clients/lsp/config.js +2 -2
- package/node_modules/pi-lens/dist/clients/lsp/index.js +7 -0
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +16 -4
- package/node_modules/pi-lens/dist/clients/lsp/server.js +19 -2
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +5 -3
- package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +12 -8
- package/node_modules/pi-lens/dist/clients/mcp/session.js +36 -4
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +24 -7
- package/node_modules/pi-lens/dist/clients/observed-mutation.js +40 -2
- package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +23 -3
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +110 -15
- package/node_modules/pi-lens/dist/clients/path-utils.js +123 -3
- package/node_modules/pi-lens/dist/clients/performance-report.js +5 -1
- package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +1 -1
- package/node_modules/pi-lens/dist/clients/pipeline.js +74 -5
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +37 -5
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +145 -18
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/dead-code.js +4 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +59 -3
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +45 -2
- package/node_modules/pi-lens/dist/clients/read-guard.js +70 -11
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +147 -9
- package/node_modules/pi-lens/dist/clients/ruff-client.js +1 -1
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +33 -5
- package/node_modules/pi-lens/dist/clients/runtime-context.js +6 -2
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +77 -7
- package/node_modules/pi-lens/dist/clients/runtime-session.js +21 -2
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +43 -12
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +330 -85
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +147 -17
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +258 -5
- package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +6 -0
- package/node_modules/pi-lens/dist/clients/session-event-guard.js +50 -5
- package/node_modules/pi-lens/dist/clients/sg-runner.js +23 -11
- package/node_modules/pi-lens/dist/clients/sgconfig.js +79 -2
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +6 -41
- package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +43 -0
- package/node_modules/pi-lens/dist/clients/tool-agreement.js +423 -0
- package/node_modules/pi-lens/dist/clients/tool-config.js +50 -0
- package/node_modules/pi-lens/dist/clients/tool-cwd.js +47 -76
- package/node_modules/pi-lens/dist/clients/tool-policy.js +163 -7
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +120 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +127 -189
- package/node_modules/pi-lens/dist/clients/widget-state.js +98 -0
- package/node_modules/pi-lens/dist/clients/word-index.js +5 -2
- package/node_modules/pi-lens/dist/clients/write-ordering-guard.js +7 -0
- package/node_modules/pi-lens/dist/index.js +27416 -24153
- package/node_modules/pi-lens/dist/mcp/server.js +5 -2
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +7 -1
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +168 -53
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +244 -72
- package/node_modules/pi-lens/docs/audit1.md +5 -5
- package/node_modules/pi-lens/docs/dependencies.md +11 -0
- package/node_modules/pi-lens/docs/dispositions.md +52 -0
- package/node_modules/pi-lens/docs/environment-variables.md +2 -2
- package/node_modules/pi-lens/docs/features.md +4 -4
- package/node_modules/pi-lens/docs/globalconfig.md +3 -1
- package/node_modules/pi-lens/docs/language-coverage.md +1 -0
- package/node_modules/pi-lens/docs/pi-lens-fixer.md +53 -94
- package/node_modules/pi-lens/docs/pi-lens-investigator.md +43 -38
- package/node_modules/pi-lens/docs/pi-lens-retro.md +97 -0
- package/node_modules/pi-lens/docs/pi-lens-reviewer.md +53 -66
- package/node_modules/pi-lens/docs/release-qa-baseline.md +22 -0
- package/node_modules/pi-lens/docs/settings.md +7 -4
- package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +1 -1
- package/node_modules/pi-lens/docs/usage.md +2 -0
- package/node_modules/pi-lens/package.json +1 -1
- package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/sql-injection.yml +24 -12
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +40 -0
- package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +15 -0
- package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +7 -0
- package/package.json +5 -11
- package/node_modules/@luxusai/pi-hindsight/CHANGELOG.md +0 -376
- package/node_modules/@luxusai/pi-hindsight/README.md +0 -92
- package/node_modules/@luxusai/pi-hindsight/docs/adr/001-memory-lifecycle-and-scope.md +0 -56
- package/node_modules/@luxusai/pi-hindsight/docs/adr/002-explicit-routing-strategy-seam.md +0 -169
- package/node_modules/@luxusai/pi-hindsight/docs/adr/003-tui-memory-mode-vocabulary.md +0 -107
- package/node_modules/@luxusai/pi-hindsight/docs/adr/004-lifeos-dual-bank-design.md +0 -89
- package/node_modules/@luxusai/pi-hindsight/docs/adr/005-domain-banks-and-agent-first-surface.md +0 -189
- package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark.webp +0 -0
- package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark@2x.webp +0 -0
- package/node_modules/@luxusai/pi-hindsight/docs/coding-memory-evaluation.md +0 -54
- package/node_modules/@luxusai/pi-hindsight/docs/compatibility.md +0 -75
- package/node_modules/@luxusai/pi-hindsight/docs/hindsight-core-functions.md +0 -300
- package/node_modules/@luxusai/pi-hindsight/docs/mission-and-mental-model-quality.md +0 -158
- package/node_modules/@luxusai/pi-hindsight/docs/next-opt-out-design.md +0 -164
- package/node_modules/@luxusai/pi-hindsight/docs/risky-memory-modes.md +0 -139
- package/node_modules/@luxusai/pi-hindsight/docs/starter-mental-model-suggestions.md +0 -74
- package/node_modules/@luxusai/pi-hindsight/docs/surface-reference.md +0 -261
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-operations.ts +0 -151
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-selection.ts +0 -18
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-settings-presenter.ts +0 -46
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-templates.ts +0 -383
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/banking.ts +0 -240
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/knowledge-page-seed.ts +0 -176
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/retain-strategies.ts +0 -178
- package/node_modules/@luxusai/pi-hindsight/extensions/client/client-retry.ts +0 -41
- package/node_modules/@luxusai/pi-hindsight/extensions/client/client.ts +0 -386
- package/node_modules/@luxusai/pi-hindsight/extensions/client/fetch-compat.ts +0 -39
- package/node_modules/@luxusai/pi-hindsight/extensions/client/timeout.ts +0 -34
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-defaults.ts +0 -140
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-model.ts +0 -61
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-registry.ts +0 -925
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-field-paths.ts +0 -247
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-normalize.ts +0 -547
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-writer.ts +0 -480
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config.ts +0 -182
- package/node_modules/@luxusai/pi-hindsight/extensions/config/setup-gate.ts +0 -86
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-execute.ts +0 -1010
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-parse.ts +0 -175
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-plan.ts +0 -425
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-presentation.ts +0 -210
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-sessions.ts +0 -817
- package/node_modules/@luxusai/pi-hindsight/extensions/index.ts +0 -25
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/git-seed.ts +0 -319
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-recall.ts +0 -196
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-retain.ts +0 -189
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-runtime.ts +0 -65
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle.ts +0 -260
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/mental-models.ts +0 -244
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/observation-scopes.ts +0 -59
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-cleanup.ts +0 -82
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-visibility.ts +0 -45
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall.ts +0 -331
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-cursor.ts +0 -354
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-job-builder.ts +0 -66
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-receipts.ts +0 -132
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain.ts +0 -228
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-bank-template-operations.ts +0 -74
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-config-operations.ts +0 -16
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-control-operations.ts +0 -648
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-diagnostics-operations.ts +0 -105
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-identity.ts +0 -68
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-service.ts +0 -71
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-types.ts +0 -13
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-recall-operations.ts +0 -162
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-retain-operations.ts +0 -131
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-scope.ts +0 -104
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-session-operations.ts +0 -37
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/operation-catalog.ts +0 -893
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/reflect-presenter.ts +0 -35
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/scope-migrate.ts +0 -177
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/tools.ts +0 -7
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/flush-presenter.ts +0 -21
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/jsonl-queue-store.ts +0 -112
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-delivery.ts +0 -111
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-lock.ts +0 -214
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-operations.ts +0 -70
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue.ts +0 -392
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/bank-template-presentation.ts +0 -45
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/commands.ts +0 -9
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/guided-setup.ts +0 -860
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/prefill-input.ts +0 -105
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-flow.ts +0 -189
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-server-probe.ts +0 -299
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-actions.ts +0 -201
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-facts.ts +0 -47
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-render.ts +0 -239
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-types.ts +0 -50
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui.ts +0 -259
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/tool-presenters.ts +0 -77
- package/node_modules/@luxusai/pi-hindsight/extensions/types.ts +0 -534
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/diagnostics.ts +0 -319
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/messages.ts +0 -325
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/sanitize.ts +0 -42
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-memory-meta.ts +0 -244
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-operations.ts +0 -56
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session.ts +0 -50
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-fields.ts +0 -167
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-health.ts +0 -207
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status.ts +0 -120
- package/node_modules/@luxusai/pi-hindsight/extensions/version.ts +0 -8
- package/node_modules/@luxusai/pi-hindsight/package.json +0 -118
- package/node_modules/@luxusai/pi-hindsight/skills/hindsight-memory-doctor/SKILL.md +0 -75
|
@@ -1,383 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
BankTemplateConfig,
|
|
3
|
-
BankTemplateManifest,
|
|
4
|
-
BankTemplateMentalModel,
|
|
5
|
-
} from "@vectorize-io/hindsight-client";
|
|
6
|
-
import {
|
|
7
|
-
defaultGlobalBankMissions,
|
|
8
|
-
defaultLifeBankMissions,
|
|
9
|
-
defaultProjectBankMissions,
|
|
10
|
-
resolveBankMissions,
|
|
11
|
-
} from "./bank-operations.js";
|
|
12
|
-
import type { BankMissionDefaults } from "./bank-operations.js";
|
|
13
|
-
import { KNOWLEDGE_ENTITY_LABELS, PI_RETAIN_STRATEGIES } from "./retain-strategies.js";
|
|
14
|
-
import type { AgentUseProfile, BankMissionSettings } from "../types.js";
|
|
15
|
-
|
|
16
|
-
export type BankTemplateProfileId =
|
|
17
|
-
| "pi-coding-project"
|
|
18
|
-
| "pi-conversation-project"
|
|
19
|
-
| "pi-coding-user"
|
|
20
|
-
| "pi-conversation-user"
|
|
21
|
-
/** @deprecated alias for pi-coding-user */
|
|
22
|
-
| "pi-user-preferences";
|
|
23
|
-
|
|
24
|
-
export type BankTemplateTarget = "project" | "user";
|
|
25
|
-
|
|
26
|
-
export interface BuiltInBankTemplate {
|
|
27
|
-
id: BankTemplateProfileId;
|
|
28
|
-
label: string;
|
|
29
|
-
target: BankTemplateTarget;
|
|
30
|
-
/** Which agent use profile this template is for. */
|
|
31
|
-
agentUse: AgentUseProfile;
|
|
32
|
-
description: string;
|
|
33
|
-
manifest: BankTemplateManifest;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function bankConfigFromMissions(
|
|
37
|
-
missions: BankMissionDefaults,
|
|
38
|
-
options?: { codingStrategies?: boolean },
|
|
39
|
-
): BankTemplateConfig {
|
|
40
|
-
const base: BankTemplateConfig = {
|
|
41
|
-
reflect_mission: missions.reflectMission,
|
|
42
|
-
retain_mission: missions.retainMission,
|
|
43
|
-
enable_observations: true,
|
|
44
|
-
observations_mission: missions.observationsMission,
|
|
45
|
-
};
|
|
46
|
-
if (!options?.codingStrategies) return base;
|
|
47
|
-
// Coding-agents-aligned multi-strategy retain + knowledge entity labels for page routing.
|
|
48
|
-
// Default strategy is conversation (live Pi sessions); git/gitlog used by opt-in seed paths.
|
|
49
|
-
return {
|
|
50
|
-
...base,
|
|
51
|
-
retain_extraction_mode: "verbose",
|
|
52
|
-
retain_default_strategy: "conversation",
|
|
53
|
-
retain_strategies: { ...PI_RETAIN_STRATEGIES },
|
|
54
|
-
entity_labels: [KNOWLEDGE_ENTITY_LABELS],
|
|
55
|
-
entities_allow_free_form: true,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Tags must be a subset of tags written at retain time (source:pi, harness:pi, project:*, session:*, repo:*).
|
|
60
|
-
// Project-tier models get project:<id> stamped at apply time (resolveBankTemplateManifest).
|
|
61
|
-
const RETAIN_COMPAT_TAGS = ["source:pi"] as const;
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Coding-agent MM refresh defaults (oh-my-pi / Claude Code / Hindsight deep dive):
|
|
65
|
-
* delta folds new evidence; refresh after consolidation; no MM→MM feedback.
|
|
66
|
-
* Project MMs: observation-first (less probe/world noise).
|
|
67
|
-
* Prefs/user MMs: world+experience+observation — observation-only can rebuild empty after clear
|
|
68
|
-
* (live: coding-assistant-operating-preferences → "#").
|
|
69
|
-
* Template import sends the full trigger; agent create only maps refreshAfterConsolidation today.
|
|
70
|
-
*/
|
|
71
|
-
type MmTrigger = NonNullable<BankTemplateMentalModel["trigger"]>;
|
|
72
|
-
const DEFAULT_MM_TRIGGER_PROJECT: MmTrigger = {
|
|
73
|
-
mode: "delta",
|
|
74
|
-
refresh_after_consolidation: true,
|
|
75
|
-
fact_types: ["observation"],
|
|
76
|
-
exclude_mental_models: true,
|
|
77
|
-
};
|
|
78
|
-
const DEFAULT_MM_TRIGGER_PREFS: MmTrigger = {
|
|
79
|
-
mode: "delta",
|
|
80
|
-
refresh_after_consolidation: true,
|
|
81
|
-
fact_types: ["world", "experience", "observation"],
|
|
82
|
-
exclude_mental_models: true,
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
/** Seed max_tokens: keep inject lean (AMB cost; inject shares mentalModels.maxChars). */
|
|
86
|
-
const DEFAULT_MM_MAX_TOKENS_PREFS = 600;
|
|
87
|
-
const DEFAULT_MM_MAX_TOKENS_PROJECT = 800;
|
|
88
|
-
|
|
89
|
-
// Bank-global on shared coding bank (no project:* tag) — injects for every project.
|
|
90
|
-
const CODING_BANK_GLOBAL_MENTAL_MODELS: BankTemplateMentalModel[] = [
|
|
91
|
-
{
|
|
92
|
-
id: "coding-assistant-operating-preferences",
|
|
93
|
-
name: "Coding assistant operating preferences",
|
|
94
|
-
source_query:
|
|
95
|
-
"What durable preferences has the user shown for how coding assistants should plan, verify, commit, use tools, and communicate across repositories? Especially capture clarification style: whether questions are welcome, when to ask (up front vs mid-task), and that questions should be high-signal (not answerable by the agent alone). Exclude one-off probe/bait/test session constraints such as temporary 'do not ask questions; just execute' rules. Capture only stable cross-project habits.",
|
|
96
|
-
tags: [...RETAIN_COMPAT_TAGS],
|
|
97
|
-
max_tokens: DEFAULT_MM_MAX_TOKENS_PREFS,
|
|
98
|
-
trigger: DEFAULT_MM_TRIGGER_PREFS,
|
|
99
|
-
},
|
|
100
|
-
];
|
|
101
|
-
|
|
102
|
-
// Coding project models — durable engineering knowledge (oh-my-pi-shaped core + a few extras).
|
|
103
|
-
const CODING_PROJECT_MENTAL_MODELS: BankTemplateMentalModel[] = [
|
|
104
|
-
{
|
|
105
|
-
id: "project-architecture-and-seams",
|
|
106
|
-
name: "Project architecture and seams",
|
|
107
|
-
source_query:
|
|
108
|
-
"What are the stable architecture boundaries, modules, and seams in this project?",
|
|
109
|
-
tags: [...RETAIN_COMPAT_TAGS],
|
|
110
|
-
max_tokens: DEFAULT_MM_MAX_TOKENS_PROJECT,
|
|
111
|
-
trigger: DEFAULT_MM_TRIGGER_PROJECT,
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
id: "project-conventions",
|
|
115
|
-
name: "Project conventions",
|
|
116
|
-
source_query:
|
|
117
|
-
"What are this project's conventions for code style, build, testing, release, and review? Only include conventions explicit in the project or repeatedly enforced.",
|
|
118
|
-
tags: [...RETAIN_COMPAT_TAGS],
|
|
119
|
-
max_tokens: DEFAULT_MM_MAX_TOKENS_PROJECT,
|
|
120
|
-
trigger: DEFAULT_MM_TRIGGER_PROJECT,
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
id: "project-decisions",
|
|
124
|
-
name: "Project decisions",
|
|
125
|
-
source_query:
|
|
126
|
-
"What durable architectural or product decisions have been made for this project, and what rationale or trade-offs were recorded? Exclude transient plans and active task state.",
|
|
127
|
-
tags: [...RETAIN_COMPAT_TAGS],
|
|
128
|
-
max_tokens: DEFAULT_MM_MAX_TOKENS_PROJECT,
|
|
129
|
-
trigger: DEFAULT_MM_TRIGGER_PROJECT,
|
|
130
|
-
},
|
|
131
|
-
];
|
|
132
|
-
|
|
133
|
-
// Conversation / real-life task project models — not coding-centric.
|
|
134
|
-
const CONVERSATION_PROJECT_MENTAL_MODELS: BankTemplateMentalModel[] = [
|
|
135
|
-
{
|
|
136
|
-
id: "active-goals-and-commitments",
|
|
137
|
-
name: "Active goals and commitments",
|
|
138
|
-
source_query:
|
|
139
|
-
"What goals, commitments, deadlines, and open loops is the user tracking in this context? Prefer durable ongoing items over one-off chat filler.",
|
|
140
|
-
tags: [...RETAIN_COMPAT_TAGS],
|
|
141
|
-
max_tokens: DEFAULT_MM_MAX_TOKENS_PROJECT,
|
|
142
|
-
trigger: DEFAULT_MM_TRIGGER_PREFS,
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
id: "people-and-context",
|
|
146
|
-
name: "People and context",
|
|
147
|
-
source_query:
|
|
148
|
-
"Which people, roles, relationships, and recurring situations matter here? Capture only durable context the assistant needs, not sensitive private details.",
|
|
149
|
-
tags: [...RETAIN_COMPAT_TAGS],
|
|
150
|
-
max_tokens: DEFAULT_MM_MAX_TOKENS_PREFS,
|
|
151
|
-
trigger: DEFAULT_MM_TRIGGER_PREFS,
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
id: "decisions-and-preferences",
|
|
155
|
-
name: "Decisions and preferences",
|
|
156
|
-
source_query:
|
|
157
|
-
"What durable decisions, preferences, and constraints has the user stated for this conversation or life domain? Exclude one-off requests.",
|
|
158
|
-
tags: [...RETAIN_COMPAT_TAGS],
|
|
159
|
-
max_tokens: DEFAULT_MM_MAX_TOKENS_PROJECT,
|
|
160
|
-
trigger: DEFAULT_MM_TRIGGER_PREFS,
|
|
161
|
-
},
|
|
162
|
-
];
|
|
163
|
-
|
|
164
|
-
const CODING_USER_MENTAL_MODELS: BankTemplateMentalModel[] = [
|
|
165
|
-
{
|
|
166
|
-
id: "user-collaboration-preferences",
|
|
167
|
-
name: "User collaboration preferences",
|
|
168
|
-
source_query:
|
|
169
|
-
"What durable preferences has the user shown for collaboration, review, autonomy, and communication?",
|
|
170
|
-
tags: [...RETAIN_COMPAT_TAGS],
|
|
171
|
-
max_tokens: DEFAULT_MM_MAX_TOKENS_PREFS,
|
|
172
|
-
trigger: DEFAULT_MM_TRIGGER_PREFS,
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
id: "coding-assistant-operating-preferences",
|
|
176
|
-
name: "Coding assistant operating preferences",
|
|
177
|
-
source_query:
|
|
178
|
-
"What durable preferences has the user shown for how coding assistants should plan, verify, commit, and use tools?",
|
|
179
|
-
tags: [...RETAIN_COMPAT_TAGS],
|
|
180
|
-
max_tokens: DEFAULT_MM_MAX_TOKENS_PREFS,
|
|
181
|
-
trigger: DEFAULT_MM_TRIGGER_PREFS,
|
|
182
|
-
},
|
|
183
|
-
{
|
|
184
|
-
id: "cross-project-workflow-habits",
|
|
185
|
-
name: "Cross-project workflow habits",
|
|
186
|
-
source_query:
|
|
187
|
-
"What workflow habits recur across the user's repositories, issue tracking, PR review, and release process?",
|
|
188
|
-
tags: [...RETAIN_COMPAT_TAGS],
|
|
189
|
-
max_tokens: DEFAULT_MM_MAX_TOKENS_PREFS,
|
|
190
|
-
trigger: DEFAULT_MM_TRIGGER_PREFS,
|
|
191
|
-
},
|
|
192
|
-
];
|
|
193
|
-
|
|
194
|
-
const CONVERSATION_USER_MENTAL_MODELS: BankTemplateMentalModel[] = [
|
|
195
|
-
{
|
|
196
|
-
id: "communication-preferences",
|
|
197
|
-
name: "Communication preferences",
|
|
198
|
-
source_query:
|
|
199
|
-
"What durable preferences has the user shown for tone, length, language, and how the assistant should respond?",
|
|
200
|
-
tags: [...RETAIN_COMPAT_TAGS],
|
|
201
|
-
max_tokens: DEFAULT_MM_MAX_TOKENS_PREFS,
|
|
202
|
-
trigger: DEFAULT_MM_TRIGGER_PREFS,
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
id: "life-workflow-habits",
|
|
206
|
-
name: "Life and task workflow habits",
|
|
207
|
-
source_query:
|
|
208
|
-
"What recurring real-life workflows, planning habits, and task-management preferences does the user express across conversations?",
|
|
209
|
-
tags: [...RETAIN_COMPAT_TAGS],
|
|
210
|
-
max_tokens: DEFAULT_MM_MAX_TOKENS_PREFS,
|
|
211
|
-
trigger: DEFAULT_MM_TRIGGER_PREFS,
|
|
212
|
-
},
|
|
213
|
-
{
|
|
214
|
-
id: "priority-and-scheduling-preferences",
|
|
215
|
-
name: "Priority and scheduling preferences",
|
|
216
|
-
source_query:
|
|
217
|
-
"How does the user prefer to prioritize, schedule, and trade off time across personal and work tasks? Capture durable patterns only.",
|
|
218
|
-
tags: [...RETAIN_COMPAT_TAGS],
|
|
219
|
-
max_tokens: DEFAULT_MM_MAX_TOKENS_PREFS,
|
|
220
|
-
trigger: DEFAULT_MM_TRIGGER_PREFS,
|
|
221
|
-
},
|
|
222
|
-
];
|
|
223
|
-
|
|
224
|
-
export const BUILT_IN_BANK_TEMPLATES: readonly BuiltInBankTemplate[] = [
|
|
225
|
-
{
|
|
226
|
-
id: "pi-coding-project",
|
|
227
|
-
label: "Coding project",
|
|
228
|
-
target: "project",
|
|
229
|
-
agentUse: "coding",
|
|
230
|
-
description: "Repo-focused mental models for architecture, conventions, and durable decisions.",
|
|
231
|
-
manifest: {
|
|
232
|
-
version: "1",
|
|
233
|
-
bank: bankConfigFromMissions(defaultProjectBankMissions(), { codingStrategies: true }),
|
|
234
|
-
mental_models: CODING_PROJECT_MENTAL_MODELS,
|
|
235
|
-
},
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
id: "pi-conversation-project",
|
|
239
|
-
label: "Conversation / life tasks",
|
|
240
|
-
target: "project",
|
|
241
|
-
agentUse: "conversation",
|
|
242
|
-
description:
|
|
243
|
-
"Non-coding mental models for goals, people/context, and durable decisions in a conversation or real-life task agent.",
|
|
244
|
-
manifest: {
|
|
245
|
-
version: "1",
|
|
246
|
-
bank: bankConfigFromMissions(defaultProjectBankMissions()),
|
|
247
|
-
mental_models: CONVERSATION_PROJECT_MENTAL_MODELS,
|
|
248
|
-
},
|
|
249
|
-
},
|
|
250
|
-
{
|
|
251
|
-
id: "pi-coding-user",
|
|
252
|
-
label: "Coding user preferences",
|
|
253
|
-
target: "user",
|
|
254
|
-
agentUse: "coding",
|
|
255
|
-
description: "Cross-project durable coding-assistant and collaboration preferences.",
|
|
256
|
-
manifest: {
|
|
257
|
-
version: "1",
|
|
258
|
-
bank: bankConfigFromMissions(defaultGlobalBankMissions()),
|
|
259
|
-
mental_models: CODING_USER_MENTAL_MODELS,
|
|
260
|
-
},
|
|
261
|
-
},
|
|
262
|
-
{
|
|
263
|
-
id: "pi-conversation-user",
|
|
264
|
-
label: "Conversation user preferences",
|
|
265
|
-
target: "user",
|
|
266
|
-
agentUse: "conversation",
|
|
267
|
-
description: "Cross-context durable communication and life-workflow preferences.",
|
|
268
|
-
manifest: {
|
|
269
|
-
version: "1",
|
|
270
|
-
bank: bankConfigFromMissions(defaultLifeBankMissions()),
|
|
271
|
-
mental_models: CONVERSATION_USER_MENTAL_MODELS,
|
|
272
|
-
},
|
|
273
|
-
},
|
|
274
|
-
] as const;
|
|
275
|
-
|
|
276
|
-
/** Legacy id still resolves for older docs/scripts. */
|
|
277
|
-
const LEGACY_TEMPLATE_ALIASES: Record<string, BankTemplateProfileId> = {
|
|
278
|
-
"pi-user-preferences": "pi-coding-user",
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
export function listBuiltInBankTemplates(): readonly BuiltInBankTemplate[] {
|
|
282
|
-
return BUILT_IN_BANK_TEMPLATES;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
export function listBankTemplatesForAgentUse(
|
|
286
|
-
agentUse: AgentUseProfile,
|
|
287
|
-
): readonly BuiltInBankTemplate[] {
|
|
288
|
-
return BUILT_IN_BANK_TEMPLATES.filter((template) => template.agentUse === agentUse);
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
export function defaultTemplateIdFor(
|
|
292
|
-
target: BankTemplateTarget,
|
|
293
|
-
agentUse: AgentUseProfile,
|
|
294
|
-
): BankTemplateProfileId {
|
|
295
|
-
if (target === "project") {
|
|
296
|
-
return agentUse === "conversation" ? "pi-conversation-project" : "pi-coding-project";
|
|
297
|
-
}
|
|
298
|
-
return agentUse === "conversation" ? "pi-conversation-user" : "pi-coding-user";
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
export function getBuiltInBankTemplate(id: string): BuiltInBankTemplate | undefined {
|
|
302
|
-
const resolved = LEGACY_TEMPLATE_ALIASES[id] ?? id;
|
|
303
|
-
return BUILT_IN_BANK_TEMPLATES.find((template) => template.id === resolved);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
function defaultMissionsForTarget(
|
|
307
|
-
target: BankTemplateTarget,
|
|
308
|
-
agentUse: AgentUseProfile,
|
|
309
|
-
): BankMissionDefaults {
|
|
310
|
-
if (target === "user") {
|
|
311
|
-
return agentUse === "conversation" ? defaultLifeBankMissions() : defaultGlobalBankMissions();
|
|
312
|
-
}
|
|
313
|
-
return defaultProjectBankMissions();
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
function slugProjectId(projectId: string): string {
|
|
317
|
-
return (
|
|
318
|
-
projectId
|
|
319
|
-
.toLowerCase()
|
|
320
|
-
.replace(/[^a-z0-9]+/g, "-")
|
|
321
|
-
.replace(/^-|-$/g, "")
|
|
322
|
-
.slice(0, 48) || "project"
|
|
323
|
-
);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/** Bank-global models merged into coding project template apply (unstamped). */
|
|
327
|
-
function bankGlobalMentalModelsForTemplate(templateId: string): readonly BankTemplateMentalModel[] {
|
|
328
|
-
if (templateId === "pi-coding-project") return CODING_BANK_GLOBAL_MENTAL_MODELS;
|
|
329
|
-
return [];
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* Resolve template manifest for import. For project-target templates with a projectId,
|
|
334
|
-
* stamp project-tier mental models with project:<id> tags and id suffixes so multi-project
|
|
335
|
-
* domain banks do not share one architecture model (ADR-005). Coding project templates also
|
|
336
|
-
* merge bank-global models (no project tag) so setup can ensure cross-project starters.
|
|
337
|
-
*/
|
|
338
|
-
export function resolveBankTemplateManifest(
|
|
339
|
-
template: BuiltInBankTemplate,
|
|
340
|
-
bankMissionSettings: BankMissionSettings,
|
|
341
|
-
options?: { projectId?: string },
|
|
342
|
-
): BankTemplateManifest {
|
|
343
|
-
const missions = resolveBankMissions(
|
|
344
|
-
bankMissionSettings,
|
|
345
|
-
defaultMissionsForTarget(template.target, template.agentUse),
|
|
346
|
-
);
|
|
347
|
-
const projectId = options?.projectId?.trim();
|
|
348
|
-
let mental_models = template.manifest.mental_models;
|
|
349
|
-
if (template.target === "project" && projectId && mental_models?.length) {
|
|
350
|
-
const suffix = slugProjectId(projectId);
|
|
351
|
-
const projectTag = `project:${projectId}`;
|
|
352
|
-
const stamped = mental_models.map((model) => ({
|
|
353
|
-
...model,
|
|
354
|
-
id: `${model.id}--${suffix}`,
|
|
355
|
-
tags: [...new Set([...(model.tags ?? []), "source:pi", projectTag])],
|
|
356
|
-
}));
|
|
357
|
-
const bankGlobal = bankGlobalMentalModelsForTemplate(template.id);
|
|
358
|
-
mental_models = bankGlobal.length > 0 ? [...bankGlobal, ...stamped] : stamped;
|
|
359
|
-
}
|
|
360
|
-
const codingStrategies = template.id === "pi-coding-project";
|
|
361
|
-
return {
|
|
362
|
-
...template.manifest,
|
|
363
|
-
...(mental_models ? { mental_models } : {}),
|
|
364
|
-
bank: bankConfigFromMissions(missions, { codingStrategies }),
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
/** Expected starter mental-model ids after resolve (for setup ensure checks). */
|
|
369
|
-
export function expectedStarterMentalModelIds(args: {
|
|
370
|
-
target: BankTemplateTarget;
|
|
371
|
-
agentUse: AgentUseProfile;
|
|
372
|
-
projectId?: string;
|
|
373
|
-
bankMissionSettings?: BankMissionSettings;
|
|
374
|
-
}): string[] {
|
|
375
|
-
const template = getBuiltInBankTemplate(defaultTemplateIdFor(args.target, args.agentUse));
|
|
376
|
-
if (!template) return [];
|
|
377
|
-
const manifest = resolveBankTemplateManifest(template, args.bankMissionSettings ?? {}, {
|
|
378
|
-
...(args.projectId ? { projectId: args.projectId } : {}),
|
|
379
|
-
});
|
|
380
|
-
return (manifest.mental_models ?? [])
|
|
381
|
-
.map((model) => model.id)
|
|
382
|
-
.filter((id): id is string => typeof id === "string" && id.length > 0);
|
|
383
|
-
}
|
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import { basename, resolve } from "node:path";
|
|
3
|
-
import { existsSync, realpathSync } from "node:fs";
|
|
4
|
-
import { dirname } from "node:path";
|
|
5
|
-
import { execFileSync } from "node:child_process";
|
|
6
|
-
import type { BankSelection, ResolvedConfig } from "../types.js";
|
|
7
|
-
|
|
8
|
-
export type ProjectIdBasis = "pin" | "remote" | "basename";
|
|
9
|
-
|
|
10
|
-
export interface ProjectIdentity {
|
|
11
|
-
/** Stable project id used in `project:<id>` tags. */
|
|
12
|
-
projectId: string;
|
|
13
|
-
basis: ProjectIdBasis;
|
|
14
|
-
/** Human-readable source (pin value, remote URL, or root path). */
|
|
15
|
-
source: string;
|
|
16
|
-
/** Absolute-path-hash legacy key (for dual-tag / migration diagnostics). */
|
|
17
|
-
legacyRepoKey: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function slug(value: string): string {
|
|
21
|
-
return (
|
|
22
|
-
value
|
|
23
|
-
.toLowerCase()
|
|
24
|
-
.replace(/[^a-z0-9]+/g, "-")
|
|
25
|
-
.replace(/^-|-$/g, "")
|
|
26
|
-
.slice(0, 48) || "repo"
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function hash(value: string): string {
|
|
31
|
-
return createHash("sha256").update(value).digest("hex").slice(0, 12);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function canonicalPath(path: string): string {
|
|
35
|
-
try {
|
|
36
|
-
return realpathSync.native(path);
|
|
37
|
-
} catch {
|
|
38
|
-
return resolve(path);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function findRepoRoot(cwd: string): string {
|
|
43
|
-
const gitRoot = findMainGitWorktreeRoot(cwd);
|
|
44
|
-
if (gitRoot) return canonicalPath(gitRoot);
|
|
45
|
-
|
|
46
|
-
let current = resolve(cwd);
|
|
47
|
-
while (true) {
|
|
48
|
-
if (existsSync(`${current}/.git`)) return canonicalPath(current);
|
|
49
|
-
const parent = resolve(current, "..");
|
|
50
|
-
if (parent === current) return canonicalPath(cwd);
|
|
51
|
-
current = parent;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function findMainGitWorktreeRoot(cwd: string): string | undefined {
|
|
56
|
-
try {
|
|
57
|
-
const git = (args: string[]) =>
|
|
58
|
-
execFileSync("git", ["rev-parse", "--path-format=absolute", ...args], {
|
|
59
|
-
cwd,
|
|
60
|
-
encoding: "utf8",
|
|
61
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
62
|
-
timeout: 1000,
|
|
63
|
-
}).trim();
|
|
64
|
-
|
|
65
|
-
const commonDir = git(["--git-common-dir"]);
|
|
66
|
-
if (!commonDir) return undefined;
|
|
67
|
-
const gitDir = git(["--git-dir"]);
|
|
68
|
-
|
|
69
|
-
if (commonDir !== gitDir && basename(commonDir) === ".git") return dirname(commonDir);
|
|
70
|
-
|
|
71
|
-
const topLevel = git(["--show-toplevel"]);
|
|
72
|
-
return topLevel || (basename(commonDir) === ".git" ? dirname(commonDir) : commonDir);
|
|
73
|
-
} catch {
|
|
74
|
-
return undefined;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/** Path-hash legacy identity (Mac/Linux path moves change this). Prefer projectId. */
|
|
79
|
-
export function legacyRepoKey(cwd: string): string {
|
|
80
|
-
const root = findRepoRoot(cwd);
|
|
81
|
-
return `${slug(basename(root))}-${hash(root)}`;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/** @deprecated Use resolveProjectIdentity / projectId; kept for call-site compatibility. */
|
|
85
|
-
export function repoKey(cwd: string): string {
|
|
86
|
-
return legacyRepoKey(cwd);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export function normalizeGitRemoteToProjectId(remoteUrl: string): string {
|
|
90
|
-
let value = remoteUrl.trim();
|
|
91
|
-
const scp = value.match(/^git@([^:]+):(.+)$/i);
|
|
92
|
-
if (scp) value = `${scp[1]}/${scp[2]}`;
|
|
93
|
-
value = value
|
|
94
|
-
// Drop userinfo (tokens/credentials) before slugging so insteadOf/helper URLs
|
|
95
|
-
// cannot leak into stable project:<id> tags.
|
|
96
|
-
.replace(/^(https?:\/\/)[^/@]+@/i, "$1")
|
|
97
|
-
.replace(/^https?:\/\//i, "")
|
|
98
|
-
.replace(/^ssh:\/\/git@/i, "")
|
|
99
|
-
.replace(/^git:\/\//i, "")
|
|
100
|
-
.replace(/\.git$/i, "")
|
|
101
|
-
.replace(/\/+/g, "/");
|
|
102
|
-
const id = slug(value);
|
|
103
|
-
return id || "remote";
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function gitRemoteOrigin(repoRoot: string): string | undefined {
|
|
107
|
-
try {
|
|
108
|
-
// Read the configured URL, not `git remote get-url`, so url.*.insteadOf
|
|
109
|
-
// credential rewrites (CI/cloud agents) do not change project identity.
|
|
110
|
-
const url = execFileSync("git", ["config", "--get", "remote.origin.url"], {
|
|
111
|
-
cwd: repoRoot,
|
|
112
|
-
encoding: "utf8",
|
|
113
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
114
|
-
timeout: 1000,
|
|
115
|
-
}).trim();
|
|
116
|
-
return url || undefined;
|
|
117
|
-
} catch {
|
|
118
|
-
return undefined;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Resolve stable project identity: pin → git remote (default) → basename.
|
|
124
|
-
* Survives absolute path moves when a remote or pin is available (ADR-005).
|
|
125
|
-
*/
|
|
126
|
-
export function resolveProjectIdentity(cwd: string, config: ResolvedConfig): ProjectIdentity {
|
|
127
|
-
const root = findRepoRoot(cwd);
|
|
128
|
-
const legacy = `${slug(basename(root))}-${hash(root)}`;
|
|
129
|
-
const pin = config.scope?.projectId?.trim();
|
|
130
|
-
if (pin) {
|
|
131
|
-
return {
|
|
132
|
-
projectId: slug(pin) || pin,
|
|
133
|
-
basis: "pin",
|
|
134
|
-
source: pin,
|
|
135
|
-
legacyRepoKey: legacy,
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const strategy = config.scope?.projectIdStrategy ?? "remote";
|
|
140
|
-
if (strategy === "remote") {
|
|
141
|
-
const remote = gitRemoteOrigin(root);
|
|
142
|
-
if (remote) {
|
|
143
|
-
return {
|
|
144
|
-
projectId: normalizeGitRemoteToProjectId(remote),
|
|
145
|
-
basis: "remote",
|
|
146
|
-
source: remote,
|
|
147
|
-
legacyRepoKey: legacy,
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const base = slug(basename(root)) || "project";
|
|
153
|
-
return {
|
|
154
|
-
projectId: base,
|
|
155
|
-
basis: "basename",
|
|
156
|
-
source: root,
|
|
157
|
-
legacyRepoKey: legacy,
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export function projectScopeTag(projectId: string): string {
|
|
162
|
-
return `project:${projectId}`;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export function legacyRepoScopeTag(legacyKey: string): string {
|
|
166
|
-
return `repo:${legacyKey}`;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Resolve the coding-role bank id.
|
|
171
|
-
* - Explicit banks.project.bankId always wins (domain coding bank or isolated override).
|
|
172
|
-
* - isolated-bank mode (or legacy path when no bankId): path/cwd-derived bank.
|
|
173
|
-
* - domain-tagged without bankId: still path-derived for upgrade safety; setup should set bankId.
|
|
174
|
-
*/
|
|
175
|
-
export function deriveProjectBankId(cwd: string, config: ResolvedConfig): string {
|
|
176
|
-
if (config.banks.project.bankId) return config.banks.project.bankId;
|
|
177
|
-
// Domain-tagged + explicit bankId is the preferred shared coding bank path.
|
|
178
|
-
// Without bankId, keep path-derived identity so upgrades do not silently merge banks.
|
|
179
|
-
const basis = config.banks.project.derive === "cwd" ? resolve(cwd) : findRepoRoot(cwd);
|
|
180
|
-
return `pi-project-${slug(basename(basis))}-${hash(basis)}`;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/** True when this repo uses a hard-isolated bank rather than a shared coding domain bank. */
|
|
184
|
-
export function isIsolatedBankMode(config: ResolvedConfig): boolean {
|
|
185
|
-
return config.scope.mode === "isolated-bank";
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/** Coding-role bank id (alias for deriveProjectBankId). */
|
|
189
|
-
export function deriveCodingBankId(cwd: string, config: ResolvedConfig): string {
|
|
190
|
-
return deriveProjectBankId(cwd, config);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
export function selectBanks(cwd: string, config: ResolvedConfig): BankSelection {
|
|
194
|
-
const globalBankId = config.banks.user.enabled ? config.banks.user.bankId : undefined;
|
|
195
|
-
return {
|
|
196
|
-
projectBankId: deriveProjectBankId(cwd, config),
|
|
197
|
-
...(globalBankId ? { globalBankId } : {}),
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
export function baseTags(
|
|
202
|
-
cwd: string,
|
|
203
|
-
sessionId: string,
|
|
204
|
-
leafIdOrConfig?: string | ResolvedConfig,
|
|
205
|
-
maybeConfig?: ResolvedConfig,
|
|
206
|
-
): string[] {
|
|
207
|
-
const leafId = typeof leafIdOrConfig === "string" ? leafIdOrConfig : undefined;
|
|
208
|
-
const config =
|
|
209
|
-
typeof leafIdOrConfig === "object" && leafIdOrConfig
|
|
210
|
-
? leafIdOrConfig
|
|
211
|
-
: (maybeConfig ??
|
|
212
|
-
({
|
|
213
|
-
scope: { projectIdStrategy: "remote" },
|
|
214
|
-
} as ResolvedConfig));
|
|
215
|
-
const identity = resolveProjectIdentity(cwd, config);
|
|
216
|
-
const tags = [
|
|
217
|
-
"source:pi",
|
|
218
|
-
// Provenance host tag (coding-agents uses harness:<name> + source:chat).
|
|
219
|
-
"harness:pi",
|
|
220
|
-
projectScopeTag(identity.projectId),
|
|
221
|
-
// Dual-tag window: keep legacy path-hash tag so older memories still match any_strict.
|
|
222
|
-
legacyRepoScopeTag(identity.legacyRepoKey),
|
|
223
|
-
`session:${sessionId}`,
|
|
224
|
-
];
|
|
225
|
-
if (leafId) tags.push(`branch:${leafId}`);
|
|
226
|
-
return tags;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/** Project recall filter: match either stable project tag or legacy path-hash repo tag. */
|
|
230
|
-
export function recallScopeTags(cwd: string, config?: ResolvedConfig): string[] {
|
|
231
|
-
const identity = resolveProjectIdentity(
|
|
232
|
-
cwd,
|
|
233
|
-
config ?? ({ scope: { projectIdStrategy: "remote" } } as ResolvedConfig),
|
|
234
|
-
);
|
|
235
|
-
return [projectScopeTag(identity.projectId), legacyRepoScopeTag(identity.legacyRepoKey)];
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
export function formatProjectIdentityForStatus(identity: ProjectIdentity): string {
|
|
239
|
-
return `project:${identity.projectId} (from ${identity.basis}: ${identity.source})`;
|
|
240
|
-
}
|