akm-cli 0.9.0-beta.9 → 0.9.0-rc.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 +715 -0
- package/README.md +12 -4
- package/dist/akm +38 -0
- package/dist/akm-migrate-storage +38 -0
- package/dist/assets/help/help-improve.md +9 -6
- package/dist/assets/hints/cli-hints-full.md +6 -5
- package/dist/assets/profiles/default.json +9 -4
- package/dist/assets/profiles/frequent.json +1 -1
- package/dist/assets/profiles/memory-focus.json +1 -1
- package/dist/assets/profiles/proactive-maintenance.json +25 -0
- package/dist/assets/profiles/quick.json +1 -1
- package/dist/assets/profiles/recombine-only.json +21 -0
- package/dist/assets/profiles/reflect-distill.json +30 -0
- package/dist/assets/profiles/synthesize.json +15 -0
- package/dist/assets/profiles/thorough.json +1 -1
- package/dist/assets/prompts/consolidate-system.md +23 -0
- package/dist/assets/prompts/contradiction-judge.md +33 -0
- package/dist/assets/prompts/distill-knowledge-system.md +22 -0
- package/dist/assets/prompts/distill-lesson-system.md +36 -0
- package/dist/assets/prompts/extract-session.md +11 -3
- package/dist/assets/prompts/graph-extract-system.md +1 -0
- package/dist/assets/prompts/graph-extract-user-prompt.md +1 -1
- package/dist/assets/prompts/memory-infer-system.md +1 -0
- package/dist/assets/prompts/memory-infer-user.md +5 -0
- package/dist/assets/prompts/metadata-enhance-system.md +1 -0
- package/dist/assets/prompts/procedural-system.md +44 -0
- package/dist/assets/prompts/recombine-system.md +40 -0
- package/dist/assets/prompts/staleness-detect-system.md +6 -0
- package/dist/assets/prompts/validate-summary-judge.md +1 -0
- package/dist/assets/prompts/workflow-unit-preamble.md +26 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +39 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +40 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +43 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +43 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +40 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +43 -0
- package/dist/assets/templates/html/health.html +281 -111
- package/dist/assets/wiki/ingest-workflow-template.md +45 -16
- package/dist/assets/wiki/schema-template.md +4 -4
- package/dist/cli/clack.js +56 -0
- package/dist/cli/config-migrate.js +7 -1
- package/dist/cli/confirm.js +1 -1
- package/dist/cli/parse-args.js +46 -1
- package/dist/cli/shared.js +28 -0
- package/dist/cli.js +25 -21
- package/dist/commands/agent/agent-dispatch.js +3 -2
- package/dist/commands/agent/agent-support.js +0 -7
- package/dist/commands/agent/contribute-cli.js +26 -7
- package/dist/commands/config-cli.js +26 -13
- package/dist/commands/env/child-env.js +47 -0
- package/dist/commands/env/env-binding.js +95 -0
- package/dist/commands/env/env-cli.js +228 -292
- package/dist/commands/env/env.js +14 -67
- package/dist/commands/env/secret-cli.js +140 -138
- package/dist/commands/feedback-cli.js +156 -155
- package/dist/commands/graph/graph-cli.js +5 -13
- package/dist/commands/graph/graph.js +3 -3
- package/dist/commands/health/advisories.js +151 -0
- package/dist/commands/health/checks.js +103 -16
- package/dist/commands/health/html-report.js +447 -81
- package/dist/commands/health/improve-metrics.js +771 -0
- package/dist/commands/health/llm-usage.js +65 -0
- package/dist/commands/health/md-report.js +103 -0
- package/dist/commands/health/metrics.js +278 -0
- package/dist/commands/health/stash-exposure.js +46 -0
- package/dist/commands/health/surfaces.js +216 -0
- package/dist/commands/health/task-runs.js +135 -0
- package/dist/commands/health/types.js +26 -0
- package/dist/commands/health/windows.js +195 -0
- package/dist/commands/health.js +91 -1091
- package/dist/commands/improve/anti-collapse.js +170 -0
- package/dist/commands/improve/calibration.js +161 -0
- package/dist/commands/improve/collapse-detector.js +421 -0
- package/dist/commands/improve/consolidate/chunking.js +141 -0
- package/dist/commands/improve/consolidate/eligibility.js +64 -0
- package/dist/commands/improve/consolidate/merge.js +145 -0
- package/dist/commands/improve/consolidate/sanitize.js +231 -0
- package/dist/commands/{lint.js → improve/consolidate/types.js} +1 -1
- package/dist/commands/improve/consolidate.js +1295 -1277
- package/dist/commands/improve/dedup.js +482 -0
- package/dist/commands/improve/distill/content-repair.js +202 -0
- package/dist/commands/improve/distill/promote-memory.js +229 -0
- package/dist/commands/improve/distill/quality-gate.js +236 -0
- package/dist/commands/improve/distill-guards.js +127 -0
- package/dist/commands/improve/distill-promotion-policy.js +826 -167
- package/dist/commands/improve/distill.js +228 -605
- package/dist/commands/improve/eligibility.js +434 -0
- package/dist/commands/improve/encoding-salience.js +205 -0
- package/dist/commands/improve/extract-cli.js +179 -59
- package/dist/commands/improve/extract-prompt.js +54 -3
- package/dist/commands/improve/extract-watch.js +140 -0
- package/dist/commands/improve/extract.js +409 -43
- package/dist/commands/improve/feedback-valence.js +54 -0
- package/dist/commands/improve/hot-probation.js +45 -0
- package/dist/commands/improve/improve-auto-accept.js +157 -10
- package/dist/commands/improve/improve-cli.js +115 -73
- package/dist/commands/improve/improve-profiles.js +28 -8
- package/dist/commands/improve/improve-result-file.js +15 -25
- package/dist/commands/improve/improve-session.js +58 -0
- package/dist/commands/improve/improve.js +485 -2764
- package/dist/commands/improve/locks.js +154 -0
- package/dist/commands/improve/loop-stages.js +1100 -0
- package/dist/commands/improve/memory/memory-belief.js +14 -15
- package/dist/commands/improve/memory/memory-contradiction-detect.js +83 -60
- package/dist/commands/improve/memory/memory-improve.js +27 -27
- package/dist/commands/improve/outcome-loop.js +270 -0
- package/dist/commands/improve/preparation.js +2002 -0
- package/dist/commands/improve/proactive-maintenance.js +37 -35
- package/dist/commands/improve/procedural.js +398 -0
- package/dist/commands/improve/recombine.js +818 -0
- package/dist/commands/improve/reflect-noise.js +0 -0
- package/dist/commands/improve/reflect.js +206 -45
- package/dist/commands/improve/salience.js +455 -0
- package/dist/commands/improve/schema-similarity-gate.js +168 -0
- package/dist/commands/improve/shared.js +51 -0
- package/dist/commands/improve/triage.js +93 -0
- package/dist/commands/lint/agent-linter.js +19 -24
- package/dist/commands/lint/base-linter.js +173 -60
- package/dist/commands/lint/command-linter.js +19 -24
- package/dist/commands/lint/env-key-rules.js +38 -1
- package/dist/commands/lint/fact-linter.js +39 -0
- package/dist/commands/lint/index.js +31 -13
- package/dist/commands/lint/memory-linter.js +1 -1
- package/dist/commands/lint/registry.js +7 -2
- package/dist/commands/lint/task-linter.js +3 -3
- package/dist/commands/lint/workflow-linter.js +26 -1
- package/dist/commands/observability-cli.js +4 -4
- package/dist/commands/proposal/drain-policies.js +13 -4
- package/dist/commands/proposal/drain.js +45 -51
- package/dist/commands/proposal/legacy-import.js +115 -0
- package/dist/commands/proposal/proposal-cli.js +24 -34
- package/dist/commands/proposal/proposal.js +2 -1
- package/dist/commands/proposal/propose.js +8 -3
- package/dist/commands/proposal/repository.js +829 -0
- package/dist/commands/proposal/validators/proposal-quality-validators.js +9 -8
- package/dist/commands/proposal/validators/proposals.js +93 -895
- package/dist/commands/read/curate.js +410 -111
- package/dist/commands/read/knowledge.js +10 -3
- package/dist/commands/read/remember-cli.js +133 -138
- package/dist/commands/read/search-cli.js +15 -8
- package/dist/commands/read/search.js +22 -11
- package/dist/commands/read/show.js +106 -14
- package/dist/commands/registry-cli.js +76 -87
- package/dist/commands/remember.js +11 -12
- package/dist/commands/sources/add-cli.js +91 -95
- package/dist/commands/sources/history.js +1 -1
- package/dist/commands/sources/init.js +66 -18
- package/dist/commands/sources/installed-stashes.js +11 -3
- package/dist/commands/sources/migration-help.js +7 -4
- package/dist/commands/sources/schema-repair.js +44 -46
- package/dist/commands/sources/self-update.js +2 -2
- package/dist/commands/sources/source-add.js +7 -3
- package/dist/commands/sources/sources-cli.js +3 -3
- package/dist/commands/sources/stash-cli.js +19 -39
- package/dist/commands/sources/stash-skeleton.js +57 -8
- package/dist/commands/tasks/default-tasks.js +15 -2
- package/dist/commands/tasks/tasks-cli.js +20 -29
- package/dist/commands/tasks/tasks.js +39 -11
- package/dist/commands/wiki-cli.js +23 -38
- package/dist/commands/workflow-cli.js +291 -13
- package/dist/core/asset/asset-registry.js +3 -1
- package/dist/core/asset/asset-spec.js +79 -5
- package/dist/core/asset/frontmatter.js +188 -167
- package/dist/core/asset/markdown.js +8 -0
- package/dist/core/authoring-rules.js +92 -0
- package/dist/core/common.js +4 -23
- package/dist/core/concurrent.js +10 -1
- package/dist/core/config/config-io.js +10 -1
- package/dist/core/config/config-migration.js +18 -40
- package/dist/core/config/config-schema.js +403 -62
- package/dist/core/config/config-types.js +3 -3
- package/dist/core/config/config.js +67 -22
- package/dist/core/deep-merge.js +38 -0
- package/dist/core/errors.js +1 -0
- package/dist/core/eval/rank-metrics.js +113 -0
- package/dist/core/events.js +4 -7
- package/dist/core/improve-types.js +47 -8
- package/dist/core/json-schema.js +142 -0
- package/dist/core/logs-db.js +14 -75
- package/dist/core/parse.js +36 -16
- package/dist/core/paths.js +18 -18
- package/dist/core/standards/resolve-standards-context.js +87 -0
- package/dist/core/standards/resolve-stash-standards.js +99 -0
- package/dist/core/standards/resolve-type-conventions.js +66 -0
- package/dist/core/state/migrations.js +770 -0
- package/dist/core/state-db.js +132 -1126
- package/dist/core/structured.js +69 -0
- package/dist/core/time.js +53 -0
- package/dist/core/warn.js +21 -0
- package/dist/core/write-source.js +37 -0
- package/dist/indexer/db/db.js +261 -770
- package/dist/indexer/db/entry-mapper.js +41 -0
- package/dist/indexer/db/graph-db.js +129 -86
- package/dist/indexer/db/llm-cache.js +2 -2
- package/dist/indexer/db/schema.js +516 -0
- package/dist/indexer/ensure-index.js +36 -92
- package/dist/indexer/feedback/utility-policy.js +75 -0
- package/dist/indexer/graph/graph-boost.js +51 -41
- package/dist/indexer/graph/graph-extraction.js +207 -4
- package/dist/indexer/index-writer-lock.js +18 -11
- package/dist/indexer/index-written-assets.js +105 -0
- package/dist/indexer/indexer.js +182 -204
- package/dist/indexer/passes/dir-staleness.js +114 -0
- package/dist/indexer/passes/memory-inference.js +13 -5
- package/dist/indexer/passes/metadata.js +20 -0
- package/dist/indexer/read-preflight.js +23 -0
- package/dist/indexer/search/db-search.js +89 -13
- package/dist/indexer/search/fts-query.js +51 -0
- package/dist/indexer/search/ranking-contributors.js +95 -9
- package/dist/indexer/search/ranking.js +79 -3
- package/dist/indexer/search/search-fields.js +6 -0
- package/dist/indexer/search/search-source.js +32 -21
- package/dist/indexer/search/semantic-status.js +4 -0
- package/dist/indexer/walk/matchers.js +48 -0
- package/dist/indexer/walk/walker.js +21 -13
- package/dist/integrations/agent/builders.js +41 -13
- package/dist/integrations/agent/config.js +20 -59
- package/dist/integrations/agent/detect.js +9 -0
- package/dist/integrations/agent/index.js +3 -19
- package/dist/integrations/agent/model-aliases.js +16 -2
- package/dist/integrations/agent/profiles.js +79 -6
- package/dist/integrations/agent/prompts.js +75 -9
- package/dist/integrations/agent/runner-dispatch.js +83 -0
- package/dist/integrations/agent/runner.js +13 -9
- package/dist/integrations/agent/spawn.js +206 -81
- package/dist/integrations/harnesses/aider/agent-builder.js +113 -0
- package/dist/integrations/harnesses/aider/index.js +58 -0
- package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
- package/dist/integrations/harnesses/amazonq/agent-builder.js +153 -0
- package/dist/integrations/harnesses/amazonq/index.js +59 -0
- package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
- package/dist/integrations/harnesses/claude/agent-builder.js +46 -7
- package/dist/integrations/harnesses/claude/index.js +27 -23
- package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
- package/dist/integrations/harnesses/claude/session-log.js +10 -0
- package/dist/integrations/harnesses/codex/agent-builder.js +137 -0
- package/dist/integrations/harnesses/codex/index.js +63 -0
- package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
- package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
- package/dist/integrations/harnesses/copilot/index.js +60 -0
- package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
- package/dist/integrations/harnesses/gemini/agent-builder.js +121 -0
- package/dist/integrations/harnesses/gemini/index.js +60 -0
- package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
- package/dist/integrations/harnesses/index.js +28 -7
- package/dist/integrations/harnesses/opencode/agent-builder.js +1 -1
- package/dist/integrations/harnesses/opencode/index.js +17 -16
- package/dist/integrations/harnesses/opencode/session-log.js +173 -3
- package/dist/integrations/harnesses/opencode-sdk/harness.js +65 -0
- package/dist/integrations/harnesses/opencode-sdk/index.js +10 -34
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +642 -71
- package/dist/integrations/harnesses/openhands/agent-builder.js +126 -0
- package/dist/integrations/harnesses/openhands/index.js +58 -0
- package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
- package/dist/integrations/harnesses/pi/agent-builder.js +104 -0
- package/dist/integrations/harnesses/pi/index.js +58 -0
- package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
- package/dist/integrations/harnesses/types.js +8 -0
- package/dist/integrations/session-logs/index.js +40 -11
- package/dist/llm/call-ai.js +2 -2
- package/dist/llm/client.js +34 -11
- package/dist/llm/embedder.js +67 -4
- package/dist/llm/embedders/cache.js +3 -1
- package/dist/llm/embedders/deterministic.js +66 -0
- package/dist/llm/embedders/local.js +73 -3
- package/dist/llm/feature-gate.js +16 -15
- package/dist/llm/graph-extract.js +67 -44
- package/dist/llm/memory-infer-impl.js +138 -0
- package/dist/llm/memory-infer.js +1 -127
- package/dist/llm/metadata-enhance.js +44 -31
- package/dist/llm/structured-call.js +49 -0
- package/dist/migrate-storage-node.mjs +8 -0
- package/dist/output/context.js +5 -5
- package/dist/output/renderers.js +87 -15
- package/dist/output/shapes/curate.js +14 -2
- package/dist/output/shapes/helpers.js +0 -3
- package/dist/output/shapes/passthrough.js +6 -1
- package/dist/output/text/helpers.js +241 -2
- package/dist/output/text/workflow.js +4 -1
- package/dist/registry/providers/skills-sh.js +21 -147
- package/dist/registry/providers/static-index.js +15 -157
- package/dist/registry/resolve.js +27 -9
- package/dist/runtime.js +25 -1
- package/dist/schemas/akm-config.json +14225 -0
- package/dist/schemas/akm-workflow.json +328 -0
- package/dist/scripts/migrate-storage.js +2743 -8390
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +1652 -607
- package/dist/setup/detect.js +9 -0
- package/dist/setup/legacy-config.js +106 -0
- package/dist/setup/prompt.js +57 -0
- package/dist/setup/providers.js +14 -0
- package/dist/setup/registry-stash-loader.js +12 -0
- package/dist/setup/semantic-assets.js +124 -0
- package/dist/setup/setup.js +52 -1614
- package/dist/setup/steps/connection.js +734 -0
- package/dist/setup/steps/output.js +31 -0
- package/dist/setup/steps/platforms.js +124 -0
- package/dist/setup/steps/semantic.js +27 -0
- package/dist/setup/steps/sources.js +222 -0
- package/dist/setup/steps/stashdir.js +42 -0
- package/dist/setup/steps/tasks.js +152 -0
- package/dist/sources/include.js +6 -2
- package/dist/sources/providers/filesystem.js +0 -1
- package/dist/sources/providers/git-install.js +210 -0
- package/dist/sources/providers/git-provider.js +234 -0
- package/dist/sources/providers/git-stash.js +248 -0
- package/dist/sources/providers/git.js +10 -661
- package/dist/sources/providers/npm.js +2 -6
- package/dist/sources/providers/provider-utils.js +13 -7
- package/dist/sources/providers/sync-from-ref.js +9 -1
- package/dist/sources/providers/website.js +9 -5
- package/dist/sources/website-ingest.js +187 -29
- package/dist/sources/wiki-fetchers/registry.js +53 -0
- package/dist/sources/wiki-fetchers/youtube.js +239 -0
- package/dist/storage/database.js +45 -10
- package/dist/storage/managed-db.js +82 -0
- package/dist/storage/repositories/canaries-repository.js +107 -0
- package/dist/storage/repositories/consolidation-repository.js +38 -0
- package/dist/storage/repositories/embeddings-repository.js +72 -0
- package/dist/storage/repositories/events-repository.js +187 -0
- package/dist/storage/repositories/extract-sessions-repository.js +96 -0
- package/dist/storage/repositories/improve-runs-repository.js +146 -0
- package/dist/storage/repositories/index-db.js +14 -8
- package/dist/storage/repositories/proposals-repository.js +220 -0
- package/dist/storage/repositories/recombine-repository.js +213 -0
- package/dist/storage/repositories/registry-cache.js +93 -0
- package/dist/storage/repositories/registry-index-cache-repository.js +46 -0
- package/dist/storage/repositories/task-history-repository.js +93 -0
- package/dist/storage/repositories/workflow-runs-repository.js +189 -1
- package/dist/storage/sqlite-pragmas.js +146 -0
- package/dist/tasks/backends/cron.js +1 -1
- package/dist/tasks/backends/index.js +9 -0
- package/dist/tasks/backends/launchd.js +1 -1
- package/dist/tasks/backends/schtasks.js +1 -1
- package/dist/tasks/{resolveAkmBin.js → resolve-akm-bin.js} +2 -2
- package/dist/tasks/runner.js +15 -13
- package/dist/text-import-hook.mjs +1 -1
- package/dist/wiki/wiki.js +52 -11
- package/dist/workflows/authoring/authoring.js +123 -10
- package/dist/workflows/authoring/workflow-program-template.yaml +31 -0
- package/dist/workflows/cli.js +5 -0
- package/dist/workflows/db.js +138 -4
- package/dist/workflows/exec/brief.js +484 -0
- package/dist/workflows/exec/native-executor.js +975 -0
- package/dist/workflows/exec/param-secrets.js +115 -0
- package/dist/workflows/exec/report.js +1295 -0
- package/dist/workflows/exec/run-workflow.js +596 -0
- package/dist/workflows/exec/scheduler.js +100 -0
- package/dist/workflows/exec/step-work.js +1156 -0
- package/dist/workflows/exec/unit-writer.js +23 -0
- package/dist/workflows/exec/watch.js +116 -0
- package/dist/workflows/exec/worktree.js +171 -0
- package/dist/workflows/ir/compile.js +388 -0
- package/dist/workflows/ir/params.js +54 -0
- package/dist/workflows/ir/plan-hash.js +33 -0
- package/dist/workflows/ir/schema.js +4 -0
- package/dist/workflows/parser.js +3 -1
- package/dist/workflows/program/expressions.js +369 -0
- package/dist/workflows/program/parser.js +760 -0
- package/dist/workflows/program/project.js +105 -0
- package/dist/workflows/program/schema.js +54 -0
- package/dist/workflows/renderer.js +82 -5
- package/dist/workflows/runtime/agent-identity.js +59 -14
- package/dist/workflows/runtime/runs.js +248 -153
- package/dist/workflows/runtime/unit-checkin.js +45 -0
- package/dist/workflows/runtime/workflow-asset-loader.js +188 -0
- package/dist/workflows/validate-summary.js +26 -10
- package/dist/workflows/validator.js +1 -1
- package/docs/README.md +69 -18
- package/docs/data-and-telemetry.md +7 -5
- package/docs/migration/release-notes/0.7.0.md +1 -1
- package/docs/migration/release-notes/0.9.0-beta.60.md +19 -0
- package/docs/migration/release-notes/0.9.0.md +39 -0
- package/package.json +10 -10
- package/dist/assets/tasks/core/update-stashes.yml +0 -4
- package/dist/commands/db-cli.js +0 -23
- package/dist/indexer/db/db-backup.js +0 -376
- package/dist/indexer/passes/staleness-detect.js +0 -488
|
@@ -16,7 +16,8 @@ import { isHttpUrl, isWithin, tryReadStdinText } from "../../core/common.js";
|
|
|
16
16
|
import { loadConfig } from "../../core/config/config.js";
|
|
17
17
|
import { UsageError } from "../../core/errors.js";
|
|
18
18
|
import { commitWriteTargetBoundary, formatRefForMessage, resolveWriteTarget, writeAssetToSource, } from "../../core/write-source.js";
|
|
19
|
-
import {
|
|
19
|
+
import { indexWrittenAssets } from "../../indexer/index-written-assets.js";
|
|
20
|
+
import { fetchWebsiteMarkdownSnapshot, shouldAllowPrivateWebsiteUrlForTests } from "../../sources/website-ingest.js";
|
|
20
21
|
const MAX_CAPTURED_ASSET_SLUG_LENGTH = 64;
|
|
21
22
|
// ── Asset-name normalisation ─────────────────────────────────────────────────
|
|
22
23
|
/**
|
|
@@ -101,10 +102,13 @@ export function readKnowledgeContent(source) {
|
|
|
101
102
|
* URLs are fetched via `fetchWebsiteMarkdownSnapshot`; local sources delegate
|
|
102
103
|
* to `readKnowledgeContent`.
|
|
103
104
|
*/
|
|
104
|
-
export async function readKnowledgeInput(source) {
|
|
105
|
+
export async function readKnowledgeInput(source, options) {
|
|
105
106
|
if (!isHttpUrl(source))
|
|
106
107
|
return readKnowledgeContent(source);
|
|
107
|
-
const snapshot = await fetchWebsiteMarkdownSnapshot(source
|
|
108
|
+
const snapshot = await fetchWebsiteMarkdownSnapshot(source, {
|
|
109
|
+
stashDir: options?.stashDir,
|
|
110
|
+
allowPrivateHosts: options?.allowPrivateHosts ?? shouldAllowPrivateWebsiteUrlForTests(source),
|
|
111
|
+
});
|
|
108
112
|
return { content: snapshot.content, preferredName: snapshot.preferredName };
|
|
109
113
|
}
|
|
110
114
|
// ── Asset writing ────────────────────────────────────────────────────────────
|
|
@@ -141,6 +145,9 @@ export async function writeMarkdownAsset(options) {
|
|
|
141
145
|
// 0.9.0 (issue #507): single batch commit at the write boundary for git
|
|
142
146
|
// targets. No-op for filesystem/primary-stash targets.
|
|
143
147
|
commitWriteTargetBoundary(target, `Update ${formatRefForMessage(ref)}`);
|
|
148
|
+
// Write-path indexing: the asset is searchable immediately. Fail-open; reads
|
|
149
|
+
// no longer trigger reindexes, so keeping the index current is the writer's job.
|
|
150
|
+
await indexWrittenAssets(source.path, [result.path]);
|
|
144
151
|
return {
|
|
145
152
|
ref: result.ref,
|
|
146
153
|
path: result.path,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
import {
|
|
5
|
-
import { output, parseAllFlagValues
|
|
4
|
+
import { getStringArg } from "../../cli/parse-args.js";
|
|
5
|
+
import { defineJsonCommand, output, parseAllFlagValues } from "../../cli/shared.js";
|
|
6
6
|
import { UsageError } from "../../core/errors.js";
|
|
7
7
|
import { appendEvent } from "../../core/events.js";
|
|
8
8
|
import { buildMemoryFrontmatter, parseDuration, readMemoryContent, resolveRememberContentArg, runAutoHeuristics, runLlmEnrich, } from "../remember.js";
|
|
@@ -26,7 +26,7 @@ async function fetchSimilarMemories(query, excludeRef) {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
// ── Command definition ────────────────────────────────────────────────────────
|
|
29
|
-
export const rememberCommand =
|
|
29
|
+
export const rememberCommand = defineJsonCommand({
|
|
30
30
|
meta: {
|
|
31
31
|
name: "remember",
|
|
32
32
|
description: "Record a memory in the default stash",
|
|
@@ -60,7 +60,7 @@ export const rememberCommand = defineCommand({
|
|
|
60
60
|
},
|
|
61
61
|
expires: {
|
|
62
62
|
type: "string",
|
|
63
|
-
description: "Expiry duration shorthand
|
|
63
|
+
description: "Expiry duration shorthand — e.g. 30d, 12h, 5m (minutes), 3M (months). Resolved to an ISO date.",
|
|
64
64
|
},
|
|
65
65
|
source: {
|
|
66
66
|
type: "string",
|
|
@@ -102,141 +102,42 @@ export const rememberCommand = defineCommand({
|
|
|
102
102
|
},
|
|
103
103
|
},
|
|
104
104
|
async run({ args }) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (!hasStructuredArgs) {
|
|
129
|
-
// Phase 1B / Rec 7: even the zero-flag hot-path emits
|
|
130
|
-
// `captureMode: hot` + `beliefState: asserted` so user-supplied
|
|
131
|
-
// memories outrank background-derived ones during ranking.
|
|
132
|
-
const frontmatterBlock = buildMemoryFrontmatter({
|
|
133
|
-
captureMode: "hot",
|
|
134
|
-
beliefState: "asserted",
|
|
135
|
-
});
|
|
136
|
-
const contentWithFrontmatter = `${frontmatterBlock}\n${body}`;
|
|
137
|
-
// Derive the asset slug from the body (not the frontmatter block);
|
|
138
|
-
// otherwise inferAssetName would key off the leading `---` delimiter.
|
|
139
|
-
const result = await writeMarkdownAsset({
|
|
140
|
-
type: "memory",
|
|
141
|
-
content: contentWithFrontmatter,
|
|
142
|
-
name: args.name,
|
|
143
|
-
fallbackPrefix: "memory",
|
|
144
|
-
preferredName: inferAssetName(body, "memory"),
|
|
145
|
-
force: args.force,
|
|
146
|
-
target: args.target,
|
|
147
|
-
path: args.path,
|
|
148
|
-
});
|
|
149
|
-
appendEvent({
|
|
150
|
-
eventType: "remember",
|
|
151
|
-
ref: result.ref,
|
|
152
|
-
metadata: { path: result.path, force: args.force === true },
|
|
153
|
-
});
|
|
154
|
-
if (args.showSimilar) {
|
|
155
|
-
const similar = await fetchSimilarMemories(body.slice(0, 500), result.ref);
|
|
156
|
-
output("remember", { ok: true, ...result, similar });
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
output("remember", { ok: true, ...result });
|
|
160
|
-
}
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
// ── Accumulate metadata from all three modes ──────────────────────────
|
|
164
|
-
// Start with CLI args (Mode 1: always)
|
|
165
|
-
const tags = [...rawTags];
|
|
166
|
-
// --description is persisted as-is; LLM enrichment may fill it if absent.
|
|
167
|
-
let description = args.description || undefined;
|
|
168
|
-
let source = args.source;
|
|
169
|
-
let observed_at;
|
|
170
|
-
let expires;
|
|
171
|
-
let subjective;
|
|
172
|
-
// Resolve --expires to an ISO date string
|
|
173
|
-
if (args.expires) {
|
|
174
|
-
const durationMs = parseDuration(args.expires);
|
|
175
|
-
const expiresDate = new Date(Date.now() + durationMs);
|
|
176
|
-
expires = expiresDate.toISOString().slice(0, 10);
|
|
177
|
-
}
|
|
178
|
-
// Mode 2: --auto heuristics
|
|
179
|
-
if (args.auto) {
|
|
180
|
-
const auto = runAutoHeuristics(body);
|
|
181
|
-
for (const t of auto.tags) {
|
|
182
|
-
if (!tags.includes(t))
|
|
183
|
-
tags.push(t);
|
|
184
|
-
}
|
|
185
|
-
if (!source && auto.source)
|
|
186
|
-
source = auto.source;
|
|
187
|
-
if (!observed_at && auto.observed_at)
|
|
188
|
-
observed_at = auto.observed_at;
|
|
189
|
-
if (!subjective && auto.subjective)
|
|
190
|
-
subjective = auto.subjective;
|
|
191
|
-
}
|
|
192
|
-
// Mode 3: --enrich LLM (fail-soft)
|
|
193
|
-
if (args.enrich) {
|
|
194
|
-
const enriched = await runLlmEnrich(body);
|
|
195
|
-
for (const t of enriched.tags) {
|
|
196
|
-
if (!tags.includes(t))
|
|
197
|
-
tags.push(t);
|
|
198
|
-
}
|
|
199
|
-
if (!description && enriched.description)
|
|
200
|
-
description = enriched.description;
|
|
201
|
-
if (!observed_at && enriched.observed_at)
|
|
202
|
-
observed_at = enriched.observed_at;
|
|
203
|
-
}
|
|
204
|
-
// ── Required-field check (before any write) ───────────────────────────
|
|
205
|
-
// Tags remain required when the user explicitly asked for tag-bearing
|
|
206
|
-
// metadata (--tag / --enrich / --description / --source / --expires).
|
|
207
|
-
// `--auto` alone is allowed even when its heuristics derive zero tags.
|
|
208
|
-
// Scope-only writes (`akm remember "..." --user u1`) also skip this
|
|
209
|
-
// check — scope is independent metadata and a memory with only scope is
|
|
210
|
-
// valid.
|
|
211
|
-
const missing = [];
|
|
212
|
-
if (hasTagRequiringArgs && tags.length === 0)
|
|
213
|
-
missing.push("tags");
|
|
214
|
-
if (missing.length > 0) {
|
|
215
|
-
throw new UsageError(`Memory is missing required frontmatter field(s): ${missing.join(", ")}. ` +
|
|
216
|
-
"Provide them via --tag <value>, --auto (heuristics), or --enrich (LLM).");
|
|
217
|
-
}
|
|
218
|
-
// ── Build frontmatter and write ───────────────────────────────────────
|
|
219
|
-
// Phase 1B / Rec 7: the hot-path CLI write always marks the memory as
|
|
220
|
-
// `captureMode: hot` and `beliefState: asserted`. Ranking applies a
|
|
221
|
-
// hot-capture boost so user-supplied memories outrank otherwise-equal
|
|
222
|
-
// background-derived ones.
|
|
105
|
+
const body = readMemoryContent(resolveRememberContentArg(args.content));
|
|
106
|
+
// `--name` is a flat name; subdirectory placement is `--path`'s job.
|
|
107
|
+
assertFlatAssetName(args.name);
|
|
108
|
+
// Determine if the user has requested any structured metadata mode.
|
|
109
|
+
// Collect all --tag occurrences directly from process.argv because citty
|
|
110
|
+
// only exposes the last value for repeated string flags.
|
|
111
|
+
const rawTags = parseAllFlagValues("--tag");
|
|
112
|
+
// Collect scope flags. Scope alone counts as structured metadata so we
|
|
113
|
+
// emit frontmatter, but it does NOT trigger the "tags required" check —
|
|
114
|
+
// memory + scope (no tags) is a valid combination for multi-tenant use.
|
|
115
|
+
const scopeFields = {};
|
|
116
|
+
for (const k of ["user", "agent", "run", "channel"]) {
|
|
117
|
+
const v = getStringArg(args, k);
|
|
118
|
+
if (v)
|
|
119
|
+
scopeFields[k] = v;
|
|
120
|
+
}
|
|
121
|
+
const hasScope = Object.keys(scopeFields).length > 0;
|
|
122
|
+
const hasTagRequiringArgs = rawTags.length > 0 || !!args.expires || !!args.source || !!args.description;
|
|
123
|
+
const hasStructuredArgs = hasTagRequiringArgs || hasScope || args.auto;
|
|
124
|
+
if (!hasStructuredArgs) {
|
|
125
|
+
// Phase 1B / Rec 7: even the zero-flag hot-path emits
|
|
126
|
+
// `captureMode: hot` + `beliefState: asserted` so user-supplied
|
|
127
|
+
// memories outrank background-derived ones during ranking.
|
|
223
128
|
const frontmatterBlock = buildMemoryFrontmatter({
|
|
224
|
-
description,
|
|
225
|
-
tags,
|
|
226
|
-
source,
|
|
227
|
-
observed_at,
|
|
228
|
-
expires,
|
|
229
|
-
subjective,
|
|
230
129
|
captureMode: "hot",
|
|
231
130
|
beliefState: "asserted",
|
|
232
|
-
...(hasScope ? { scope: scopeFields } : {}),
|
|
233
131
|
});
|
|
234
132
|
const contentWithFrontmatter = `${frontmatterBlock}\n${body}`;
|
|
133
|
+
// Derive the asset slug from the body (not the frontmatter block);
|
|
134
|
+
// otherwise inferAssetName would key off the leading `---` delimiter.
|
|
235
135
|
const result = await writeMarkdownAsset({
|
|
236
136
|
type: "memory",
|
|
237
137
|
content: contentWithFrontmatter,
|
|
238
138
|
name: args.name,
|
|
239
139
|
fallbackPrefix: "memory",
|
|
140
|
+
preferredName: inferAssetName(body, "memory"),
|
|
240
141
|
force: args.force,
|
|
241
142
|
target: args.target,
|
|
242
143
|
path: args.path,
|
|
@@ -244,22 +145,116 @@ export const rememberCommand = defineCommand({
|
|
|
244
145
|
appendEvent({
|
|
245
146
|
eventType: "remember",
|
|
246
147
|
ref: result.ref,
|
|
247
|
-
metadata: {
|
|
248
|
-
path: result.path,
|
|
249
|
-
force: args.force === true,
|
|
250
|
-
tagCount: tags.length,
|
|
251
|
-
enriched: args.enrich === true,
|
|
252
|
-
auto: args.auto === true,
|
|
253
|
-
...(hasScope ? { scope: scopeFields } : {}),
|
|
254
|
-
},
|
|
148
|
+
metadata: { path: result.path, force: args.force === true },
|
|
255
149
|
});
|
|
256
150
|
if (args.showSimilar) {
|
|
257
|
-
const similar = await fetchSimilarMemories(
|
|
151
|
+
const similar = await fetchSimilarMemories(body.slice(0, 500), result.ref);
|
|
258
152
|
output("remember", { ok: true, ...result, similar });
|
|
259
153
|
}
|
|
260
154
|
else {
|
|
261
155
|
output("remember", { ok: true, ...result });
|
|
262
156
|
}
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
// ── Accumulate metadata from all three modes ──────────────────────────
|
|
160
|
+
// Start with CLI args (Mode 1: always)
|
|
161
|
+
const tags = [...rawTags];
|
|
162
|
+
// --description is persisted as-is; LLM enrichment may fill it if absent.
|
|
163
|
+
let description = args.description || undefined;
|
|
164
|
+
let source = args.source;
|
|
165
|
+
let observed_at;
|
|
166
|
+
let expires;
|
|
167
|
+
let subjective;
|
|
168
|
+
// Resolve --expires to an ISO date string
|
|
169
|
+
if (args.expires) {
|
|
170
|
+
const durationMs = parseDuration(args.expires);
|
|
171
|
+
const expiresDate = new Date(Date.now() + durationMs);
|
|
172
|
+
expires = expiresDate.toISOString().slice(0, 10);
|
|
173
|
+
}
|
|
174
|
+
// Mode 2: --auto heuristics
|
|
175
|
+
if (args.auto) {
|
|
176
|
+
const auto = runAutoHeuristics(body);
|
|
177
|
+
for (const t of auto.tags) {
|
|
178
|
+
if (!tags.includes(t))
|
|
179
|
+
tags.push(t);
|
|
180
|
+
}
|
|
181
|
+
if (!source && auto.source)
|
|
182
|
+
source = auto.source;
|
|
183
|
+
if (!observed_at && auto.observed_at)
|
|
184
|
+
observed_at = auto.observed_at;
|
|
185
|
+
if (!subjective && auto.subjective)
|
|
186
|
+
subjective = auto.subjective;
|
|
187
|
+
}
|
|
188
|
+
// Mode 3: --enrich LLM (fail-soft)
|
|
189
|
+
if (args.enrich) {
|
|
190
|
+
const enriched = await runLlmEnrich(body);
|
|
191
|
+
for (const t of enriched.tags) {
|
|
192
|
+
if (!tags.includes(t))
|
|
193
|
+
tags.push(t);
|
|
194
|
+
}
|
|
195
|
+
if (!description && enriched.description)
|
|
196
|
+
description = enriched.description;
|
|
197
|
+
if (!observed_at && enriched.observed_at)
|
|
198
|
+
observed_at = enriched.observed_at;
|
|
199
|
+
}
|
|
200
|
+
// ── Required-field check (before any write) ───────────────────────────
|
|
201
|
+
// Tags remain required when the user explicitly asked for tag-bearing
|
|
202
|
+
// metadata (--tag / --enrich / --description / --source / --expires).
|
|
203
|
+
// `--auto` alone is allowed even when its heuristics derive zero tags.
|
|
204
|
+
// Scope-only writes (`akm remember "..." --user u1`) also skip this
|
|
205
|
+
// check — scope is independent metadata and a memory with only scope is
|
|
206
|
+
// valid.
|
|
207
|
+
const missing = [];
|
|
208
|
+
if (hasTagRequiringArgs && tags.length === 0)
|
|
209
|
+
missing.push("tags");
|
|
210
|
+
if (missing.length > 0) {
|
|
211
|
+
throw new UsageError(`Memory is missing required frontmatter field(s): ${missing.join(", ")}. ` +
|
|
212
|
+
"Provide them via --tag <value>, --auto (heuristics), or --enrich (LLM).");
|
|
213
|
+
}
|
|
214
|
+
// ── Build frontmatter and write ───────────────────────────────────────
|
|
215
|
+
// Phase 1B / Rec 7: the hot-path CLI write always marks the memory as
|
|
216
|
+
// `captureMode: hot` and `beliefState: asserted`. Ranking applies a
|
|
217
|
+
// hot-capture boost so user-supplied memories outrank otherwise-equal
|
|
218
|
+
// background-derived ones.
|
|
219
|
+
const frontmatterBlock = buildMemoryFrontmatter({
|
|
220
|
+
description,
|
|
221
|
+
tags,
|
|
222
|
+
source,
|
|
223
|
+
observed_at,
|
|
224
|
+
expires,
|
|
225
|
+
subjective,
|
|
226
|
+
captureMode: "hot",
|
|
227
|
+
beliefState: "asserted",
|
|
228
|
+
...(hasScope ? { scope: scopeFields } : {}),
|
|
229
|
+
});
|
|
230
|
+
const contentWithFrontmatter = `${frontmatterBlock}\n${body}`;
|
|
231
|
+
const result = await writeMarkdownAsset({
|
|
232
|
+
type: "memory",
|
|
233
|
+
content: contentWithFrontmatter,
|
|
234
|
+
name: args.name,
|
|
235
|
+
fallbackPrefix: "memory",
|
|
236
|
+
force: args.force,
|
|
237
|
+
target: args.target,
|
|
238
|
+
path: args.path,
|
|
239
|
+
});
|
|
240
|
+
appendEvent({
|
|
241
|
+
eventType: "remember",
|
|
242
|
+
ref: result.ref,
|
|
243
|
+
metadata: {
|
|
244
|
+
path: result.path,
|
|
245
|
+
force: args.force === true,
|
|
246
|
+
tagCount: tags.length,
|
|
247
|
+
enriched: args.enrich === true,
|
|
248
|
+
auto: args.auto === true,
|
|
249
|
+
...(hasScope ? { scope: scopeFields } : {}),
|
|
250
|
+
},
|
|
263
251
|
});
|
|
252
|
+
if (args.showSimilar) {
|
|
253
|
+
const similar = await fetchSimilarMemories((body ?? args.content ?? "").slice(0, 500), result.ref);
|
|
254
|
+
output("remember", { ok: true, ...result, similar });
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
output("remember", { ok: true, ...result });
|
|
258
|
+
}
|
|
264
259
|
},
|
|
265
260
|
});
|
|
@@ -21,13 +21,15 @@ import { getHyphenatedBoolean, getOutputMode, parseFlagValue } from "../../outpu
|
|
|
21
21
|
import { akmCurate } from "./curate.js";
|
|
22
22
|
import { akmSearch, parseBeliefFilterMode, parseScopeFilterFlags, parseSearchSource } from "./search.js";
|
|
23
23
|
import { akmShowUnified } from "./show.js";
|
|
24
|
-
// AKM_EVENT_SOURCE attributes a query to a `user` invocation
|
|
25
|
-
// `improve` loop so the event log can distinguish
|
|
26
|
-
// treated as unset.
|
|
24
|
+
// AKM_EVENT_SOURCE attributes a query to a `user` invocation, the internal
|
|
25
|
+
// `improve` loop, or the `task` runner so the event log can distinguish
|
|
26
|
+
// genuine demand from machine traffic; any other value is treated as unset.
|
|
27
27
|
function resolveEventSource() {
|
|
28
28
|
const raw = process.env.AKM_EVENT_SOURCE;
|
|
29
29
|
if (raw === "improve")
|
|
30
30
|
return "improve";
|
|
31
|
+
if (raw === "task")
|
|
32
|
+
return "task";
|
|
31
33
|
if (raw === "user")
|
|
32
34
|
return "user";
|
|
33
35
|
return undefined;
|
|
@@ -63,6 +65,11 @@ export const searchCommand = defineJsonCommand({
|
|
|
63
65
|
description: "Disable the automatic project-context ranking boost (also disabled by AKM_DISABLE_PROJECT_CONTEXT=1).",
|
|
64
66
|
default: false,
|
|
65
67
|
},
|
|
68
|
+
"include-sessions": {
|
|
69
|
+
type: "boolean",
|
|
70
|
+
description: "Include session assets (excluded from default search results via config.search.defaultExcludeTypes).",
|
|
71
|
+
default: false,
|
|
72
|
+
},
|
|
66
73
|
},
|
|
67
74
|
async run({ args }) {
|
|
68
75
|
const query = (args.query ?? "").trim();
|
|
@@ -79,10 +86,7 @@ export const searchCommand = defineJsonCommand({
|
|
|
79
86
|
const includeProposed = args["include-proposed"] === true;
|
|
80
87
|
const belief = parseBeliefFilterMode(typeof args.belief === "string" ? args.belief : undefined);
|
|
81
88
|
const noProjectContext = getHyphenatedBoolean(args, "no-project-context");
|
|
82
|
-
|
|
83
|
-
// threading the flag through the entire call stack.
|
|
84
|
-
if (noProjectContext)
|
|
85
|
-
process.env.AKM_DISABLE_PROJECT_CONTEXT = "1";
|
|
89
|
+
const includeSessions = args["include-sessions"];
|
|
86
90
|
const result = await akmSearch({
|
|
87
91
|
query,
|
|
88
92
|
type,
|
|
@@ -91,6 +95,9 @@ export const searchCommand = defineJsonCommand({
|
|
|
91
95
|
filters,
|
|
92
96
|
includeProposed,
|
|
93
97
|
belief,
|
|
98
|
+
includeSessions,
|
|
99
|
+
disableProjectContext: noProjectContext,
|
|
100
|
+
disableScopedUtility: noProjectContext,
|
|
94
101
|
eventSource: resolveEventSource(),
|
|
95
102
|
});
|
|
96
103
|
output("search", result);
|
|
@@ -124,7 +131,7 @@ export const curateCommand = defineJsonCommand({
|
|
|
124
131
|
const limitParsed = parsePositiveIntFlag(args.limit ?? undefined);
|
|
125
132
|
const limit = limitParsed && limitParsed > 0 ? limitParsed : 4;
|
|
126
133
|
const source = parseSearchSource(args.source ?? "stash");
|
|
127
|
-
const curated = await akmCurate({ query: args.query, type, limit, source });
|
|
134
|
+
const curated = await akmCurate({ query: args.query, type, limit, source, eventSource: resolveEventSource() });
|
|
128
135
|
output("curate", curated);
|
|
129
136
|
},
|
|
130
137
|
});
|
|
@@ -16,14 +16,14 @@ import { rethrowIfTestIsolationError, UsageError } from "../../core/errors.js";
|
|
|
16
16
|
import { appendEvent } from "../../core/events.js";
|
|
17
17
|
import { isTransientStashPath } from "../../core/paths.js";
|
|
18
18
|
import { bumpUtilityScoresBatch, getEntryIdByFilePath } from "../../indexer/db/db.js";
|
|
19
|
+
import { resolveReadSources } from "../../indexer/read-preflight.js";
|
|
19
20
|
import { searchLocal } from "../../indexer/search/db-search.js";
|
|
20
|
-
import { resolveSourceEntries } from "../../indexer/search/search-source.js";
|
|
21
21
|
import { getCurrentWorkflowScopeKey } from "../../workflows/authoring/scope-key.js";
|
|
22
22
|
// Eagerly import source providers to trigger self-registration before the
|
|
23
23
|
// indexer or path-resolution code runs.
|
|
24
24
|
import "../../sources/providers/index.js";
|
|
25
25
|
import { insertUsageEvent } from "../../indexer/usage/usage-events.js";
|
|
26
|
-
import { withIndexDb } from "../../storage/repositories/index-db.js";
|
|
26
|
+
import { TELEMETRY_BUSY_TIMEOUT_MS, withIndexDb } from "../../storage/repositories/index-db.js";
|
|
27
27
|
import { searchRegistry } from "./registry-search.js";
|
|
28
28
|
const DEFAULT_LIMIT = 20;
|
|
29
29
|
export async function akmSearch(input) {
|
|
@@ -57,7 +57,7 @@ export async function akmSearch(input) {
|
|
|
57
57
|
else {
|
|
58
58
|
source = parsedSource;
|
|
59
59
|
}
|
|
60
|
-
let allSources =
|
|
60
|
+
let allSources = resolveReadSources(undefined, config).sources;
|
|
61
61
|
// When a named source was requested, narrow the sources list to just that entry.
|
|
62
62
|
// `resolveSourceEntries` sets `registryId` to `entry.name` for each config source.
|
|
63
63
|
if (namedSourceName !== undefined) {
|
|
@@ -108,6 +108,9 @@ export async function akmSearch(input) {
|
|
|
108
108
|
// Without this, the index (which spans every configured source)
|
|
109
109
|
// would leak hits from sources the caller did not request.
|
|
110
110
|
restrictToSources: namedSourceName !== undefined,
|
|
111
|
+
includeExcludedTypes: input.includeSessions === true,
|
|
112
|
+
disableProjectContext: input.disableProjectContext === true,
|
|
113
|
+
disableScopedUtility: input.disableScopedUtility === true,
|
|
111
114
|
});
|
|
112
115
|
const registryResult = source === "stash" ? undefined : await searchRegistry(query, { limit, registries: config.registries });
|
|
113
116
|
if (source === "stash") {
|
|
@@ -122,8 +125,9 @@ export async function akmSearch(input) {
|
|
|
122
125
|
warnings: localResult?.warnings?.length ? localResult.warnings : undefined,
|
|
123
126
|
timing: { totalMs: Date.now() - t0, rankMs: localResult?.rankMs, embedMs: localResult?.embedMs },
|
|
124
127
|
};
|
|
125
|
-
if (!input.skipLogging)
|
|
126
|
-
logSearchEvent(query, response, localResult?.mode ?? "keyword", input.eventSource);
|
|
128
|
+
if (!input.skipLogging) {
|
|
129
|
+
logSearchEvent(query, response, localResult?.mode ?? "keyword", input.eventSource, input.disableScopedUtility === true);
|
|
130
|
+
}
|
|
127
131
|
return response;
|
|
128
132
|
}
|
|
129
133
|
const registryHits = (registryResult?.hits ?? []).map((hit) => {
|
|
@@ -158,7 +162,7 @@ export async function akmSearch(input) {
|
|
|
158
162
|
timing: { totalMs: Date.now() - t0 },
|
|
159
163
|
};
|
|
160
164
|
if (!input.skipLogging)
|
|
161
|
-
logSearchEvent(query, response, undefined, input.eventSource);
|
|
165
|
+
logSearchEvent(query, response, undefined, input.eventSource, input.disableScopedUtility === true);
|
|
162
166
|
return response;
|
|
163
167
|
}
|
|
164
168
|
// source === "both"
|
|
@@ -176,7 +180,7 @@ export async function akmSearch(input) {
|
|
|
176
180
|
timing: { totalMs: Date.now() - t0 },
|
|
177
181
|
};
|
|
178
182
|
if (!input.skipLogging)
|
|
179
|
-
logSearchEvent(query, response, undefined, input.eventSource);
|
|
183
|
+
logSearchEvent(query, response, undefined, input.eventSource, input.disableScopedUtility === true);
|
|
180
184
|
return response;
|
|
181
185
|
}
|
|
182
186
|
/**
|
|
@@ -211,7 +215,7 @@ function resolveEntryIds(db, hits) {
|
|
|
211
215
|
* Per-entry events are recorded only for stash hits because registry hits
|
|
212
216
|
* have no local entry_id to reference.
|
|
213
217
|
*/
|
|
214
|
-
function logSearchEvent(query, response, mode = "keyword", eventSource = "user") {
|
|
218
|
+
function logSearchEvent(query, response, mode = "keyword", eventSource = "user", disableScopedUtility = false) {
|
|
215
219
|
// Emit a structured event to events.jsonl so workflow-trace consumers
|
|
216
220
|
// detect akm search invocations without relying on stdout scraping.
|
|
217
221
|
const stashHits = response.hits.filter((h) => h.type !== "registry");
|
|
@@ -223,6 +227,9 @@ function logSearchEvent(query, response, mode = "keyword", eventSource = "user")
|
|
|
223
227
|
metadata: { query, hitCount: stashHits.length, resultRefs: allResultRefs, mode },
|
|
224
228
|
});
|
|
225
229
|
try {
|
|
230
|
+
// Short busy timeout: telemetry must never stall the search result behind
|
|
231
|
+
// a background reindex holding the index.db write lock (30s default wait).
|
|
232
|
+
// Under contention these usage hints are skipped, not waited for.
|
|
226
233
|
withIndexDb((db) => {
|
|
227
234
|
const resolved = resolveEntryIds(db, stashHits.slice(0, 50));
|
|
228
235
|
for (const { entryId, ref } of resolved) {
|
|
@@ -236,12 +243,16 @@ function logSearchEvent(query, response, mode = "keyword", eventSource = "user")
|
|
|
236
243
|
}
|
|
237
244
|
// Bump utility scores for all resolved entries (MemRL retrieval signal).
|
|
238
245
|
// The indexer overwrites these at next reindex; bumps are temporary hints.
|
|
239
|
-
|
|
246
|
+
// Gated to user-sourced events: pipeline searches (improve probes, task
|
|
247
|
+
// runner) must not feed the utility signal (meta-review 05 DRIFT-6 —
|
|
248
|
+
// the bump previously fired unconditionally, so even correctly-tagged
|
|
249
|
+
// machine traffic inflated utility).
|
|
250
|
+
const resolvedIds = eventSource === "user" ? resolved.map((r) => r.entryId).filter((id) => id !== undefined) : [];
|
|
240
251
|
if (resolvedIds.length > 0) {
|
|
241
252
|
let scopeKey;
|
|
242
253
|
try {
|
|
243
254
|
const stashPath = response.stashDir;
|
|
244
|
-
const disabled =
|
|
255
|
+
const disabled = disableScopedUtility || (stashPath && isTransientStashPath(stashPath));
|
|
245
256
|
scopeKey = disabled ? undefined : getCurrentWorkflowScopeKey();
|
|
246
257
|
}
|
|
247
258
|
catch {
|
|
@@ -265,7 +276,7 @@ function logSearchEvent(query, response, mode = "keyword", eventSource = "user")
|
|
|
265
276
|
}),
|
|
266
277
|
source: eventSource,
|
|
267
278
|
});
|
|
268
|
-
});
|
|
279
|
+
}, { busyTimeoutMs: TELEMETRY_BUSY_TIMEOUT_MS });
|
|
269
280
|
}
|
|
270
281
|
catch (err) {
|
|
271
282
|
rethrowIfTestIsolationError(err);
|