akm-cli 0.7.4 → 0.8.0-rc.10
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 +224 -1
- package/README.md +22 -6
- package/SECURITY.md +93 -0
- package/dist/cli/config-migrate.js +144 -0
- package/dist/cli/config-validate.js +39 -0
- package/dist/cli/confirm.js +73 -0
- package/dist/cli/parse-args.js +133 -0
- package/dist/cli/shared.js +129 -0
- package/dist/cli.js +2631 -1440
- package/dist/commands/add-cli.js +279 -0
- package/dist/commands/agent-dispatch.js +110 -0
- package/dist/commands/agent-support.js +68 -0
- package/dist/commands/completions.js +3 -0
- package/dist/commands/config-cli.js +130 -534
- package/dist/commands/consolidate.js +2122 -0
- package/dist/commands/curate.js +45 -3
- package/dist/commands/db-cli.js +23 -0
- package/dist/commands/distill-promotion-policy.js +660 -0
- package/dist/commands/distill.js +1081 -73
- package/dist/commands/env.js +213 -0
- package/dist/commands/eval-cases.js +43 -0
- package/dist/commands/events.js +15 -24
- package/dist/commands/extract-cli.js +127 -0
- package/dist/commands/extract-prompt.js +204 -0
- package/dist/commands/extract.js +477 -0
- package/dist/commands/feedback-cli.js +331 -0
- package/dist/commands/graph.js +477 -0
- package/dist/commands/health.js +1302 -0
- package/dist/commands/help/help-accept.md +12 -0
- package/dist/commands/help/help-improve.md +69 -0
- package/dist/commands/help/help-proposals.md +18 -0
- package/dist/commands/help/help-propose.md +17 -0
- package/dist/commands/help/help-reject.md +11 -0
- package/dist/commands/history.js +54 -46
- package/dist/commands/improve-auto-accept.js +97 -0
- package/dist/commands/improve-cli.js +217 -0
- package/dist/commands/improve-profiles.js +166 -0
- package/dist/commands/improve-result-file.js +167 -0
- package/dist/commands/improve.js +2373 -0
- package/dist/commands/info.js +5 -2
- package/dist/commands/init.js +50 -2
- package/dist/commands/installed-stashes.js +102 -139
- package/dist/commands/knowledge.js +136 -0
- package/dist/commands/lint/agent-linter.js +49 -0
- package/dist/commands/lint/base-linter.js +479 -0
- package/dist/commands/lint/command-linter.js +49 -0
- package/dist/commands/lint/default-linter.js +16 -0
- package/dist/commands/lint/env-key-rules.js +154 -0
- package/dist/commands/lint/index.js +196 -0
- package/dist/commands/lint/knowledge-linter.js +16 -0
- package/dist/commands/lint/markdown-insertion.js +343 -0
- package/dist/commands/lint/memory-linter.js +61 -0
- package/dist/commands/lint/registry.js +36 -0
- package/dist/commands/lint/skill-linter.js +45 -0
- package/dist/commands/lint/task-linter.js +50 -0
- package/dist/commands/lint/types.js +4 -0
- package/dist/commands/lint/workflow-linter.js +56 -0
- package/dist/commands/lint.js +4 -0
- package/dist/commands/migration-help.js +3 -0
- package/dist/commands/proposal.js +67 -12
- package/dist/commands/propose.js +120 -45
- package/dist/commands/reflect.js +1104 -60
- package/dist/commands/registry-cli.js +150 -0
- package/dist/commands/registry-search.js +5 -2
- package/dist/commands/remember-cli.js +257 -0
- package/dist/commands/remember.js +70 -7
- package/dist/commands/schema-repair.js +203 -0
- package/dist/commands/search.js +115 -14
- package/dist/commands/secret.js +173 -0
- package/dist/commands/self-update.js +3 -0
- package/dist/commands/show.js +158 -60
- package/dist/commands/source-add.js +17 -45
- package/dist/commands/source-clone.js +3 -0
- package/dist/commands/source-manage.js +14 -19
- package/dist/commands/tasks.js +437 -0
- package/dist/commands/url-checker.js +42 -0
- package/dist/core/action-contributors.js +28 -0
- package/dist/core/asset-ref.js +17 -2
- package/dist/core/asset-registry.js +12 -17
- package/dist/core/asset-serialize.js +88 -0
- package/dist/core/asset-spec.js +67 -1
- package/dist/core/common.js +182 -0
- package/dist/core/concurrent.js +25 -0
- package/dist/core/config-io.js +347 -0
- package/dist/core/config-migration.js +622 -0
- package/dist/core/config-schema.js +534 -0
- package/dist/core/config-sources.js +108 -0
- package/dist/core/config-types.js +4 -0
- package/dist/core/config-walker.js +337 -0
- package/dist/core/config.js +364 -968
- package/dist/core/errors.js +42 -20
- package/dist/core/events.js +105 -135
- package/dist/core/file-lock.js +104 -0
- package/dist/core/frontmatter.js +75 -8
- package/dist/core/lesson-lint.js +3 -0
- package/dist/core/markdown.js +20 -0
- package/dist/core/memory-belief.js +62 -0
- package/dist/core/memory-contradiction-detect.js +274 -0
- package/dist/core/memory-improve.js +806 -0
- package/dist/core/parse.js +158 -0
- package/dist/core/paths.js +280 -14
- package/dist/core/proposal-quality-validators.js +380 -0
- package/dist/core/proposal-validators.js +69 -0
- package/dist/core/proposals.js +512 -42
- package/dist/core/state-db.js +1068 -0
- package/dist/core/text-truncation.js +107 -0
- package/dist/core/time.js +54 -0
- package/dist/core/tty.js +59 -0
- package/dist/core/warn.js +64 -1
- package/dist/core/write-source.js +3 -0
- package/dist/indexer/db-backup.js +391 -0
- package/dist/indexer/db-search.js +198 -489
- package/dist/indexer/db.js +990 -108
- package/dist/indexer/ensure-index.js +136 -0
- package/dist/indexer/file-context.js +3 -0
- package/dist/indexer/graph-boost.js +376 -101
- package/dist/indexer/graph-db.js +391 -0
- package/dist/indexer/graph-dedup.js +95 -0
- package/dist/indexer/graph-extraction.js +550 -114
- package/dist/indexer/index-context.js +4 -0
- package/dist/indexer/indexer.js +547 -309
- package/dist/indexer/llm-cache.js +52 -0
- package/dist/indexer/manifest.js +3 -0
- package/dist/indexer/matchers.js +167 -160
- package/dist/indexer/memory-inference.js +152 -74
- package/dist/indexer/metadata-contributors.js +29 -0
- package/dist/indexer/metadata.js +275 -196
- package/dist/indexer/path-resolver.js +92 -0
- package/dist/indexer/project-context.js +192 -0
- package/dist/indexer/ranking-contributors.js +331 -0
- package/dist/indexer/ranking.js +81 -0
- package/dist/indexer/search-fields.js +5 -9
- package/dist/indexer/search-hit-enrichers.js +111 -0
- package/dist/indexer/search-source.js +44 -10
- package/dist/indexer/semantic-status.js +6 -17
- package/dist/indexer/staleness-detect.js +447 -0
- package/dist/indexer/usage-events.js +12 -9
- package/dist/indexer/walker.js +28 -0
- package/dist/integrations/agent/builders.js +135 -0
- package/dist/integrations/agent/config.js +122 -230
- package/dist/integrations/agent/detect.js +3 -0
- package/dist/integrations/agent/index.js +7 -13
- package/dist/integrations/agent/model-aliases.js +55 -0
- package/dist/integrations/agent/profiles.js +70 -5
- package/dist/integrations/agent/prompts.js +250 -36
- package/dist/integrations/agent/runner.js +151 -0
- package/dist/integrations/agent/sdk-runner.js +126 -0
- package/dist/integrations/agent/spawn.js +183 -35
- package/dist/integrations/github.js +3 -0
- package/dist/integrations/lockfile.js +32 -69
- package/dist/integrations/session-logs/index.js +69 -0
- package/dist/integrations/session-logs/inline-refs.js +35 -0
- package/dist/integrations/session-logs/pre-filter.js +152 -0
- package/dist/integrations/session-logs/providers/claude-code.js +282 -0
- package/dist/integrations/session-logs/providers/opencode.js +258 -0
- package/dist/integrations/session-logs/types.js +4 -0
- package/dist/llm/call-ai.js +62 -0
- package/dist/llm/client.js +79 -88
- package/dist/llm/embedder.js +20 -29
- package/dist/llm/embedders/cache.js +3 -7
- package/dist/llm/embedders/local.js +42 -1
- package/dist/llm/embedders/remote.js +20 -8
- package/dist/llm/embedders/types.js +3 -7
- package/dist/llm/feature-gate.js +95 -48
- package/dist/llm/graph-extract.js +676 -72
- package/dist/llm/index-passes.js +44 -29
- package/dist/llm/memory-infer.js +80 -71
- package/dist/llm/metadata-enhance.js +42 -29
- package/dist/llm/prompts/extract-session.md +80 -0
- package/dist/llm/prompts/graph-extract-user-prompt.md +35 -0
- package/dist/output/cli-hints-full.md +292 -0
- package/dist/output/cli-hints-short.md +66 -0
- package/dist/output/cli-hints.js +7 -311
- package/dist/output/context.js +60 -8
- package/dist/output/renderers.js +306 -258
- package/dist/output/shapes/curate.js +56 -0
- package/dist/output/shapes/distill.js +10 -0
- package/dist/output/shapes/env-list.js +19 -0
- package/dist/output/shapes/events.js +11 -0
- package/dist/output/shapes/helpers.js +424 -0
- package/dist/output/shapes/history.js +7 -0
- package/dist/output/shapes/passthrough.js +102 -0
- package/dist/output/shapes/proposal-accept.js +7 -0
- package/dist/output/shapes/proposal-diff.js +7 -0
- package/dist/output/shapes/proposal-list.js +7 -0
- package/dist/output/shapes/proposal-producer.js +11 -0
- package/dist/output/shapes/proposal-reject.js +7 -0
- package/dist/output/shapes/proposal-show.js +7 -0
- package/dist/output/shapes/registry-search.js +6 -0
- package/dist/output/shapes/registry.js +30 -0
- package/dist/output/shapes/search.js +6 -0
- package/dist/output/shapes/secret-list.js +19 -0
- package/dist/output/shapes/show.js +6 -0
- package/dist/output/shapes/vault-list.js +19 -0
- package/dist/output/shapes.js +51 -511
- package/dist/output/text/add.js +6 -0
- package/dist/output/text/clone.js +6 -0
- package/dist/output/text/config.js +6 -0
- package/dist/output/text/curate.js +6 -0
- package/dist/output/text/distill.js +7 -0
- package/dist/output/text/enable-disable.js +7 -0
- package/dist/output/text/events.js +10 -0
- package/dist/output/text/feedback.js +6 -0
- package/dist/output/text/helpers.js +1039 -0
- package/dist/output/text/history.js +7 -0
- package/dist/output/text/import.js +6 -0
- package/dist/output/text/index.js +6 -0
- package/dist/output/text/info.js +6 -0
- package/dist/output/text/init.js +6 -0
- package/dist/output/text/list.js +6 -0
- package/dist/output/text/proposal-producer.js +8 -0
- package/dist/output/text/proposal.js +11 -0
- package/dist/output/text/registry-commands.js +11 -0
- package/dist/output/text/registry.js +30 -0
- package/dist/output/text/remember.js +6 -0
- package/dist/output/text/remove.js +6 -0
- package/dist/output/text/save.js +6 -0
- package/dist/output/text/search.js +6 -0
- package/dist/output/text/show.js +6 -0
- package/dist/output/text/update.js +6 -0
- package/dist/output/text/upgrade.js +6 -0
- package/dist/output/text/vault.js +16 -0
- package/dist/output/text/wiki.js +15 -0
- package/dist/output/text/workflow.js +14 -0
- package/dist/output/text.js +44 -1093
- package/dist/registry/build-index.js +3 -0
- package/dist/registry/create-provider-registry.js +3 -0
- package/dist/registry/factory.js +4 -1
- package/dist/registry/origin-resolve.js +3 -0
- package/dist/registry/providers/index.js +3 -0
- package/dist/registry/providers/skills-sh.js +71 -50
- package/dist/registry/providers/static-index.js +53 -48
- package/dist/registry/providers/types.js +3 -24
- package/dist/registry/resolve.js +11 -16
- package/dist/registry/types.js +3 -0
- package/dist/scripts/migrate-storage.js +17750 -0
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +9031 -0
- package/dist/scripts/migrations/v16-to-v17.js +141 -0
- package/dist/setup/detect.js +3 -0
- package/dist/setup/ripgrep-install.js +3 -0
- package/dist/setup/ripgrep-resolve.js +3 -0
- package/dist/setup/setup.js +775 -37
- package/dist/setup/steps.js +3 -15
- package/dist/sources/include.js +3 -0
- package/dist/sources/provider-factory.js +5 -12
- package/dist/sources/provider.js +3 -20
- package/dist/sources/providers/filesystem.js +19 -23
- package/dist/sources/providers/git.js +179 -20
- package/dist/sources/providers/index.js +3 -0
- package/dist/sources/providers/install-types.js +3 -13
- package/dist/sources/providers/npm.js +3 -4
- package/dist/sources/providers/provider-utils.js +3 -0
- package/dist/sources/providers/sync-from-ref.js +3 -11
- package/dist/sources/providers/tar-utils.js +3 -0
- package/dist/sources/providers/website.js +18 -22
- package/dist/sources/resolve.js +3 -0
- package/dist/sources/types.js +3 -0
- package/dist/sources/website-ingest.js +7 -0
- package/dist/tasks/backends/cron.js +203 -0
- package/dist/tasks/backends/exec-utils.js +28 -0
- package/dist/tasks/backends/index.js +24 -0
- package/dist/tasks/backends/launchd-template.xml +19 -0
- package/dist/tasks/backends/launchd.js +187 -0
- package/dist/tasks/backends/schtasks-template.xml +29 -0
- package/dist/tasks/backends/schtasks.js +215 -0
- package/dist/tasks/parser.js +211 -0
- package/dist/tasks/resolveAkmBin.js +87 -0
- package/dist/tasks/runner.js +458 -0
- package/dist/tasks/schedule.js +227 -0
- package/dist/tasks/schema.js +15 -0
- package/dist/tasks/validator.js +62 -0
- package/dist/version.js +3 -0
- package/dist/wiki/index-template.md +12 -0
- package/dist/wiki/ingest-workflow-template.md +54 -0
- package/dist/wiki/log-template.md +8 -0
- package/dist/wiki/schema-template.md +61 -0
- package/dist/wiki/wiki-templates.js +15 -0
- package/dist/wiki/wiki.js +13 -61
- package/dist/workflows/authoring.js +8 -25
- package/dist/workflows/cli.js +3 -0
- package/dist/workflows/db.js +141 -2
- package/dist/workflows/document-cache.js +3 -10
- package/dist/workflows/parser.js +3 -0
- package/dist/workflows/renderer.js +11 -3
- package/dist/workflows/runs.js +91 -89
- package/dist/workflows/schema.js +3 -0
- package/dist/workflows/scope-key.js +79 -0
- package/dist/workflows/validator.js +4 -8
- package/dist/workflows/workflow-template.md +24 -0
- package/docs/README.md +10 -2
- package/docs/data-and-telemetry.md +225 -0
- package/docs/migration/release-notes/0.7.0.md +1 -1
- package/docs/migration/release-notes/0.7.4.md +1 -1
- package/docs/migration/release-notes/0.7.5.md +20 -0
- package/docs/migration/release-notes/0.8.0.md +48 -0
- package/docs/migration/v0.7-to-v0.8.md +1307 -0
- package/package.json +29 -11
- package/dist/commands/install-audit.js +0 -381
- package/dist/commands/vault.js +0 -333
- package/dist/templates/wiki-templates.js +0 -100
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
import { makeAssetRef } from "../core/asset-ref";
|
|
5
|
+
import { getDerivedForParent } from "./db";
|
|
6
|
+
import { getRenderer } from "./file-context";
|
|
7
|
+
const rendererSearchHitEnricher = {
|
|
8
|
+
name: "renderer-search-hit-enricher",
|
|
9
|
+
appliesTo(ctx) {
|
|
10
|
+
return ctx.rendererRegistry.rendererNameFor(ctx.type) !== undefined;
|
|
11
|
+
},
|
|
12
|
+
async enrich(hit, ctx) {
|
|
13
|
+
const rendererName = ctx.rendererRegistry.rendererNameFor(ctx.type);
|
|
14
|
+
if (!rendererName)
|
|
15
|
+
return;
|
|
16
|
+
const renderer = await getRenderer(rendererName);
|
|
17
|
+
renderer?.enrichSearchHit?.(hit, ctx.stashDir);
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Phase 5A / Advantage D5 — derived-memory enricher.
|
|
22
|
+
*
|
|
23
|
+
* When a parent memory has a `.derived` child indexed (the LLM-distilled
|
|
24
|
+
* lesson surface), this enricher rewrites the parent hit to surface the
|
|
25
|
+
* derived child's description / searchHints / tags AND sets `expandTo` to
|
|
26
|
+
* the derived child's ref so callers can fetch it via `akm show <ref>`.
|
|
27
|
+
*
|
|
28
|
+
* The parent ref is preserved on the hit — only the surface text is
|
|
29
|
+
* swapped, so links and provenance still point at the canonical parent.
|
|
30
|
+
*
|
|
31
|
+
* Skipped for:
|
|
32
|
+
* - non-memory hits
|
|
33
|
+
* - memory hits that are themselves derived children (name ends with
|
|
34
|
+
* `.derived`) — we never recurse parent→child→grandchild
|
|
35
|
+
* - contexts without an open DB connection
|
|
36
|
+
*/
|
|
37
|
+
export const derivedMemoryEnricher = {
|
|
38
|
+
name: "derived-memory-enricher",
|
|
39
|
+
appliesTo(ctx) {
|
|
40
|
+
return ctx.type === "memory" && ctx.db !== undefined;
|
|
41
|
+
},
|
|
42
|
+
enrich(hit, ctx) {
|
|
43
|
+
if (!ctx.db)
|
|
44
|
+
return;
|
|
45
|
+
// Never recurse: a `.derived` hit is itself the child surface; leaving
|
|
46
|
+
// it untouched also avoids `<parent>.derived.derived` chains.
|
|
47
|
+
if (hit.name.toLowerCase().endsWith(".derived"))
|
|
48
|
+
return;
|
|
49
|
+
// Parent ref shape: `memory:<name>`. Re-build from the entry's name
|
|
50
|
+
// so we don't depend on whatever wiki/registry prefix `hit.ref` carries.
|
|
51
|
+
const parentRef = makeAssetRef("memory", hit.name);
|
|
52
|
+
const derived = getDerivedForParent(ctx.db, parentRef);
|
|
53
|
+
if (!derived)
|
|
54
|
+
return;
|
|
55
|
+
// Swap description / searchHints / tags from the derived child.
|
|
56
|
+
// The parent ref itself is preserved — only the surface text is swapped.
|
|
57
|
+
if (typeof derived.entry.description === "string" && derived.entry.description.length > 0) {
|
|
58
|
+
hit.description = derived.entry.description;
|
|
59
|
+
}
|
|
60
|
+
if (Array.isArray(derived.entry.searchHints) && derived.entry.searchHints.length > 0) {
|
|
61
|
+
// We don't have a `searchHints` field on SourceSearchHit today — it's
|
|
62
|
+
// only used inside ranking. The plan says to swap when present; we
|
|
63
|
+
// record it onto the hit only if a future renderer surfaces it. For
|
|
64
|
+
// now, treat as advisory (no-op when SearchHit lacks the field).
|
|
65
|
+
}
|
|
66
|
+
if (Array.isArray(derived.entry.tags) && derived.entry.tags.length > 0) {
|
|
67
|
+
hit.tags = derived.entry.tags;
|
|
68
|
+
}
|
|
69
|
+
hit.expandTo = makeAssetRef("memory", derived.entry.name);
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Registry of additional enrichers — populated by
|
|
74
|
+
* {@link registerSearchHitEnricher} and consumed in addition to
|
|
75
|
+
* {@link defaultSearchHitEnrichers} when `enrichSearchHit` is invoked
|
|
76
|
+
* without an explicit enricher list.
|
|
77
|
+
*
|
|
78
|
+
* Kept module-local so callers must use `registerSearchHitEnricher` rather
|
|
79
|
+
* than mutating the array directly.
|
|
80
|
+
*/
|
|
81
|
+
const additionalEnrichers = [];
|
|
82
|
+
export const defaultSearchHitEnrichers = [rendererSearchHitEnricher, derivedMemoryEnricher];
|
|
83
|
+
/**
|
|
84
|
+
* Register an additional enricher to be applied alongside the defaults.
|
|
85
|
+
*
|
|
86
|
+
* Idempotent on `name`: subsequent calls with the same name replace the
|
|
87
|
+
* previously-registered enricher (so tests can re-register cleanly without
|
|
88
|
+
* stacking duplicates).
|
|
89
|
+
*/
|
|
90
|
+
export function registerSearchHitEnricher(enricher) {
|
|
91
|
+
const existingIndex = additionalEnrichers.findIndex((e) => e.name === enricher.name);
|
|
92
|
+
if (existingIndex >= 0) {
|
|
93
|
+
additionalEnrichers[existingIndex] = enricher;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
additionalEnrichers.push(enricher);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Test-only: clear the registered-enrichers list. Not part of the public API.
|
|
101
|
+
*/
|
|
102
|
+
export function _resetRegisteredSearchHitEnrichers() {
|
|
103
|
+
additionalEnrichers.length = 0;
|
|
104
|
+
}
|
|
105
|
+
export async function enrichSearchHit(hit, ctx, enrichers = [...defaultSearchHitEnrichers, ...additionalEnrichers]) {
|
|
106
|
+
for (const enricher of enrichers) {
|
|
107
|
+
if (!enricher.appliesTo(ctx))
|
|
108
|
+
continue;
|
|
109
|
+
await enricher.enrich(hit, ctx);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
1
4
|
import fs from "node:fs";
|
|
2
5
|
import path from "node:path";
|
|
3
6
|
import { resolveStashDir } from "../core/common";
|
|
4
|
-
import { loadConfig } from "../core/config";
|
|
7
|
+
import { getSources, loadConfig } from "../core/config";
|
|
5
8
|
import { resolveSourceProviderFactory } from "../sources/provider-factory";
|
|
6
9
|
// Eager side-effect imports so all built-in source providers self-register
|
|
7
10
|
// before resolveEntryContentDir() runs.
|
|
@@ -21,7 +24,7 @@ const GIT_STASH_TYPES = new Set(["git"]);
|
|
|
21
24
|
* 1. The primary stash directory (the entry marked `primary: true`, or the
|
|
22
25
|
* legacy top-level `stashDir`). Always emitted, even when the directory
|
|
23
26
|
* does not yet exist on disk, so callers can use it as the clone target.
|
|
24
|
-
* 2. Each entry in `config.sources
|
|
27
|
+
* 2. Each entry in `config.sources[]` (in declared order), excluding the
|
|
25
28
|
* one already emitted as the primary.
|
|
26
29
|
* 3. Each entry in `config.installed[]` (registry-managed stashes).
|
|
27
30
|
*
|
|
@@ -32,12 +35,29 @@ const GIT_STASH_TYPES = new Set(["git"]);
|
|
|
32
35
|
export function resolveSourceEntries(overrideStashDir, existingConfig) {
|
|
33
36
|
const stashDir = overrideStashDir ?? resolveStashDir();
|
|
34
37
|
const config = existingConfig ?? loadConfig();
|
|
35
|
-
|
|
38
|
+
// Primary stash is always writable.
|
|
39
|
+
const sources = [{ path: stashDir, writable: true }];
|
|
36
40
|
const seen = new Set([path.resolve(stashDir)]);
|
|
37
|
-
const addSource = (dir, registryId, wikiName) => {
|
|
41
|
+
const addSource = (dir, registryId, wikiName, writable) => {
|
|
38
42
|
const resolved = path.resolve(dir);
|
|
39
|
-
if (seen.has(resolved))
|
|
43
|
+
if (seen.has(resolved)) {
|
|
44
|
+
// Already in the source list — typically the primary stash injected at
|
|
45
|
+
// sources[0] before this loop. Enrich that entry with whatever metadata
|
|
46
|
+
// the matching config source carries so `--source <config-name>` can
|
|
47
|
+
// find it via registryId. Without this, the primary stash entry stays
|
|
48
|
+
// identity-less and a user-named primary source ("name": "my-stash")
|
|
49
|
+
// would validate but match zero entries when filtering.
|
|
50
|
+
const existing = sources.find((s) => s.path === resolved);
|
|
51
|
+
if (existing) {
|
|
52
|
+
if (registryId && !existing.registryId)
|
|
53
|
+
existing.registryId = registryId;
|
|
54
|
+
if (wikiName && !existing.wikiName)
|
|
55
|
+
existing.wikiName = wikiName;
|
|
56
|
+
if (writable && !existing.writable)
|
|
57
|
+
existing.writable = true;
|
|
58
|
+
}
|
|
40
59
|
return;
|
|
60
|
+
}
|
|
41
61
|
seen.add(resolved);
|
|
42
62
|
if (isSuspiciousStashRoot(dir)) {
|
|
43
63
|
warn(`Warning: stash root "${dir}" appears to be a system directory. This may be unintentional.`);
|
|
@@ -47,13 +67,14 @@ export function resolveSourceEntries(overrideStashDir, existingConfig) {
|
|
|
47
67
|
path: resolved,
|
|
48
68
|
...(registryId ? { registryId } : {}),
|
|
49
69
|
...(wikiName ? { wikiName } : {}),
|
|
70
|
+
...(writable ? { writable: true } : {}),
|
|
50
71
|
});
|
|
51
72
|
}
|
|
52
73
|
};
|
|
53
74
|
// (1) + (2) Single pass over declared stashes — primary first if present,
|
|
54
75
|
// then the rest in declared order. The primary's directory is already
|
|
55
76
|
// injected as `sources[0]` above, so we only need to dedupe the source set.
|
|
56
|
-
const stashes = config
|
|
77
|
+
const stashes = getSources(config);
|
|
57
78
|
const primaryIdx = stashes.findIndex((entry) => entry.primary === true);
|
|
58
79
|
const ordered = [];
|
|
59
80
|
if (primaryIdx >= 0) {
|
|
@@ -72,11 +93,12 @@ export function resolveSourceEntries(overrideStashDir, existingConfig) {
|
|
|
72
93
|
const dir = resolveEntryContentDir(entry);
|
|
73
94
|
if (dir == null)
|
|
74
95
|
continue;
|
|
75
|
-
addSource(dir, entry.name, entry.wikiName);
|
|
96
|
+
addSource(dir, entry.name, entry.wikiName, entry.writable === true);
|
|
76
97
|
}
|
|
77
98
|
// (3) Installed stashes (registry-managed). Always last.
|
|
99
|
+
// Only installed entries explicitly marked writable: true are considered writable.
|
|
78
100
|
for (const entry of config.installed ?? []) {
|
|
79
|
-
addSource(entry.stashRoot, entry.id, entry.wikiName);
|
|
101
|
+
addSource(entry.stashRoot, entry.id, entry.wikiName, entry.writable === true);
|
|
80
102
|
}
|
|
81
103
|
return sources;
|
|
82
104
|
}
|
|
@@ -132,6 +154,19 @@ function resolveEntryContentDir(entry) {
|
|
|
132
154
|
export function resolveAllStashDirs(overrideStashDir) {
|
|
133
155
|
return resolveSourceEntries(overrideStashDir).map((s) => s.path);
|
|
134
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Return the resolved absolute paths of all writable stash sources.
|
|
159
|
+
*
|
|
160
|
+
* The primary stash is always writable. Filesystem/git sources that have
|
|
161
|
+
* `writable: true` in config are also included. Registry-cached sources
|
|
162
|
+
* (installed without `writable: true`) are excluded because they are
|
|
163
|
+
* overwritten on `akm update` and must never be mutated.
|
|
164
|
+
*/
|
|
165
|
+
export function getWritableStashDirs(overrideStashDir, existingConfig) {
|
|
166
|
+
return resolveSourceEntries(overrideStashDir, existingConfig)
|
|
167
|
+
.filter((s) => s.writable === true)
|
|
168
|
+
.map((s) => s.path);
|
|
169
|
+
}
|
|
135
170
|
/**
|
|
136
171
|
* Find which source a file path belongs to.
|
|
137
172
|
*/
|
|
@@ -226,8 +261,7 @@ function isValidDirectory(dir) {
|
|
|
226
261
|
export async function ensureSourceCaches(config, options) {
|
|
227
262
|
const cfg = config ?? loadConfig();
|
|
228
263
|
const force = options?.force === true;
|
|
229
|
-
|
|
230
|
-
const entries = cfg.sources ?? cfg.stashes ?? [];
|
|
264
|
+
const entries = getSources(cfg);
|
|
231
265
|
for (const entry of entries) {
|
|
232
266
|
if (!GIT_STASH_TYPES.has(entry.type) || !entry.url || entry.enabled === false)
|
|
233
267
|
continue;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
1
4
|
import fs from "node:fs";
|
|
2
|
-
import
|
|
5
|
+
import { writeFileAtomic } from "../core/common";
|
|
3
6
|
import { getCacheDir, getSemanticStatusPath } from "../core/paths";
|
|
4
|
-
import { DEFAULT_LOCAL_MODEL } from "../llm/
|
|
7
|
+
import { DEFAULT_LOCAL_MODEL } from "../llm/embedders/local";
|
|
5
8
|
export function deriveSemanticProviderFingerprint(embedding) {
|
|
6
9
|
if (embedding?.endpoint) {
|
|
7
10
|
return `remote:${embedding.endpoint}|${embedding.model}|${embedding.dimension ?? "default"}`;
|
|
@@ -41,21 +44,7 @@ export function readSemanticStatus() {
|
|
|
41
44
|
export function writeSemanticStatus(status) {
|
|
42
45
|
const dir = getCacheDir();
|
|
43
46
|
fs.mkdirSync(dir, { recursive: true });
|
|
44
|
-
|
|
45
|
-
const tmpPath = path.join(dir, `semantic-status.json.tmp.${process.pid}.${Math.random().toString(36).slice(2)}`);
|
|
46
|
-
fs.writeFileSync(tmpPath, `${JSON.stringify(status, null, 2)}\n`, "utf8");
|
|
47
|
-
try {
|
|
48
|
-
fs.renameSync(tmpPath, filePath);
|
|
49
|
-
}
|
|
50
|
-
catch (err) {
|
|
51
|
-
try {
|
|
52
|
-
fs.unlinkSync(tmpPath);
|
|
53
|
-
}
|
|
54
|
-
catch {
|
|
55
|
-
/* ignore cleanup failure */
|
|
56
|
-
}
|
|
57
|
-
throw err;
|
|
58
|
-
}
|
|
47
|
+
writeFileAtomic(getSemanticStatusPath(), `${JSON.stringify(status, null, 2)}\n`);
|
|
59
48
|
}
|
|
60
49
|
export function clearSemanticStatus() {
|
|
61
50
|
try {
|