akm-cli 0.8.6 → 0.8.14
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 +442 -0
- package/dist/assets/help/help-proposals.md +1 -2
- package/dist/assets/hints/cli-hints-full.md +34 -19
- package/dist/assets/hints/cli-hints-short.md +1 -1
- package/dist/assets/profiles/catchup.json +13 -0
- package/dist/assets/profiles/consolidate.json +13 -0
- package/dist/assets/profiles/frequent.json +13 -0
- package/dist/assets/tasks/core/backup.yml +4 -0
- package/dist/assets/tasks/core/extract.yml +4 -0
- package/dist/assets/tasks/core/improve.yml +4 -0
- package/dist/assets/tasks/core/index-refresh.yml +4 -0
- package/dist/assets/tasks/core/sync.yml +4 -0
- package/dist/assets/tasks/core/update-stashes.yml +4 -0
- package/dist/assets/tasks/core/version-check.yml +4 -0
- package/dist/assets/templates/html/default.html +78 -0
- package/dist/assets/templates/html/health.html +560 -0
- package/dist/assets/templates/html/vendor/echarts.min.js +45 -0
- package/dist/cli/config-migrate.js +6 -6
- package/dist/cli/config-validate.js +4 -4
- package/dist/cli/confirm.js +3 -3
- package/dist/cli/parse-args.js +1 -1
- package/dist/cli/shared.js +72 -19
- package/dist/cli-node.mjs +26 -0
- package/dist/cli.js +206 -3866
- package/dist/commands/{agent-dispatch.js → agent/agent-dispatch.js} +6 -6
- package/dist/commands/{agent-support.js → agent/agent-support.js} +2 -2
- package/dist/commands/agent/contribute-cli.js +200 -0
- package/dist/commands/completions.js +1 -1
- package/dist/commands/config-cli.js +230 -3
- package/dist/commands/db-cli.js +2 -2
- package/dist/commands/env/env-cli.js +529 -0
- package/dist/commands/env/env.js +410 -0
- package/dist/commands/env/secret-cli.js +259 -0
- package/dist/commands/{secret.js → env/secret.js} +6 -47
- package/dist/commands/events.js +4 -4
- package/dist/commands/feedback-cli.js +18 -34
- package/dist/commands/graph/graph-cli.js +132 -0
- package/dist/commands/{graph.js → graph/graph.js} +22 -16
- package/dist/commands/health/checks.js +279 -0
- package/dist/commands/health/html-report.js +448 -0
- package/dist/commands/health.js +189 -266
- package/dist/commands/{consolidate.js → improve/consolidate.js} +63 -38
- package/dist/commands/{distill-promotion-policy.js → improve/distill-promotion-policy.js} +3 -3
- package/dist/commands/{distill.js → improve/distill.js} +39 -18
- package/dist/commands/{eval-cases.js → improve/eval-cases.js} +1 -1
- package/dist/commands/{extract-cli.js → improve/extract-cli.js} +4 -4
- package/dist/commands/{extract-prompt.js → improve/extract-prompt.js} +2 -2
- package/dist/commands/{extract.js → improve/extract.js} +221 -26
- package/dist/commands/{improve-auto-accept.js → improve/improve-auto-accept.js} +30 -4
- package/dist/commands/{improve-cli.js → improve/improve-cli.js} +44 -22
- package/dist/commands/{improve-profiles.js → improve/improve-profiles.js} +13 -7
- package/dist/commands/{improve-result-file.js → improve/improve-result-file.js} +1 -1
- package/dist/commands/{improve.js → improve/improve.js} +672 -292
- package/dist/{core → commands/improve/memory}/memory-belief.js +2 -2
- package/dist/{core → commands/improve/memory}/memory-contradiction-detect.js +5 -5
- package/dist/{core → commands/improve/memory}/memory-improve.js +4 -4
- package/dist/commands/improve/reflect-noise.js +0 -0
- package/dist/commands/{reflect.js → improve/reflect.js} +58 -28
- package/dist/commands/improve/session-asset.js +248 -0
- package/dist/commands/lint/agent-linter.js +1 -1
- package/dist/commands/lint/base-linter.js +55 -37
- package/dist/commands/lint/command-linter.js +1 -1
- package/dist/commands/lint/default-linter.js +1 -1
- package/dist/commands/lint/env-key-rules.js +1 -1
- package/dist/commands/lint/index.js +19 -25
- package/dist/commands/lint/knowledge-linter.js +1 -1
- package/dist/commands/lint/memory-linter.js +1 -1
- package/dist/commands/lint/registry.js +8 -8
- package/dist/commands/lint/skill-linter.js +1 -1
- package/dist/commands/lint/task-linter.js +1 -1
- package/dist/commands/lint/workflow-linter.js +1 -1
- package/dist/commands/lint.js +1 -1
- package/dist/commands/observability-cli.js +244 -0
- package/dist/commands/proposal/drain-policies.js +3 -3
- package/dist/commands/proposal/drain.js +87 -15
- package/dist/commands/proposal/proposal-cli.js +490 -0
- package/dist/commands/{proposal.js → proposal/proposal.js} +17 -6
- package/dist/commands/{propose.js → proposal/propose.js} +11 -11
- package/dist/{core → commands/proposal/validators}/proposal-quality-validators.js +8 -3
- package/dist/{core → commands/proposal/validators}/proposal-validators.js +5 -5
- package/dist/{core → commands/proposal/validators}/proposals.js +374 -345
- package/dist/commands/{curate.js → read/curate.js} +7 -7
- package/dist/commands/{knowledge.js → read/knowledge.js} +22 -9
- package/dist/commands/{registry-search.js → read/registry-search.js} +5 -5
- package/dist/commands/{remember-cli.js → read/remember-cli.js} +15 -7
- package/dist/commands/read/search-cli.js +207 -0
- package/dist/commands/{search.js → read/search.js} +22 -27
- package/dist/commands/{show.js → read/show.js} +31 -45
- package/dist/commands/registry-cli.js +8 -8
- package/dist/commands/remember.js +14 -10
- package/dist/commands/sources/add-cli.js +293 -0
- package/dist/commands/{history.js → sources/history.js} +27 -25
- package/dist/commands/{info.js → sources/info.js} +6 -6
- package/dist/commands/{init.js → sources/init.js} +6 -6
- package/dist/commands/{installed-stashes.js → sources/installed-stashes.js} +12 -12
- package/dist/commands/{migration-help.js → sources/migration-help.js} +3 -2
- package/dist/commands/{schema-repair.js → sources/schema-repair.js} +8 -8
- package/dist/commands/{self-update.js → sources/self-update.js} +10 -9
- package/dist/commands/{source-add.js → sources/source-add.js} +10 -10
- package/dist/commands/{source-clone.js → sources/source-clone.js} +7 -7
- package/dist/commands/{source-manage.js → sources/source-manage.js} +4 -4
- package/dist/commands/sources/sources-cli.js +305 -0
- package/dist/commands/sources/stash-cli.js +219 -0
- package/dist/commands/{stash-skeleton.js → sources/stash-skeleton.js} +2 -1
- package/dist/commands/tasks/default-tasks.js +173 -0
- package/dist/commands/tasks/tasks-cli.js +210 -0
- package/dist/commands/{tasks.js → tasks/tasks.js} +14 -14
- package/dist/commands/wiki-cli.js +307 -0
- package/dist/commands/workflow-cli.js +329 -0
- package/dist/core/action-contributors.js +1 -1
- package/dist/core/assert.js +40 -0
- package/dist/core/asset/asset-create.js +54 -0
- package/dist/core/{asset-ref.js → asset/asset-ref.js} +21 -4
- package/dist/core/{asset-registry.js → asset/asset-registry.js} +3 -3
- package/dist/core/{asset-spec.js → asset/asset-spec.js} +17 -31
- package/dist/core/{markdown.js → asset/markdown.js} +1 -1
- package/dist/core/{stash-meta.js → asset/stash-meta.js} +1 -1
- package/dist/core/best-effort.js +64 -0
- package/dist/core/common.js +32 -18
- package/dist/core/{config-io.js → config/config-io.js} +29 -19
- package/dist/core/{config-migration.js → config/config-migration.js} +11 -9
- package/dist/core/{config-schema.js → config/config-schema.js} +50 -7
- package/dist/core/config/config-types.js +16 -0
- package/dist/core/{config-walker.js → config/config-walker.js} +2 -2
- package/dist/core/{config.js → config/config.js} +10 -8
- package/dist/core/env-secret-ref.js +90 -0
- package/dist/core/errors.js +13 -3
- package/dist/core/events.js +27 -4
- package/dist/core/file-lock.js +1 -1
- package/dist/core/improve-types.js +48 -0
- package/dist/core/lesson-lint.js +2 -2
- package/dist/core/logs-db.js +304 -0
- package/dist/core/paths.js +2 -2
- package/dist/core/ripgrep/install.js +2 -2
- package/dist/core/ripgrep/resolve.js +2 -2
- package/dist/core/state-db.js +195 -60
- package/dist/core/text-truncation.js +148 -0
- package/dist/core/time.js +1 -1
- package/dist/core/write-source.js +98 -85
- package/dist/indexer/{db-backup.js → db/db-backup.js} +9 -24
- package/dist/indexer/{db.js → db/db.js} +128 -118
- package/dist/indexer/{graph-db.js → db/graph-db.js} +9 -4
- package/dist/indexer/{llm-cache.js → db/llm-cache.js} +15 -12
- package/dist/indexer/ensure-index.js +4 -4
- package/dist/indexer/{graph-boost.js → graph/graph-boost.js} +1 -1
- package/dist/indexer/{graph-extraction.js → graph/graph-extraction.js} +55 -13
- package/dist/indexer/indexer.js +37 -30
- package/dist/indexer/init.js +54 -0
- package/dist/indexer/manifest.js +10 -10
- package/dist/indexer/{memory-inference.js → passes/memory-inference.js} +141 -33
- package/dist/indexer/{metadata-contributors.js → passes/metadata-contributors.js} +10 -8
- package/dist/indexer/{metadata.js → passes/metadata.js} +15 -19
- package/dist/indexer/{staleness-detect.js → passes/staleness-detect.js} +53 -12
- package/dist/indexer/{db-search.js → search/db-search.js} +28 -16
- package/dist/indexer/{ranking-contributors.js → search/ranking-contributors.js} +1 -1
- package/dist/indexer/{ranking.js → search/ranking.js} +2 -2
- package/dist/indexer/{search-hit-enrichers.js → search/search-hit-enrichers.js} +3 -3
- package/dist/indexer/{search-source.js → search/search-source.js} +8 -8
- package/dist/indexer/{semantic-status.js → search/semantic-status.js} +3 -3
- package/dist/indexer/usage/unmigrated-vaults-guard.js +94 -0
- package/dist/indexer/{usage-events.js → usage/usage-events.js} +32 -0
- package/dist/indexer/{file-context.js → walk/file-context.js} +10 -15
- package/dist/indexer/{matchers.js → walk/matchers.js} +13 -9
- package/dist/indexer/{path-resolver.js → walk/path-resolver.js} +6 -6
- package/dist/indexer/{project-context.js → walk/project-context.js} +1 -1
- package/dist/indexer/{walker.js → walk/walker.js} +4 -3
- package/dist/integrations/agent/builder-shared.js +39 -0
- package/dist/integrations/agent/builders.js +14 -81
- package/dist/integrations/agent/config.js +6 -4
- package/dist/integrations/agent/detect.js +1 -1
- package/dist/integrations/agent/index.js +23 -8
- package/dist/integrations/agent/prompts.js +2 -3
- package/dist/integrations/agent/runner.js +22 -3
- package/dist/integrations/agent/spawn.js +9 -10
- package/dist/integrations/harnesses/claude/agent-builder.js +48 -0
- package/dist/integrations/harnesses/claude/config-import.js +70 -0
- package/dist/integrations/harnesses/claude/index.js +64 -0
- package/dist/integrations/{session-logs/providers/claude-code.js → harnesses/claude/session-log.js} +32 -5
- package/dist/integrations/harnesses/index.js +144 -0
- package/dist/integrations/harnesses/opencode/agent-builder.js +43 -0
- package/dist/integrations/harnesses/opencode/config-import.js +82 -0
- package/dist/integrations/harnesses/opencode/index.js +59 -0
- package/dist/integrations/{session-logs/providers/opencode.js → harnesses/opencode/session-log.js} +1 -1
- package/dist/integrations/harnesses/opencode-sdk/index.js +49 -0
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +234 -0
- package/dist/integrations/harnesses/types.js +43 -0
- package/dist/integrations/lockfile.js +7 -16
- package/dist/integrations/session-logs/index.js +82 -9
- package/dist/llm/call-ai.js +4 -4
- package/dist/llm/client.js +146 -6
- package/dist/llm/embedder.js +6 -6
- package/dist/llm/embedders/local.js +9 -22
- package/dist/llm/embedders/remote.js +2 -2
- package/dist/llm/embedders/types.js +1 -1
- package/dist/llm/graph-extract.js +31 -12
- package/dist/llm/index-passes.js +1 -1
- package/dist/llm/memory-infer.js +12 -5
- package/dist/llm/metadata-enhance.js +2 -2
- package/dist/llm/usage-persist.js +77 -0
- package/dist/llm/usage-telemetry.js +103 -0
- package/dist/output/context.js +9 -46
- package/dist/output/html-render.js +73 -0
- package/dist/output/renderers.js +88 -58
- package/dist/output/shapes/curate.js +7 -3
- package/dist/output/shapes/distill.js +7 -3
- package/dist/output/shapes/env-list.js +18 -16
- package/dist/output/shapes/events.js +5 -4
- package/dist/output/shapes/helpers.js +19 -5
- package/dist/output/shapes/history.js +7 -3
- package/dist/output/shapes/passthrough.js +8 -11
- package/dist/output/shapes/{proposal-accept.js → proposal/accept.js} +7 -3
- package/dist/output/shapes/{proposal-diff.js → proposal/diff.js} +7 -3
- package/dist/output/shapes/{proposal-list.js → proposal/list.js} +7 -3
- package/dist/output/shapes/{proposal-producer.js → proposal/producer.js} +5 -4
- package/dist/output/shapes/{proposal-reject.js → proposal/reject.js} +7 -3
- package/dist/output/shapes/{proposal-show.js → proposal/show.js} +7 -3
- package/dist/output/shapes/registry-search.js +7 -3
- package/dist/output/shapes/registry.js +12 -0
- package/dist/output/shapes/search.js +7 -3
- package/dist/output/shapes/secret-list.js +18 -16
- package/dist/output/shapes/show.js +7 -3
- package/dist/output/shapes.js +55 -30
- package/dist/output/text/add.js +2 -3
- package/dist/output/text/clone.js +2 -3
- package/dist/output/text/config.js +2 -3
- package/dist/output/text/curate.js +4 -3
- package/dist/output/text/distill.js +2 -3
- package/dist/output/text/enable-disable.js +5 -4
- package/dist/output/text/env.js +13 -0
- package/dist/output/text/events.js +5 -4
- package/dist/output/text/feedback.js +4 -3
- package/dist/output/text/helpers.js +123 -40
- package/dist/output/text/history.js +2 -3
- package/dist/output/text/import.js +2 -3
- package/dist/output/text/index.js +2 -3
- package/dist/output/text/info.js +2 -3
- package/dist/output/text/init.js +2 -3
- package/dist/output/text/list.js +2 -3
- package/dist/output/text/proposal/producer.js +9 -0
- package/dist/output/text/proposal/proposal.js +13 -0
- package/dist/output/text/registry-commands.js +8 -7
- package/dist/output/text/registry.js +12 -0
- package/dist/output/text/remember.js +4 -3
- package/dist/output/text/remove.js +2 -3
- package/dist/output/text/save.js +2 -3
- package/dist/output/text/search.js +4 -3
- package/dist/output/text/show.js +4 -3
- package/dist/output/text/update.js +2 -3
- package/dist/output/text/upgrade.js +2 -3
- package/dist/output/text/wiki.js +12 -11
- package/dist/output/text/workflow.js +12 -10
- package/dist/output/text.js +66 -32
- package/dist/registry/build-index.js +11 -10
- package/dist/registry/factory.js +1 -1
- package/dist/registry/origin-resolve.js +1 -1
- package/dist/registry/providers/index.js +2 -2
- package/dist/registry/providers/skills-sh.js +91 -72
- package/dist/registry/providers/static-index.js +75 -52
- package/dist/registry/resolve.js +3 -3
- package/dist/runtime.js +242 -0
- package/dist/scripts/migrate-storage.js +1654 -683
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +254 -168
- package/dist/setup/detect.js +311 -9
- package/dist/setup/harness-config-import.js +6 -120
- package/dist/setup/setup.js +454 -43
- package/dist/sources/include.js +1 -1
- package/dist/sources/provider-factory.js +2 -2
- package/dist/sources/providers/filesystem.js +3 -3
- package/dist/sources/providers/git.js +9 -9
- package/dist/sources/providers/index.js +4 -4
- package/dist/sources/providers/npm.js +6 -6
- package/dist/sources/providers/provider-utils.js +13 -20
- package/dist/sources/providers/sync-from-ref.js +5 -5
- package/dist/sources/providers/tar-utils.js +2 -2
- package/dist/sources/providers/website.js +2 -2
- package/dist/sources/resolve.js +5 -5
- package/dist/sources/website-ingest.js +5 -5
- package/dist/storage/database.js +102 -0
- package/dist/storage/engines/sqlite-migrations.js +42 -0
- package/dist/storage/locations.js +25 -0
- package/dist/storage/repositories/index-db.js +43 -0
- package/dist/storage/repositories/workflow-runs-repository.js +141 -0
- package/dist/tasks/backends/cron.js +4 -4
- package/dist/tasks/backends/exec-utils.js +32 -0
- package/dist/tasks/backends/index.js +3 -3
- package/dist/tasks/backends/launchd.js +7 -14
- package/dist/tasks/backends/schtasks.js +7 -16
- package/dist/tasks/embedded.js +71 -0
- package/dist/tasks/parser.js +2 -2
- package/dist/tasks/resolveAkmBin.js +1 -1
- package/dist/tasks/runner.js +127 -31
- package/dist/tasks/schedule.js +1 -1
- package/dist/tasks/validator.js +7 -7
- package/dist/text-import-hook.mjs +51 -0
- package/dist/version.js +2 -1
- package/dist/wiki/wiki.js +7 -7
- package/dist/workflows/{authoring.js → authoring/authoring.js} +6 -6
- package/dist/workflows/{scope-key.js → authoring/scope-key.js} +1 -1
- package/dist/workflows/cli.js +1 -1
- package/dist/workflows/db.js +54 -32
- package/dist/workflows/parser.js +4 -4
- package/dist/workflows/renderer.js +5 -5
- package/dist/workflows/runtime/agent-identity.js +56 -0
- package/dist/workflows/runtime/checkin.js +57 -0
- package/dist/workflows/{runs.js → runtime/runs.js} +197 -101
- package/dist/workflows/validate-summary.js +82 -0
- package/docs/README.md +1 -1
- package/docs/data-and-telemetry.md +6 -6
- package/package.json +17 -8
- package/dist/commands/add-cli.js +0 -279
- package/dist/commands/env.js +0 -213
- package/dist/integrations/agent/sdk-runner.js +0 -126
- package/dist/output/shapes/vault-list.js +0 -19
- package/dist/output/text/proposal-producer.js +0 -8
- package/dist/output/text/proposal.js +0 -12
- package/dist/output/text/vault.js +0 -16
- /package/dist/core/{asset-serialize.js → asset/asset-serialize.js} +0 -0
- /package/dist/core/{frontmatter.js → asset/frontmatter.js} +0 -0
- /package/dist/core/{config-sources.js → config/config-sources.js} +0 -0
- /package/dist/indexer/{graph-dedup.js → graph/graph-dedup.js} +0 -0
- /package/dist/{core/config-types.js → indexer/passes/pass-context.js} +0 -0
- /package/dist/indexer/{search-fields.js → search/search-fields.js} +0 -0
- /package/dist/indexer/{index-context.js → walk/index-context.js} +0 -0
- /package/dist/workflows/{document-cache.js → runtime/document-cache.js} +0 -0
|
@@ -2,14 +2,14 @@
|
|
|
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
4
|
import { defineCommand } from "citty";
|
|
5
|
-
import { parsePositiveIntFlag } from "../cli/parse-args";
|
|
6
|
-
import { output, runWithJsonErrors } from "../cli/shared";
|
|
7
|
-
import { DEFAULT_CONFIG, loadUserConfig, saveConfig } from "../core/config";
|
|
8
|
-
import { UsageError } from "../core/errors";
|
|
9
|
-
import { warn } from "../core/warn";
|
|
10
|
-
import { getHyphenatedArg, getHyphenatedBoolean } from "../output/context";
|
|
11
|
-
import { buildRegistryIndex, writeRegistryIndex } from "../registry/build-index";
|
|
12
|
-
import { searchRegistry } from "./registry-search";
|
|
5
|
+
import { parsePositiveIntFlag } from "../cli/parse-args.js";
|
|
6
|
+
import { output, runWithJsonErrors } from "../cli/shared.js";
|
|
7
|
+
import { DEFAULT_CONFIG, loadUserConfig, saveConfig } from "../core/config/config.js";
|
|
8
|
+
import { UsageError } from "../core/errors.js";
|
|
9
|
+
import { warn } from "../core/warn.js";
|
|
10
|
+
import { getHyphenatedArg, getHyphenatedBoolean } from "../output/context.js";
|
|
11
|
+
import { buildRegistryIndex, writeRegistryIndex } from "../registry/build-index.js";
|
|
12
|
+
import { searchRegistry } from "./read/registry-search.js";
|
|
13
13
|
export const registryCommand = defineCommand({
|
|
14
14
|
meta: { name: "registry", description: "Manage stash registries" },
|
|
15
15
|
subCommands: {
|
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
* heuristic derivation, LLM enrichment) is testable in isolation and the
|
|
9
9
|
* CLI entry point stays focused on argument parsing + output routing.
|
|
10
10
|
*/
|
|
11
|
-
import { serializeFrontmatter } from "../core/asset-serialize";
|
|
12
|
-
import { toErrorMessage, tryReadStdinText } from "../core/common";
|
|
13
|
-
import { getDefaultLlmConfig, loadConfig } from "../core/config";
|
|
14
|
-
import { UsageError } from "../core/errors";
|
|
15
|
-
import { warn } from "../core/warn";
|
|
16
|
-
import { SCOPE_KEYS } from "../indexer/metadata";
|
|
17
|
-
import { parseFlagValue } from "../output/context";
|
|
11
|
+
import { serializeFrontmatter } from "../core/asset/asset-serialize.js";
|
|
12
|
+
import { toErrorMessage, tryReadStdinText } from "../core/common.js";
|
|
13
|
+
import { getDefaultLlmConfig, loadConfig } from "../core/config/config.js";
|
|
14
|
+
import { UsageError } from "../core/errors.js";
|
|
15
|
+
import { warn } from "../core/warn.js";
|
|
16
|
+
import { SCOPE_KEYS } from "../indexer/passes/metadata.js";
|
|
17
|
+
import { parseFlagValue } from "../output/context.js";
|
|
18
18
|
/**
|
|
19
19
|
* Parse a shorthand duration string to a number of milliseconds.
|
|
20
20
|
* Supports: `30d` (days), `12h` (hours), `6m` (months, approximated as 30d).
|
|
@@ -148,7 +148,11 @@ export async function runLlmEnrich(body) {
|
|
|
148
148
|
warn("Warning: --enrich requires an LLM to be configured. Run `akm setup` to configure one.");
|
|
149
149
|
return { tags: [] };
|
|
150
150
|
}
|
|
151
|
-
const { chatCompletion, parseEmbeddedJsonResponse: parseJsonResponse } = await import("../llm/client");
|
|
151
|
+
const { chatCompletion, parseEmbeddedJsonResponse: parseJsonResponse } = await import("../llm/client.js");
|
|
152
|
+
// #576: attribute this entry point's LLM call to the `remember` stage. The
|
|
153
|
+
// wrapper is ambient — if a usage sink is active it tags the record; if not,
|
|
154
|
+
// it is a no-op.
|
|
155
|
+
const { withLlmStage } = await import("../llm/usage-telemetry.js");
|
|
152
156
|
const prompt = `You are a memory tagger for a developer knowledge base.
|
|
153
157
|
Given the memory text below, return ONLY a JSON object with these fields:
|
|
154
158
|
- "tags": array of 1-5 short lowercase keyword tags
|
|
@@ -164,10 +168,10 @@ Return ONLY the JSON object, no prose, no markdown fences.`;
|
|
|
164
168
|
const result = await (async () => {
|
|
165
169
|
try {
|
|
166
170
|
return await Promise.race([
|
|
167
|
-
chatCompletion(llmConfig, [
|
|
171
|
+
withLlmStage("remember", () => chatCompletion(llmConfig, [
|
|
168
172
|
{ role: "system", content: "Return only valid JSON. No prose." },
|
|
169
173
|
{ role: "user", content: prompt },
|
|
170
|
-
], { maxTokens: 256, temperature: 0.1 }),
|
|
174
|
+
], { maxTokens: 256, temperature: 0.1 })),
|
|
171
175
|
new Promise((_, reject) => {
|
|
172
176
|
timeoutHandle = setTimeout(() => reject(new Error("LLM enrichment timed out")), LLM_ENRICH_TIMEOUT_MS);
|
|
173
177
|
}),
|
|
@@ -0,0 +1,293 @@
|
|
|
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 fs from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import * as p from "@clack/prompts";
|
|
7
|
+
import { defineCommand } from "citty";
|
|
8
|
+
import { output, runWithJsonErrors } from "../../cli/shared.js";
|
|
9
|
+
import { UsageError } from "../../core/errors.js";
|
|
10
|
+
import { appendEvent } from "../../core/events.js";
|
|
11
|
+
import { warn } from "../../core/warn.js";
|
|
12
|
+
import { getHyphenatedBoolean } from "../../output/context.js";
|
|
13
|
+
import { akmRemove } from "./installed-stashes.js";
|
|
14
|
+
import { akmAdd } from "./source-add.js";
|
|
15
|
+
import { addStash } from "./source-manage.js";
|
|
16
|
+
// ── Shared website-options helper (also used by wikiRegisterCommand) ──────────
|
|
17
|
+
export function buildWebsiteOptions(args) {
|
|
18
|
+
const websiteOptions = {};
|
|
19
|
+
if (typeof args["max-pages"] === "string" && args["max-pages"].length > 0)
|
|
20
|
+
websiteOptions.maxPages = args["max-pages"];
|
|
21
|
+
if (typeof args["max-depth"] === "string" && args["max-depth"].length > 0)
|
|
22
|
+
websiteOptions.maxDepth = args["max-depth"];
|
|
23
|
+
return websiteOptions;
|
|
24
|
+
}
|
|
25
|
+
// ── HTTP safety check ─────────────────────────────────────────────────────────
|
|
26
|
+
export function shouldWarnOnPlainHttp(ref) {
|
|
27
|
+
if (!ref.startsWith("http://"))
|
|
28
|
+
return false;
|
|
29
|
+
try {
|
|
30
|
+
const hostname = new URL(ref).hostname.toLowerCase();
|
|
31
|
+
return (hostname !== "localhost" &&
|
|
32
|
+
hostname !== "127.0.0.1" &&
|
|
33
|
+
hostname !== "0.0.0.0" &&
|
|
34
|
+
hostname !== "::1" &&
|
|
35
|
+
hostname !== "[::1]" &&
|
|
36
|
+
!hostname.endsWith(".localhost"));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** Scan every env file in the freshly-installed stash for dangerous env keys. */
|
|
43
|
+
function collectDangerousKeyFindings(installedStashRoot, checkEnvForDangerousKeys) {
|
|
44
|
+
const allFindings = [];
|
|
45
|
+
const subdir = "env";
|
|
46
|
+
const prefix = "env";
|
|
47
|
+
const dir = path.join(installedStashRoot, subdir);
|
|
48
|
+
const envFiles = fs.existsSync(dir) ? fs.readdirSync(dir).filter((f) => f.endsWith(".env")) : [];
|
|
49
|
+
for (const envFile of envFiles) {
|
|
50
|
+
const envPath = path.join(dir, envFile);
|
|
51
|
+
const baseName = path.basename(envFile, ".env");
|
|
52
|
+
const vaultRef = baseName === "" ? `${prefix}:default` : `${prefix}:${baseName}`;
|
|
53
|
+
const relPath = path.join(subdir, envFile);
|
|
54
|
+
const findings = checkEnvForDangerousKeys(envPath, relPath, vaultRef);
|
|
55
|
+
for (const finding of findings) {
|
|
56
|
+
// Extract the key name from the detail string for the summary line.
|
|
57
|
+
const keyMatch = finding.detail.match(/Env key `([^`]+)`/);
|
|
58
|
+
const keyName = keyMatch ? keyMatch[1] : finding.file;
|
|
59
|
+
allFindings.push({ vaultRef, keyName, relPath });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return allFindings;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Audit a freshly-installed stash for dangerous env keys and decide whether the
|
|
66
|
+
* install must be blocked. Returns a typed decision instead of calling
|
|
67
|
+
* `process.exit`, so the abort cannot be lost to a swallowed exception. See the
|
|
68
|
+
* block comment above for the security rationale.
|
|
69
|
+
*/
|
|
70
|
+
export async function auditInstalledStashForDangerousKeys(opts) {
|
|
71
|
+
const { installedStashRoot, ref, allowDangerousKeys, rollbackTarget, isTTY } = opts;
|
|
72
|
+
// Best-effort scan: if collecting findings itself throws (corrupt env file,
|
|
73
|
+
// fs error) there is nothing concrete to block on, so fail soft. Crucially,
|
|
74
|
+
// this soft path runs BEFORE any findings exist — it can never re-open an
|
|
75
|
+
// already-detected dangerous install.
|
|
76
|
+
let allFindings;
|
|
77
|
+
try {
|
|
78
|
+
const { checkEnvForDangerousKeys } = await import("../lint/env-key-rules.js");
|
|
79
|
+
allFindings = collectDangerousKeyFindings(installedStashRoot, checkEnvForDangerousKeys);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return { blocked: false };
|
|
83
|
+
}
|
|
84
|
+
if (allFindings.length === 0)
|
|
85
|
+
return { blocked: false };
|
|
86
|
+
if (allowDangerousKeys) {
|
|
87
|
+
// Operator has explicitly accepted the risk — warn and continue.
|
|
88
|
+
for (const f of allFindings) {
|
|
89
|
+
warn(`[dangerous-vault-key] ${f.relPath}: key \`${f.keyName}\` in ${f.vaultRef} can hijack process execution via \`akm env run\`. Proceeding because --allow-insecure was set.`);
|
|
90
|
+
}
|
|
91
|
+
return { blocked: false };
|
|
92
|
+
}
|
|
93
|
+
// Helper: roll the install back before aborting. Rollback is best-effort; a
|
|
94
|
+
// failed rollback never UN-blocks the install — we still abort, just with a
|
|
95
|
+
// warning telling the operator to remove the stash manually.
|
|
96
|
+
async function rollback() {
|
|
97
|
+
try {
|
|
98
|
+
await akmRemove({ target: rollbackTarget });
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
catch (_rollbackErr) {
|
|
102
|
+
return (`Rollback failed — stash may still be installed at ${installedStashRoot}. ` +
|
|
103
|
+
`Remove it manually with: akm remove ${rollbackTarget}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (isTTY) {
|
|
107
|
+
// Interactive path: show findings and ask the user to confirm.
|
|
108
|
+
// Guard on stdin (not stdout) because p.confirm() reads from stdin;
|
|
109
|
+
// stdout may be a TTY while stdin is piped, which would cause a hang.
|
|
110
|
+
const stashLabel = ref;
|
|
111
|
+
const groupedByVault = new Map();
|
|
112
|
+
for (const f of allFindings) {
|
|
113
|
+
const existing = groupedByVault.get(f.vaultRef) ?? [];
|
|
114
|
+
existing.push(f.keyName);
|
|
115
|
+
groupedByVault.set(f.vaultRef, existing);
|
|
116
|
+
}
|
|
117
|
+
for (const [vaultRef, keys] of groupedByVault) {
|
|
118
|
+
warn(`[warn] Env "${vaultRef}" in stash "${stashLabel}" contains potentially dangerous keys:`);
|
|
119
|
+
for (const key of keys) {
|
|
120
|
+
warn(` - ${key}: can hijack process execution via \`akm env run\``);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const confirmed = await p.confirm({
|
|
124
|
+
message: "Install anyway?",
|
|
125
|
+
initialValue: false,
|
|
126
|
+
});
|
|
127
|
+
if (p.isCancel(confirmed) || confirmed !== true) {
|
|
128
|
+
const rollbackWarning = await rollback();
|
|
129
|
+
console.error(JSON.stringify({
|
|
130
|
+
ok: false,
|
|
131
|
+
error: "Install aborted: stash contains dangerous env keys. Remove the keys or re-run with --allow-insecure to bypass.",
|
|
132
|
+
code: "DANGEROUS_VAULT_KEY",
|
|
133
|
+
...(rollbackWarning ? { rollbackWarning } : {}),
|
|
134
|
+
}, null, 2));
|
|
135
|
+
return { blocked: true, exitCode: 1 };
|
|
136
|
+
}
|
|
137
|
+
// Operator confirmed at the prompt — allow the install to proceed.
|
|
138
|
+
return { blocked: false };
|
|
139
|
+
}
|
|
140
|
+
// Non-interactive path without bypass flag: fail hard.
|
|
141
|
+
const rollbackWarning = await rollback();
|
|
142
|
+
const keyList = allFindings.map((f) => ` - ${f.keyName} (${f.vaultRef})`).join("\n");
|
|
143
|
+
console.error(JSON.stringify({
|
|
144
|
+
ok: false,
|
|
145
|
+
error: `Install blocked: stash "${ref}" contains dangerous env keys that can hijack process execution via \`akm env run\`:\n${keyList}\nRe-run with --allow-insecure to bypass this check after reviewing the env file.`,
|
|
146
|
+
code: "DANGEROUS_VAULT_KEY",
|
|
147
|
+
...(rollbackWarning ? { rollbackWarning } : {}),
|
|
148
|
+
}, null, 2));
|
|
149
|
+
return { blocked: true, exitCode: 1 };
|
|
150
|
+
}
|
|
151
|
+
// ── Command definition ────────────────────────────────────────────────────────
|
|
152
|
+
export const addCommand = defineCommand({
|
|
153
|
+
meta: {
|
|
154
|
+
name: "add",
|
|
155
|
+
description: "Add a source (local directory, website, npm package, GitHub repo, git URL, or remote provider)",
|
|
156
|
+
},
|
|
157
|
+
args: {
|
|
158
|
+
ref: {
|
|
159
|
+
type: "positional",
|
|
160
|
+
description: "Path, URL, or registry ref (website URL, npm package, owner/repo, git URL, or local directory)",
|
|
161
|
+
required: true,
|
|
162
|
+
},
|
|
163
|
+
provider: { type: "string", description: "Provider type (e.g. website, npm). Required for URL sources." },
|
|
164
|
+
options: { type: "string", description: 'Provider options as JSON (e.g. \'{"apiKey":"key"}\').' },
|
|
165
|
+
name: { type: "string", description: "Human-friendly name for the source" },
|
|
166
|
+
writable: {
|
|
167
|
+
type: "boolean",
|
|
168
|
+
description: "Mark a git stash as writable so changes can be pushed back",
|
|
169
|
+
default: false,
|
|
170
|
+
},
|
|
171
|
+
type: {
|
|
172
|
+
type: "string",
|
|
173
|
+
description: "Override asset type for all files in this stash (currently supports: wiki)",
|
|
174
|
+
},
|
|
175
|
+
"max-pages": { type: "string", description: "Maximum pages to crawl for website sources (default: 50)" },
|
|
176
|
+
"max-depth": { type: "string", description: "Maximum crawl depth for website sources (default: 3)" },
|
|
177
|
+
"allow-insecure": {
|
|
178
|
+
type: "boolean",
|
|
179
|
+
description: "Allow a plain HTTP source URL and skip confirmation for dangerous env keys (e.g. LD_PRELOAD, PATH). Use only after explicitly reviewing the stash.",
|
|
180
|
+
default: false,
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
async run({ args }) {
|
|
184
|
+
await runWithJsonErrors(async () => {
|
|
185
|
+
const ref = args.ref.trim();
|
|
186
|
+
const allowInsecure = getHyphenatedBoolean(args, "allow-insecure");
|
|
187
|
+
const allowDangerousKeys = allowInsecure;
|
|
188
|
+
// URL with --provider → stash source (remote or git provider)
|
|
189
|
+
if (args.provider) {
|
|
190
|
+
if (shouldWarnOnPlainHttp(ref)) {
|
|
191
|
+
if (!allowInsecure) {
|
|
192
|
+
throw new UsageError("Source URL uses plain HTTP (not HTTPS). An on-path attacker could substitute a malicious payload. " +
|
|
193
|
+
"Use https:// or pass --allow-insecure if you have explicitly accepted the risk.", "INVALID_FLAG_VALUE", "Re-run with `--allow-insecure` only after confirming the URL is trusted.");
|
|
194
|
+
}
|
|
195
|
+
warn("Warning: source URL uses plain HTTP (not HTTPS). --allow-insecure was set; an on-path attacker could substitute a malicious payload.");
|
|
196
|
+
}
|
|
197
|
+
let parsedOptions;
|
|
198
|
+
if (args.options) {
|
|
199
|
+
try {
|
|
200
|
+
const parsed = JSON.parse(args.options);
|
|
201
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
202
|
+
throw new UsageError("--options must be a JSON object");
|
|
203
|
+
}
|
|
204
|
+
parsedOptions = parsed;
|
|
205
|
+
}
|
|
206
|
+
catch (err) {
|
|
207
|
+
if (err instanceof UsageError)
|
|
208
|
+
throw err;
|
|
209
|
+
throw new UsageError("--options must be valid JSON");
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
const result = addStash({
|
|
213
|
+
target: ref,
|
|
214
|
+
name: args.name,
|
|
215
|
+
providerType: args.provider,
|
|
216
|
+
options: parsedOptions,
|
|
217
|
+
writable: args.writable,
|
|
218
|
+
});
|
|
219
|
+
appendEvent({
|
|
220
|
+
eventType: "add",
|
|
221
|
+
metadata: { target: ref, provider: args.provider, name: args.name ?? null, writable: args.writable === true },
|
|
222
|
+
});
|
|
223
|
+
output("add", result);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
if (shouldWarnOnPlainHttp(ref)) {
|
|
227
|
+
if (!allowInsecure) {
|
|
228
|
+
throw new UsageError("Source URL uses plain HTTP (not HTTPS). An on-path attacker could substitute a malicious payload. " +
|
|
229
|
+
"Use https:// or pass --allow-insecure if you have explicitly accepted the risk.", "INVALID_FLAG_VALUE", "Re-run with `--allow-insecure` only after confirming the URL is trusted.");
|
|
230
|
+
}
|
|
231
|
+
warn("Warning: source URL uses plain HTTP (not HTTPS). --allow-insecure was set; an on-path attacker could substitute a malicious payload.");
|
|
232
|
+
}
|
|
233
|
+
const websiteOptions = buildWebsiteOptions(args);
|
|
234
|
+
if (args.type === "wiki") {
|
|
235
|
+
const { registerWikiSource } = await import("./source-add.js");
|
|
236
|
+
const result = await registerWikiSource({
|
|
237
|
+
ref,
|
|
238
|
+
name: args.name,
|
|
239
|
+
options: Object.keys(websiteOptions).length > 0 ? websiteOptions : undefined,
|
|
240
|
+
writable: args.writable,
|
|
241
|
+
});
|
|
242
|
+
appendEvent({
|
|
243
|
+
eventType: "add",
|
|
244
|
+
metadata: { target: ref, type: "wiki", name: args.name ?? null, writable: args.writable === true },
|
|
245
|
+
});
|
|
246
|
+
output("add", result);
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
const result = await akmAdd({
|
|
250
|
+
ref,
|
|
251
|
+
name: args.name,
|
|
252
|
+
overrideType: args.type,
|
|
253
|
+
options: Object.keys(websiteOptions).length > 0 ? websiteOptions : undefined,
|
|
254
|
+
writable: args.writable,
|
|
255
|
+
});
|
|
256
|
+
appendEvent({
|
|
257
|
+
eventType: "add",
|
|
258
|
+
metadata: {
|
|
259
|
+
target: ref,
|
|
260
|
+
name: args.name ?? null,
|
|
261
|
+
overrideType: args.type ?? null,
|
|
262
|
+
writable: args.writable === true,
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
// ── Post-install env key audit ──────────────────────────────────────────
|
|
266
|
+
// Resolve the stash root from the install result and scan any env files
|
|
267
|
+
// for dangerous env var keys. When findings are present the install is
|
|
268
|
+
// gated: TTY → interactive confirmation prompt; non-TTY without
|
|
269
|
+
// --allow-insecure → hard failure (exit 1). Pass
|
|
270
|
+
// --allow-insecure to skip the prompt non-interactively.
|
|
271
|
+
const installedStashRoot = result.installed?.stashRoot ??
|
|
272
|
+
(result.sourceAdded && "stashRoot" in result.sourceAdded ? result.sourceAdded.stashRoot : undefined);
|
|
273
|
+
if (installedStashRoot) {
|
|
274
|
+
// Use the canonical installed id (most reliably resolved by akmRemove) rather
|
|
275
|
+
// than the raw user-supplied ref which may not match after URL normalisation.
|
|
276
|
+
const rollbackTarget = result.installed?.id ?? result.sourceAdded?.stashRoot ?? ref;
|
|
277
|
+
// The audit RETURNS its decision; we decide `process.exit` here, OUTSIDE
|
|
278
|
+
// any catch, so the abort cannot be lost to a swallowed exception (C3).
|
|
279
|
+
const decision = await auditInstalledStashForDangerousKeys({
|
|
280
|
+
installedStashRoot,
|
|
281
|
+
ref,
|
|
282
|
+
allowDangerousKeys,
|
|
283
|
+
rollbackTarget,
|
|
284
|
+
isTTY: process.stdin.isTTY === true,
|
|
285
|
+
});
|
|
286
|
+
if (decision.blocked) {
|
|
287
|
+
process.exit(decision.exitCode);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
output("add", result);
|
|
291
|
+
});
|
|
292
|
+
},
|
|
293
|
+
});
|
|
@@ -1,12 +1,28 @@
|
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
/**
|
|
5
|
+
* `akm history` — surfaces internal mutation/usage events for a single asset
|
|
6
|
+
* (`--ref`) or stash-wide.
|
|
7
|
+
*
|
|
8
|
+
* Event sources:
|
|
9
|
+
* - `usage_events` SQLite table: search, show, and feedback events recorded
|
|
10
|
+
* by the local indexer during normal CLI use.
|
|
11
|
+
* - `events.jsonl` append-only stream (opt-in via `--include-proposals`):
|
|
12
|
+
* proposal lifecycle events (`promoted`, `rejected`) emitted by
|
|
13
|
+
* `akm proposal accept` / `akm proposal reject`. Use this flag to see
|
|
14
|
+
* the full proposal review trail alongside usage events.
|
|
15
|
+
*
|
|
16
|
+
* The two sources are merged and sorted chronologically (oldest first) so
|
|
17
|
+
* consumers see a coherent lifecycle trail in a single output.
|
|
18
|
+
*/
|
|
19
|
+
import { parseAssetRef } from "../../core/asset/asset-ref.js";
|
|
20
|
+
import { UsageError } from "../../core/errors.js";
|
|
21
|
+
import { readEvents } from "../../core/events.js";
|
|
22
|
+
import { isoToSqlite, parseSinceToIso } from "../../core/time.js";
|
|
23
|
+
import { closeDatabase, openExistingDatabase } from "../../indexer/db/db.js";
|
|
24
|
+
import { getUsageEvents } from "../../indexer/usage/usage-events.js";
|
|
25
|
+
import { listProposals } from "../proposal/validators/proposals.js";
|
|
10
26
|
// Proposal lifecycle event types emitted by the proposal substrate (#225).
|
|
11
27
|
const PROPOSAL_EVENT_TYPES = new Set(["promoted", "rejected"]);
|
|
12
28
|
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
@@ -71,25 +87,11 @@ export async function akmHistory(options = {}) {
|
|
|
71
87
|
const db = options.db ?? openExistingDatabase();
|
|
72
88
|
const ownsDb = options.db === undefined;
|
|
73
89
|
try {
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
if (sinceNormalized !== undefined) {
|
|
81
|
-
conditions.push("created_at >= ?");
|
|
82
|
-
params.push(sinceNormalized);
|
|
83
|
-
}
|
|
84
|
-
if (options.source !== undefined) {
|
|
85
|
-
conditions.push("source = ?");
|
|
86
|
-
params.push(options.source);
|
|
87
|
-
}
|
|
88
|
-
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
89
|
-
const sql = `SELECT id, event_type, query, entry_id, entry_ref, signal, metadata, source, created_at
|
|
90
|
-
FROM usage_events ${where}
|
|
91
|
-
ORDER BY id ASC`;
|
|
92
|
-
const rows = db.prepare(sql).all(...params);
|
|
90
|
+
const rows = getUsageEvents(db, {
|
|
91
|
+
entry_ref: normalizedRef,
|
|
92
|
+
since: sinceNormalized,
|
|
93
|
+
source: options.source,
|
|
94
|
+
});
|
|
93
95
|
const usageEntries = rows.map(toEntry);
|
|
94
96
|
// ── Proposal lifecycle events (opt-in) ────────────────────────────────
|
|
95
97
|
const sources = ["usage_events"];
|
|
@@ -2,12 +2,12 @@
|
|
|
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
4
|
import fs from "node:fs";
|
|
5
|
-
import { getAssetTypes } from "
|
|
6
|
-
import { getSources, loadConfig } from "
|
|
7
|
-
import { getDbPath } from "
|
|
8
|
-
import { closeDatabase, getEntryCount, getMeta, isVecAvailable, openExistingDatabase } from "
|
|
9
|
-
import { getEffectiveSemanticStatus, readSemanticStatus } from "
|
|
10
|
-
import { pkgVersion } from "
|
|
5
|
+
import { getAssetTypes } from "../../core/asset/asset-spec.js";
|
|
6
|
+
import { getSources, loadConfig } from "../../core/config/config.js";
|
|
7
|
+
import { getDbPath } from "../../core/paths.js";
|
|
8
|
+
import { closeDatabase, getEntryCount, getMeta, isVecAvailable, openExistingDatabase } from "../../indexer/db/db.js";
|
|
9
|
+
import { getEffectiveSemanticStatus, readSemanticStatus } from "../../indexer/search/semantic-status.js";
|
|
10
|
+
import { pkgVersion } from "../../version.js";
|
|
11
11
|
/**
|
|
12
12
|
* Assemble system info describing the current capabilities, configuration,
|
|
13
13
|
* and index state. Used by `akm info`.
|
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
import { spawnSync } from "node:child_process";
|
|
11
11
|
import fs from "node:fs";
|
|
12
12
|
import path from "node:path";
|
|
13
|
-
import { TYPE_DIRS } from "
|
|
14
|
-
import { loadUserConfig, saveConfig } from "
|
|
15
|
-
import { ConfigError } from "
|
|
16
|
-
import { assertSafeStashDir, getBinDir, getConfigPath, getDefaultStashDir } from "
|
|
17
|
-
import { ensureRg } from "
|
|
18
|
-
import { copyStashSkeleton, scaffoldStashMeta } from "./stash-skeleton";
|
|
13
|
+
import { TYPE_DIRS } from "../../core/asset/asset-spec.js";
|
|
14
|
+
import { loadUserConfig, saveConfig } from "../../core/config/config.js";
|
|
15
|
+
import { ConfigError } from "../../core/errors.js";
|
|
16
|
+
import { assertSafeStashDir, getBinDir, getConfigPath, getDefaultStashDir } from "../../core/paths.js";
|
|
17
|
+
import { ensureRg } from "../../core/ripgrep/install.js";
|
|
18
|
+
import { copyStashSkeleton, scaffoldStashMeta } from "./stash-skeleton.js";
|
|
19
19
|
/**
|
|
20
20
|
* Refuse to persist a temporary-directory stashDir to the user's config when
|
|
21
21
|
* running under a test runner AND `--dir <tempdir>` was passed explicitly.
|
|
@@ -9,18 +9,18 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import fs from "node:fs";
|
|
11
11
|
import path from "node:path";
|
|
12
|
-
import { isWithin, resolveStashDir } from "
|
|
13
|
-
import { getSources, loadConfig } from "
|
|
14
|
-
import { NotFoundError, UsageError } from "
|
|
15
|
-
import { akmIndex } from "
|
|
16
|
-
import { removeLockEntry, upsertLockEntry } from "
|
|
17
|
-
import { parseRegistryRef } from "
|
|
18
|
-
import { parseGitRepoUrl, syncMirroredRepo } from "
|
|
19
|
-
import { syncFromRef } from "
|
|
20
|
-
import { ensureWebsiteMirror } from "
|
|
21
|
-
import { listWikis, resolveWikisRoot } from "
|
|
22
|
-
import { removeInstalledRegistryEntry, upsertInstalledRegistryEntry } from "./source-add";
|
|
23
|
-
import { removeStash } from "./source-manage";
|
|
12
|
+
import { isWithin, resolveStashDir } from "../../core/common.js";
|
|
13
|
+
import { getSources, loadConfig } from "../../core/config/config.js";
|
|
14
|
+
import { NotFoundError, UsageError } from "../../core/errors.js";
|
|
15
|
+
import { akmIndex } from "../../indexer/indexer.js";
|
|
16
|
+
import { removeLockEntry, upsertLockEntry } from "../../integrations/lockfile.js";
|
|
17
|
+
import { parseRegistryRef } from "../../registry/resolve.js";
|
|
18
|
+
import { parseGitRepoUrl, syncMirroredRepo } from "../../sources/providers/git.js";
|
|
19
|
+
import { syncFromRef } from "../../sources/providers/sync-from-ref.js";
|
|
20
|
+
import { ensureWebsiteMirror } from "../../sources/website-ingest.js";
|
|
21
|
+
import { listWikis, resolveWikisRoot } from "../../wiki/wiki.js";
|
|
22
|
+
import { removeInstalledRegistryEntry, upsertInstalledRegistryEntry } from "./source-add.js";
|
|
23
|
+
import { removeStash } from "./source-manage.js";
|
|
24
24
|
export async function akmListSources(input) {
|
|
25
25
|
const stashDir = input?.stashDir ?? resolveStashDir();
|
|
26
26
|
const config = loadConfig();
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
6
|
+
import { getDirname } from "../../runtime.js";
|
|
6
7
|
const CHANGELOG_URL = "https://github.com/itlackey/akm/blob/main/CHANGELOG.md";
|
|
7
8
|
const MIGRATION_DOC_URL = "https://github.com/itlackey/akm/blob/main/docs/migration/v0.5-to-v0.6.md";
|
|
8
9
|
/**
|
|
@@ -13,11 +14,11 @@ const MIGRATION_DOC_URL = "https://github.com/itlackey/akm/blob/main/docs/migrat
|
|
|
13
14
|
* `files[]` array in `package.json`.
|
|
14
15
|
*/
|
|
15
16
|
function releaseNotesDir() {
|
|
16
|
-
return path.resolve(import.meta.
|
|
17
|
+
return path.resolve(getDirname(import.meta.url), "../../../docs/migration/release-notes");
|
|
17
18
|
}
|
|
18
19
|
function loadChangelog() {
|
|
19
20
|
try {
|
|
20
|
-
const changelogPath = path.resolve(import.meta.
|
|
21
|
+
const changelogPath = path.resolve(getDirname(import.meta.url), "../../../CHANGELOG.md");
|
|
21
22
|
if (fs.existsSync(changelogPath)) {
|
|
22
23
|
return fs.readFileSync(changelogPath, "utf8");
|
|
23
24
|
}
|
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import fs from "node:fs";
|
|
16
16
|
import path from "node:path";
|
|
17
|
-
import { parseAssetRef } from "
|
|
18
|
-
import { assembleAsset } from "
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
17
|
+
import { parseAssetRef } from "../../core/asset/asset-ref.js";
|
|
18
|
+
import { assembleAsset } from "../../core/asset/asset-serialize.js";
|
|
19
|
+
import { parseFrontmatter } from "../../core/asset/frontmatter.js";
|
|
20
|
+
import { appendEvent, readEvents } from "../../core/events.js";
|
|
21
|
+
import { info, warn } from "../../core/warn.js";
|
|
22
|
+
import { resolveAssetPath } from "../../indexer/walk/path-resolver.js";
|
|
23
|
+
import { chatCompletion, parseEmbeddedJsonResponse } from "../../llm/client.js";
|
|
24
|
+
import { createProposal, isProposalSkipped } from "../proposal/validators/proposals.js";
|
|
25
25
|
// ── Constants ────────────────────────────────────────────────────────────────
|
|
26
26
|
/** Minimum gap between schema-repair attempts on the same asset. */
|
|
27
27
|
const SCHEMA_REPAIR_COOLDOWN_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
|
|
@@ -5,9 +5,10 @@ import * as childProcess from "node:child_process";
|
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
6
6
|
import fs from "node:fs";
|
|
7
7
|
import path from "node:path";
|
|
8
|
-
import { fetchWithRetry, IS_WINDOWS } from "
|
|
9
|
-
import { warn } from "
|
|
10
|
-
import { githubHeaders } from "
|
|
8
|
+
import { fetchWithRetry, IS_WINDOWS } from "../../core/common.js";
|
|
9
|
+
import { warn } from "../../core/warn.js";
|
|
10
|
+
import { githubHeaders } from "../../integrations/github.js";
|
|
11
|
+
import { getDirname, mainPath, semverOrder } from "../../runtime.js";
|
|
11
12
|
const REPO = "itlackey/akm";
|
|
12
13
|
const DEFAULT_PACKAGE_NAME = "akm-cli";
|
|
13
14
|
const NODE_MODULES_SEGMENT = "/node_modules/";
|
|
@@ -16,8 +17,8 @@ const PNPM_GLOBAL_INSTALL_PATTERN = /(^|\/)(?:pnpm\/global|\.pnpm-global)(?:\/\d
|
|
|
16
17
|
/** Read live runtime signals. */
|
|
17
18
|
export function getInstallSignals() {
|
|
18
19
|
return {
|
|
19
|
-
bunMain:
|
|
20
|
-
importMetaDir: import.meta.
|
|
20
|
+
bunMain: mainPath,
|
|
21
|
+
importMetaDir: getDirname(import.meta.url),
|
|
21
22
|
hasAkmVersion: typeof AKM_VERSION !== "undefined",
|
|
22
23
|
};
|
|
23
24
|
}
|
|
@@ -34,8 +35,8 @@ export function detectInstallMethod(signals) {
|
|
|
34
35
|
}
|
|
35
36
|
return "npm";
|
|
36
37
|
}
|
|
37
|
-
// Bun-compiled binaries:
|
|
38
|
-
// NOT process.execPath. The old check (
|
|
38
|
+
// Bun-compiled binaries: mainPath points to a virtual /$bunfs/
|
|
39
|
+
// path, NOT process.execPath. The old check (mainPath === process.execPath) was
|
|
39
40
|
// always false for compiled binaries, causing "unknown" for every binary user.
|
|
40
41
|
if (s.bunMain !== undefined) {
|
|
41
42
|
// Primary check: compiled binaries embed sources under /$bunfs/
|
|
@@ -77,7 +78,7 @@ export async function checkForUpdate(currentVersion) {
|
|
|
77
78
|
return {
|
|
78
79
|
currentVersion,
|
|
79
80
|
latestVersion,
|
|
80
|
-
updateAvailable: latestVersion !== "" &&
|
|
81
|
+
updateAvailable: latestVersion !== "" && semverOrder(currentVersion, latestVersion) < 0,
|
|
81
82
|
installMethod,
|
|
82
83
|
};
|
|
83
84
|
}
|
|
@@ -373,7 +374,7 @@ function normalizePathSeparators(value) {
|
|
|
373
374
|
}
|
|
374
375
|
function getInstalledPackageName() {
|
|
375
376
|
try {
|
|
376
|
-
const pkgPath = path.resolve(import.meta.
|
|
377
|
+
const pkgPath = path.resolve(getDirname(import.meta.url), "../../../package.json");
|
|
377
378
|
if (fs.existsSync(pkgPath)) {
|
|
378
379
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
379
380
|
if (typeof pkg.name === "string" && pkg.name.trim()) {
|
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
6
|
-
import { isHttpUrl, resolveStashDir } from "
|
|
7
|
-
import { getSources, loadConfig, loadUserConfig, saveConfig } from "
|
|
8
|
-
import { ConfigError, UsageError } from "
|
|
9
|
-
import { akmIndex } from "
|
|
10
|
-
import { upsertLockEntry } from "
|
|
11
|
-
import { parseRegistryRef } from "
|
|
12
|
-
import { detectStashRoot } from "
|
|
13
|
-
import { syncFromRef } from "
|
|
14
|
-
import { ensureWebsiteMirror, validateWebsiteInputUrl } from "
|
|
15
|
-
import { ensureWikiNameAvailable, validateWikiName } from "
|
|
6
|
+
import { isHttpUrl, resolveStashDir } from "../../core/common.js";
|
|
7
|
+
import { getSources, loadConfig, loadUserConfig, saveConfig } from "../../core/config/config.js";
|
|
8
|
+
import { ConfigError, UsageError } from "../../core/errors.js";
|
|
9
|
+
import { akmIndex } from "../../indexer/indexer.js";
|
|
10
|
+
import { upsertLockEntry } from "../../integrations/lockfile.js";
|
|
11
|
+
import { parseRegistryRef } from "../../registry/resolve.js";
|
|
12
|
+
import { detectStashRoot } from "../../sources/providers/provider-utils.js";
|
|
13
|
+
import { syncFromRef } from "../../sources/providers/sync-from-ref.js";
|
|
14
|
+
import { ensureWebsiteMirror, validateWebsiteInputUrl } from "../../sources/website-ingest.js";
|
|
15
|
+
import { ensureWikiNameAvailable, validateWikiName } from "../../wiki/wiki.js";
|
|
16
16
|
const VALID_OVERRIDE_TYPES = new Set(["wiki"]);
|
|
17
17
|
export async function akmAdd(input) {
|
|
18
18
|
const ref = input.ref.trim();
|