akm-cli 0.9.0-beta.6 → 0.9.0-rc.0
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 +663 -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/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 -14
- 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-cli.js +220 -227
- package/dist/commands/env/env.js +14 -67
- package/dist/commands/env/secret-cli.js +140 -138
- package/dist/commands/feedback-cli.js +153 -147
- package/dist/commands/graph/graph-cli.js +5 -13
- package/dist/commands/graph/graph.js +76 -72
- 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 -1083
- 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 +1313 -1278
- 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 +243 -599
- 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 +55 -4
- 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 +160 -7
- package/dist/commands/improve/improve-cli.js +115 -73
- package/dist/commands/improve/improve-profiles.js +32 -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 +510 -2537
- 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 +115 -0
- 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 +212 -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 +7 -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 -882
- package/dist/commands/read/curate.js +419 -103
- 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/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 +29 -41
- 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 +15 -1
- package/dist/core/asset/asset-registry.js +3 -1
- package/dist/core/asset/asset-spec.js +21 -4
- 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 +389 -58
- 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/logs-db.js +14 -75
- package/dist/core/parse.js +36 -16
- package/dist/core/paths.js +21 -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 +142 -1091
- 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 +356 -780
- 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 +103 -24
- 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 +106 -0
- package/dist/indexer/index-written-assets.js +105 -0
- package/dist/indexer/indexer.js +291 -310
- 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 +9 -0
- package/dist/indexer/walk/walker.js +21 -13
- package/dist/integrations/agent/builders.js +39 -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 +7 -2
- package/dist/integrations/agent/profiles.js +7 -1
- package/dist/integrations/agent/prompts.js +75 -9
- package/dist/integrations/agent/runner-dispatch.js +59 -0
- package/dist/integrations/agent/runner.js +13 -9
- package/dist/integrations/agent/spawn.js +69 -67
- package/dist/integrations/harnesses/claude/agent-builder.js +1 -1
- package/dist/integrations/harnesses/claude/index.js +2 -0
- package/dist/integrations/harnesses/claude/session-log.js +11 -1
- package/dist/integrations/harnesses/index.js +2 -3
- package/dist/integrations/harnesses/opencode/agent-builder.js +1 -1
- package/dist/integrations/harnesses/opencode/index.js +2 -0
- package/dist/integrations/harnesses/opencode/session-log.js +173 -3
- package/dist/integrations/harnesses/opencode-sdk/index.js +2 -2
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +98 -17
- package/dist/integrations/harnesses/types.js +1 -0
- package/dist/integrations/session-logs/index.js +16 -0
- package/dist/llm/call-ai.js +2 -2
- package/dist/llm/client.js +57 -15
- 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 +85 -14
- package/dist/output/shapes/curate.js +14 -2
- package/dist/output/shapes/helpers.js +0 -3
- package/dist/output/shapes/passthrough.js +2 -1
- package/dist/output/text/helpers.js +29 -1
- package/dist/output/text/workflow.js +1 -0
- 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/scripts/migrate-storage.js +2718 -2354
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +891 -597
- 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/tar-utils.js +16 -8
- 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/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 +0 -0
- package/dist/wiki/wiki.js +52 -11
- package/dist/workflows/cli.js +1 -0
- package/dist/workflows/db.js +3 -4
- package/dist/workflows/runtime/runs.js +43 -118
- package/dist/workflows/runtime/workflow-asset-loader.js +125 -0
- package/dist/workflows/validate-summary.js +2 -7
- package/docs/README.md +69 -18
- package/docs/data-and-telemetry.md +5 -4
- package/docs/migration/release-notes/0.7.0.md +1 -1
- 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
|
@@ -5,39 +5,39 @@
|
|
|
5
5
|
* Stash-lifecycle command cluster — the create/index/ingest/inspect verbs for
|
|
6
6
|
* the working stash and its index database: `akm init` (create the stash +
|
|
7
7
|
* persist stashDir), `akm index` (build/refresh the search index), `akm import`
|
|
8
|
-
* (ingest a knowledge doc/URL), `akm
|
|
9
|
-
*
|
|
8
|
+
* (ingest a knowledge doc/URL), and `akm info` (system capabilities + index
|
|
9
|
+
* stats).
|
|
10
10
|
* Extracted verbatim from src/cli.ts (WS6) so the God Module shrinks; the
|
|
11
|
-
* `main.subCommands.{init,index,import,
|
|
11
|
+
* `main.subCommands.{init,index,import,info}` keys and every subcommand's
|
|
12
12
|
* args/output shape stay byte-identical.
|
|
13
13
|
*
|
|
14
14
|
* These share no private helper with any command still inline in cli.ts — every
|
|
15
15
|
* dependency is already exported from a shared module (core/paths, core/warn,
|
|
16
16
|
* core/errors, core/events, output/context, cli/shared, cli/parse-args, plus the
|
|
17
|
-
* per-command implementations in ./init, ./indexer, ./info, ./
|
|
17
|
+
* per-command implementations in ./init, ./indexer, ./info, ./knowledge,
|
|
18
18
|
* ./core/asset-create, ./core/common), so the cluster moves with zero hoisting.
|
|
19
19
|
*
|
|
20
20
|
* The leaf handlers whose body is a plain `runWithJsonErrors(...) + output(...)`
|
|
21
|
-
* (`init`, `import`, `info
|
|
21
|
+
* (`init`, `import`, `info`) are migrated onto
|
|
22
22
|
* `defineJsonCommand`, which emits the same JSON envelope (stdout/stderr/
|
|
23
23
|
* exit-code) as the inline form. `index` keeps a plain `defineCommand` wrapping
|
|
24
24
|
* `runWithJsonErrors` because its body owns a spinner, an AbortController, and
|
|
25
25
|
* SIGINT/SIGTERM handlers in a try/finally — left byte-for-byte untouched.
|
|
26
26
|
*/
|
|
27
27
|
import path from "node:path";
|
|
28
|
-
import * as p from "@clack/prompts";
|
|
29
28
|
import { defineCommand } from "citty";
|
|
30
|
-
import
|
|
29
|
+
import * as p from "../../cli/clack.js";
|
|
31
30
|
import { defineJsonCommand, output, runWithJsonErrors } from "../../cli/shared.js";
|
|
32
31
|
import { assertFlatAssetName } from "../../core/asset/asset-create.js";
|
|
33
32
|
import { isHttpUrl } from "../../core/common.js";
|
|
33
|
+
import { loadConfig } from "../../core/config/config.js";
|
|
34
34
|
import { UsageError } from "../../core/errors.js";
|
|
35
35
|
import { appendEvent } from "../../core/events.js";
|
|
36
36
|
import { getCacheDir } from "../../core/paths.js";
|
|
37
37
|
import { clearLogFile, info, isVerbose, setLogFile } from "../../core/warn.js";
|
|
38
|
+
import { resolveWriteTarget } from "../../core/write-source.js";
|
|
38
39
|
import { akmIndex } from "../../indexer/indexer.js";
|
|
39
40
|
import { getHyphenatedBoolean, getOutputMode, parseFlagValue } from "../../output/context.js";
|
|
40
|
-
import { akmDbBackups } from "../db-cli.js";
|
|
41
41
|
import { readKnowledgeInput, writeMarkdownAsset } from "../read/knowledge.js";
|
|
42
42
|
import { assembleInfo } from "./info.js";
|
|
43
43
|
import { akmInit } from "./init.js";
|
|
@@ -48,12 +48,20 @@ export const initCommand = defineJsonCommand({
|
|
|
48
48
|
},
|
|
49
49
|
args: {
|
|
50
50
|
dir: { type: "string", description: "Custom stash directory path (default: ~/akm)" },
|
|
51
|
+
"set-default": {
|
|
52
|
+
type: "boolean",
|
|
53
|
+
description: "Make --dir the default stash (write stashDir to config.json). Without this, `akm init --dir X` scaffolds X but leaves your existing default stash unchanged.",
|
|
54
|
+
default: false,
|
|
55
|
+
},
|
|
51
56
|
},
|
|
52
57
|
async run({ args }) {
|
|
53
58
|
// Accept both historical spellings for backwards compatibility with
|
|
54
59
|
// older docs/scripts that used `--stashDir`.
|
|
55
60
|
const legacyDir = parseFlagValue(process.argv, "--stashDir") ?? parseFlagValue(process.argv, "--stash-dir");
|
|
56
|
-
const result = await akmInit({
|
|
61
|
+
const result = await akmInit({
|
|
62
|
+
dir: args.dir ?? legacyDir,
|
|
63
|
+
setDefault: args["set-default"],
|
|
64
|
+
});
|
|
57
65
|
output("init", result);
|
|
58
66
|
},
|
|
59
67
|
});
|
|
@@ -71,6 +79,11 @@ export const indexCommand = defineCommand({
|
|
|
71
79
|
description: "When combined with --clean, report stale entries without deleting them.",
|
|
72
80
|
default: false,
|
|
73
81
|
},
|
|
82
|
+
background: {
|
|
83
|
+
type: "boolean",
|
|
84
|
+
description: "Run as a background process (suppresses interactive output, manages PID file).",
|
|
85
|
+
default: false,
|
|
86
|
+
},
|
|
74
87
|
},
|
|
75
88
|
async run({ args }) {
|
|
76
89
|
await runWithJsonErrors(async () => {
|
|
@@ -80,6 +93,7 @@ export const indexCommand = defineCommand({
|
|
|
80
93
|
if (getHyphenatedBoolean(args, "re-enrich") || parseFlagValue(process.argv, "--re-enrich") !== undefined) {
|
|
81
94
|
throw new UsageError("`akm index --re-enrich` has been removed. Re-enrichment of index-time LLM passes is not exposed in this slice.");
|
|
82
95
|
}
|
|
96
|
+
const isBackground = args.background === true;
|
|
83
97
|
const outputMode = getOutputMode();
|
|
84
98
|
const controller = new AbortController();
|
|
85
99
|
const abort = () => controller.abort(new Error("index interrupted"));
|
|
@@ -88,7 +102,7 @@ export const indexCommand = defineCommand({
|
|
|
88
102
|
const indexLogFile = path.join(getCacheDir(), "logs", "index", `${new Date().toISOString().replace(/[:.]/g, "-")}.log`);
|
|
89
103
|
setLogFile(indexLogFile);
|
|
90
104
|
const verbose = isVerbose();
|
|
91
|
-
const spin = !verbose && outputMode.format === "text" ? p.spinner() : null;
|
|
105
|
+
const spin = !verbose && !isBackground && outputMode.format === "text" ? p.spinner() : null;
|
|
92
106
|
if (spin) {
|
|
93
107
|
spin.start(`Building search index${args.full ? " (full rebuild)" : ""}...`);
|
|
94
108
|
}
|
|
@@ -114,7 +128,9 @@ export const indexCommand = defineCommand({
|
|
|
114
128
|
if (spin) {
|
|
115
129
|
spin.stop(`Indexed ${result.totalEntries} assets.`);
|
|
116
130
|
}
|
|
117
|
-
|
|
131
|
+
if (!isBackground) {
|
|
132
|
+
output("index", result);
|
|
133
|
+
}
|
|
118
134
|
}
|
|
119
135
|
catch (error) {
|
|
120
136
|
if (spin) {
|
|
@@ -137,35 +153,6 @@ export const infoCommand = defineJsonCommand({
|
|
|
137
153
|
output("info", result);
|
|
138
154
|
},
|
|
139
155
|
});
|
|
140
|
-
// MVP DB administration. Currently only `akm db backups`; restore is manual —
|
|
141
|
-
// stop akm and run `scripts/migrations/restore-data-dir.sh <backup>`.
|
|
142
|
-
// Single source of truth: the routing set is derived from the subCommands keys
|
|
143
|
-
// (M10) so adding a subcommand can never silently desync from `hasSubcommand`.
|
|
144
|
-
const dbSubCommands = {
|
|
145
|
-
backups: defineJsonCommand({
|
|
146
|
-
meta: {
|
|
147
|
-
name: "backups",
|
|
148
|
-
description: "List pre-upgrade snapshots of the data directory (newest first). Backups are created automatically before destructive DB version upgrades unless AKM_DB_BACKUP=0.",
|
|
149
|
-
},
|
|
150
|
-
run() {
|
|
151
|
-
output("db-backups", akmDbBackups());
|
|
152
|
-
},
|
|
153
|
-
}),
|
|
154
|
-
};
|
|
155
|
-
const DB_SUBCOMMAND_SET = new Set(Object.keys(dbSubCommands));
|
|
156
|
-
export const dbCommand = defineJsonCommand({
|
|
157
|
-
meta: {
|
|
158
|
-
name: "db",
|
|
159
|
-
description: "Inspect the AKM SQLite data directory. Currently exposes `backups`; to restore from a snapshot, stop akm and run scripts/migrations/restore-data-dir.sh against the chosen backup.",
|
|
160
|
-
},
|
|
161
|
-
subCommands: dbSubCommands,
|
|
162
|
-
run({ args }) {
|
|
163
|
-
if (hasSubcommand(args, DB_SUBCOMMAND_SET))
|
|
164
|
-
return;
|
|
165
|
-
// Default action: list backups.
|
|
166
|
-
output("db-backups", akmDbBackups());
|
|
167
|
-
},
|
|
168
|
-
});
|
|
169
156
|
export const importKnowledgeCommand = defineJsonCommand({
|
|
170
157
|
meta: {
|
|
171
158
|
name: "import",
|
|
@@ -198,7 +185,8 @@ export const importKnowledgeCommand = defineJsonCommand({
|
|
|
198
185
|
async run({ args }) {
|
|
199
186
|
// `--name` is a flat name; subdirectory placement is `--path`'s job.
|
|
200
187
|
assertFlatAssetName(args.name);
|
|
201
|
-
const
|
|
188
|
+
const stashDir = resolveWriteTarget(loadConfig(), args.target).source.path;
|
|
189
|
+
const { content, preferredName } = await readKnowledgeInput(args.source, { stashDir });
|
|
202
190
|
const result = await writeMarkdownAsset({
|
|
203
191
|
type: "knowledge",
|
|
204
192
|
content,
|
|
@@ -6,27 +6,42 @@ import path from "node:path";
|
|
|
6
6
|
import { getDirname } from "../../runtime.js";
|
|
7
7
|
const SKELETON_DIR = path.join(getDirname(import.meta.url), "../../assets/stash-skeleton");
|
|
8
8
|
/**
|
|
9
|
-
* Copy the default stash skeleton into a
|
|
9
|
+
* Copy the default stash skeleton into a stash directory.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* The skeleton tree under src/assets/stash-skeleton/ is mirrored **recursively**
|
|
12
|
+
* into the stash root, preserving relative subpaths (e.g.
|
|
13
|
+
* `facts/conventions/assets/skill.md` lands at the matching stash subpath).
|
|
14
|
+
* Each file is written only if the destination does not already exist — existing
|
|
15
|
+
* (possibly user-edited) files are never overwritten. Intermediate directories
|
|
16
|
+
* are created as needed.
|
|
17
|
+
*
|
|
18
|
+
* Idempotent and absent-only: running it again on an existing stash backfills
|
|
19
|
+
* any skeleton files that are missing without clobbering present ones. Non-fatal:
|
|
20
|
+
* if the skeleton directory is missing or a copy fails the caller continues.
|
|
15
21
|
*/
|
|
16
22
|
export function copyStashSkeleton(stashDir) {
|
|
23
|
+
copySkeletonDir(SKELETON_DIR, stashDir);
|
|
24
|
+
}
|
|
25
|
+
/** Recursively mirror `srcDir` into `destDir`, writing files only when absent. */
|
|
26
|
+
function copySkeletonDir(srcDir, destDir) {
|
|
17
27
|
let entries;
|
|
18
28
|
try {
|
|
19
|
-
entries = fs.readdirSync(
|
|
29
|
+
entries = fs.readdirSync(srcDir, { withFileTypes: true });
|
|
20
30
|
}
|
|
21
31
|
catch {
|
|
22
32
|
return;
|
|
23
33
|
}
|
|
24
34
|
for (const entry of entries) {
|
|
25
|
-
const src = path.join(
|
|
26
|
-
const dest = path.join(
|
|
35
|
+
const src = path.join(srcDir, entry.name);
|
|
36
|
+
const dest = path.join(destDir, entry.name);
|
|
37
|
+
if (entry.isDirectory()) {
|
|
38
|
+
copySkeletonDir(src, dest);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
27
41
|
if (fs.existsSync(dest))
|
|
28
42
|
continue;
|
|
29
43
|
try {
|
|
44
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
30
45
|
fs.copyFileSync(src, dest);
|
|
31
46
|
}
|
|
32
47
|
catch {
|
|
@@ -56,6 +71,40 @@ export function scaffoldStashMeta(stashDir) {
|
|
|
56
71
|
// Non-fatal — stash is usable without the .meta orientation doc
|
|
57
72
|
}
|
|
58
73
|
}
|
|
74
|
+
/** Marks the akm-authored block in a stash `.gitignore` (idempotency anchor). */
|
|
75
|
+
const STASH_GITIGNORE_MARKER = "# akm: keep secret material out of git by default";
|
|
76
|
+
const STASH_GITIGNORE_BLOCK = [
|
|
77
|
+
STASH_GITIGNORE_MARKER,
|
|
78
|
+
"# env/ and secrets/ assets hold tokens and keys. They are ignored by default",
|
|
79
|
+
"# so `git push` can never leak them. To version a specific one (e.g. for a",
|
|
80
|
+
"# private-remote backup), un-ignore its path below once you accept the risk.",
|
|
81
|
+
"env/",
|
|
82
|
+
"secrets/",
|
|
83
|
+
"",
|
|
84
|
+
].join("\n");
|
|
85
|
+
/**
|
|
86
|
+
* Ensure the stash `.gitignore` keeps `env/` and `secrets/` out of git by
|
|
87
|
+
* default (08-F1: the v0.8.0 `vaults/` → `env/`+`secrets/` migration never
|
|
88
|
+
* carried the ignore rules forward, and init scaffolded none).
|
|
89
|
+
*
|
|
90
|
+
* Idempotent + non-clobbering: creates the file when absent, appends the akm
|
|
91
|
+
* block when the file exists but lacks it (preserving the user's own rules),
|
|
92
|
+
* and no-ops once the marker is present. The user opts INTO versioning by
|
|
93
|
+
* un-ignoring a path.
|
|
94
|
+
*/
|
|
95
|
+
export function ensureStashGitignore(stashDir) {
|
|
96
|
+
try {
|
|
97
|
+
const gitignorePath = path.join(stashDir, ".gitignore");
|
|
98
|
+
const existing = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, "utf8") : "";
|
|
99
|
+
if (existing.includes(STASH_GITIGNORE_MARKER))
|
|
100
|
+
return;
|
|
101
|
+
const gap = existing.length === 0 ? "" : existing.endsWith("\n") ? "\n" : "\n\n";
|
|
102
|
+
fs.writeFileSync(gitignorePath, `${existing}${gap}${STASH_GITIGNORE_BLOCK}`);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Non-fatal — the stash is usable without the ignore scaffold.
|
|
106
|
+
}
|
|
107
|
+
}
|
|
59
108
|
const STASH_META_INDEX_TEMPLATE = `---
|
|
60
109
|
# Optional, human-authored orientation for this stash. Not indexed; surfaced
|
|
61
110
|
# on demand via \`akm show meta\` (this file) or \`akm show <stash>//meta\`.
|
|
@@ -20,8 +20,9 @@ import fs from "node:fs";
|
|
|
20
20
|
import os from "node:os";
|
|
21
21
|
import { akmTasksAdd, akmTasksList } from "./tasks.js";
|
|
22
22
|
/**
|
|
23
|
-
* The canonical default improve task set. `update-stashes`
|
|
24
|
-
*
|
|
23
|
+
* The canonical default improve task set. The `update-stashes` embedded core
|
|
24
|
+
* template (nightly `akm update --all`) was retired in meta-review 06-M2:
|
|
25
|
+
* third-party stash pulls are on-demand only now, not a scheduled cron.
|
|
25
26
|
*/
|
|
26
27
|
export const DEFAULT_IMPROVE_TASKS = [
|
|
27
28
|
{
|
|
@@ -76,12 +77,19 @@ const DEFAULT_DEPS = {
|
|
|
76
77
|
list: akmTasksList,
|
|
77
78
|
add: akmTasksAdd,
|
|
78
79
|
};
|
|
80
|
+
let defaultTasksOverrides;
|
|
81
|
+
/** TEST-ONLY. Swap the CI/server/register functions; pass undefined to restore. */
|
|
82
|
+
export function _setDefaultTasksForTests(fakes) {
|
|
83
|
+
defaultTasksOverrides = fakes;
|
|
84
|
+
}
|
|
79
85
|
/**
|
|
80
86
|
* Decide whether `akm setup` is running in a CI environment, where it must
|
|
81
87
|
* register NO scheduled tasks. Mirrors the common `CI=true` convention used by
|
|
82
88
|
* GitHub Actions, GitLab CI, CircleCI, etc.
|
|
83
89
|
*/
|
|
84
90
|
export function isCiEnvironment(env = process.env) {
|
|
91
|
+
if (defaultTasksOverrides?.isCiEnvironment)
|
|
92
|
+
return defaultTasksOverrides.isCiEnvironment(env);
|
|
85
93
|
const ci = env.CI;
|
|
86
94
|
if (ci === undefined || ci === null)
|
|
87
95
|
return false;
|
|
@@ -95,6 +103,8 @@ export function isCiEnvironment(env = process.env) {
|
|
|
95
103
|
* Used as the default when setup is non-interactive (no TTY / --yes / CI).
|
|
96
104
|
*/
|
|
97
105
|
export function detectServerDefault() {
|
|
106
|
+
if (defaultTasksOverrides?.detectServerDefault)
|
|
107
|
+
return defaultTasksOverrides.detectServerDefault();
|
|
98
108
|
if (os.platform() !== "linux")
|
|
99
109
|
return false;
|
|
100
110
|
// A laptop exposes a battery under /sys/class/power_supply/BAT*. Absence of
|
|
@@ -121,6 +131,9 @@ export function detectServerDefault() {
|
|
|
121
131
|
* never re-disable a user-enabled task).
|
|
122
132
|
*/
|
|
123
133
|
export async function registerDefaultTasks(options = {}) {
|
|
134
|
+
if (defaultTasksOverrides?.registerDefaultTasks) {
|
|
135
|
+
return defaultTasksOverrides.registerDefaultTasks(options);
|
|
136
|
+
}
|
|
124
137
|
if (isCiEnvironment()) {
|
|
125
138
|
return { skipped: true, reason: "ci", created: [], existing: [], toggled: [] };
|
|
126
139
|
}
|
|
@@ -13,9 +13,8 @@
|
|
|
13
13
|
* with the family.
|
|
14
14
|
*/
|
|
15
15
|
import { defineCommand } from "citty";
|
|
16
|
-
import {
|
|
17
|
-
import { defineJsonCommand, output, runWithJsonErrors } from "../../cli/shared.js";
|
|
18
|
-
import { getHyphenatedArg } from "../../output/context.js";
|
|
16
|
+
import { parsePositiveIntFlag } from "../../cli/parse-args.js";
|
|
17
|
+
import { defineGroupCommand, defineJsonCommand, output, runWithJsonErrors } from "../../cli/shared.js";
|
|
19
18
|
import { detectServerDefault, registerDefaultTasks } from "./default-tasks.js";
|
|
20
19
|
import { akmTasksAdd, akmTasksDoctor, akmTasksHistory, akmTasksList, akmTasksRemove, akmTasksRun, akmTasksSetEnabled, akmTasksShow, akmTasksSync, parseTaskRef, } from "./tasks.js";
|
|
21
20
|
const tasksAddCommand = defineJsonCommand({
|
|
@@ -51,7 +50,7 @@ const tasksAddCommand = defineJsonCommand({
|
|
|
51
50
|
profile: args.profile,
|
|
52
51
|
params: args.params,
|
|
53
52
|
name: args.name,
|
|
54
|
-
when_to_use:
|
|
53
|
+
when_to_use: args["when-to-use"],
|
|
55
54
|
description: args.description,
|
|
56
55
|
tags: args.tags
|
|
57
56
|
? args.tags
|
|
@@ -176,35 +175,27 @@ const tasksDoctorCommand = defineJsonCommand({
|
|
|
176
175
|
output("tasks-doctor", result);
|
|
177
176
|
},
|
|
178
177
|
});
|
|
179
|
-
|
|
180
|
-
// (M10) so adding a subcommand can never silently desync from `hasSubcommand`.
|
|
181
|
-
const tasksSubCommands = {
|
|
182
|
-
add: tasksAddCommand,
|
|
183
|
-
init: tasksInitCommand,
|
|
184
|
-
list: tasksListCommand,
|
|
185
|
-
show: tasksShowCommand,
|
|
186
|
-
remove: tasksRemoveCommand,
|
|
187
|
-
enable: tasksEnableCommand,
|
|
188
|
-
disable: tasksDisableCommand,
|
|
189
|
-
run: tasksRunCommand,
|
|
190
|
-
history: tasksHistoryCommand,
|
|
191
|
-
sync: tasksSyncCommand,
|
|
192
|
-
doctor: tasksDoctorCommand,
|
|
193
|
-
};
|
|
194
|
-
const TASKS_SUBCOMMAND_SET = new Set(Object.keys(tasksSubCommands));
|
|
195
|
-
export const tasksCommand = defineCommand({
|
|
178
|
+
export const tasksCommand = defineGroupCommand({
|
|
196
179
|
meta: {
|
|
197
180
|
name: "tasks",
|
|
198
181
|
alias: "task",
|
|
199
182
|
description: "Schedule workflows or prompts via the OS-native scheduler (cron / launchd / schtasks)",
|
|
200
183
|
},
|
|
201
|
-
subCommands:
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
184
|
+
subCommands: {
|
|
185
|
+
add: tasksAddCommand,
|
|
186
|
+
init: tasksInitCommand,
|
|
187
|
+
list: tasksListCommand,
|
|
188
|
+
show: tasksShowCommand,
|
|
189
|
+
remove: tasksRemoveCommand,
|
|
190
|
+
enable: tasksEnableCommand,
|
|
191
|
+
disable: tasksDisableCommand,
|
|
192
|
+
run: tasksRunCommand,
|
|
193
|
+
history: tasksHistoryCommand,
|
|
194
|
+
sync: tasksSyncCommand,
|
|
195
|
+
doctor: tasksDoctorCommand,
|
|
196
|
+
},
|
|
197
|
+
async defaultRun() {
|
|
198
|
+
const result = await akmTasksList();
|
|
199
|
+
output("tasks-list", result);
|
|
209
200
|
},
|
|
210
201
|
});
|
|
@@ -16,11 +16,12 @@ import { isWithin, resolveStashDir } from "../../core/common.js";
|
|
|
16
16
|
import { loadConfig } from "../../core/config/config.js";
|
|
17
17
|
import { ConfigError, NotFoundError, UsageError } from "../../core/errors.js";
|
|
18
18
|
import { getTaskHistoryDir, getTaskLogDir } from "../../core/paths.js";
|
|
19
|
+
import { commitWriteTargetBoundary, deleteAssetFromSource, resolveWriteTarget, writeAssetToSource, } from "../../core/write-source.js";
|
|
19
20
|
import { listAgentProfileNames } from "../../integrations/agent/index.js";
|
|
20
21
|
import { resolveAssetPath } from "../../sources/resolve.js";
|
|
21
22
|
import { backendNameForPlatform, selectBackend } from "../../tasks/backends/index.js";
|
|
22
23
|
import { parseTaskDocument } from "../../tasks/parser.js";
|
|
23
|
-
import { resolveAkmInvocation } from "../../tasks/
|
|
24
|
+
import { resolveAkmInvocation } from "../../tasks/resolve-akm-bin.js";
|
|
24
25
|
import { exitCodeForStatus, readTaskHistory, runTask } from "../../tasks/runner.js";
|
|
25
26
|
import { parseSchedule, SCHEDULE_SUPPORTED_SUBSET_HINT, translateToCron } from "../../tasks/schedule.js";
|
|
26
27
|
import { validateTaskDocument } from "../../tasks/validator.js";
|
|
@@ -38,7 +39,8 @@ export async function akmTasksAdd(input) {
|
|
|
38
39
|
// Validate the schedule for the active backend before writing anything.
|
|
39
40
|
const backend = backendNameForPlatform();
|
|
40
41
|
parseSchedule(input.schedule, backend);
|
|
41
|
-
const
|
|
42
|
+
const target = resolveTaskWriteTarget();
|
|
43
|
+
const stashDir = target.source.path;
|
|
42
44
|
const typeRoot = path.join(stashDir, "tasks");
|
|
43
45
|
fs.mkdirSync(typeRoot, { recursive: true });
|
|
44
46
|
const assetPath = resolveAssetPathFromName("task", typeRoot, id);
|
|
@@ -64,7 +66,8 @@ export async function akmTasksAdd(input) {
|
|
|
64
66
|
});
|
|
65
67
|
const task = parseTaskDocument({ yaml, filePath: assetPath, id });
|
|
66
68
|
await validateTaskDocument(task, { backend, stashDir });
|
|
67
|
-
|
|
69
|
+
const ref = taskAssetRef(id);
|
|
70
|
+
await writeAssetToSource(target.source, target.config, ref, yaml);
|
|
68
71
|
// Install in the OS scheduler. If install fails after the file was written,
|
|
69
72
|
// delete the file so the on-disk state never claims a task is registered
|
|
70
73
|
// when it isn't.
|
|
@@ -74,13 +77,14 @@ export async function akmTasksAdd(input) {
|
|
|
74
77
|
}
|
|
75
78
|
catch (err) {
|
|
76
79
|
try {
|
|
77
|
-
|
|
80
|
+
await deleteAssetFromSource(target.source, target.config, ref);
|
|
78
81
|
}
|
|
79
82
|
catch {
|
|
80
83
|
/* ignore */
|
|
81
84
|
}
|
|
82
85
|
throw err;
|
|
83
86
|
}
|
|
87
|
+
commitWriteTargetBoundary(target, `Update task:${id}`);
|
|
84
88
|
return {
|
|
85
89
|
id,
|
|
86
90
|
ref: `task:${id}`,
|
|
@@ -192,30 +196,47 @@ export async function akmTasksShow(id) {
|
|
|
192
196
|
}
|
|
193
197
|
export async function akmTasksRemove(id) {
|
|
194
198
|
const normalised = normaliseTaskId(id);
|
|
195
|
-
const
|
|
199
|
+
const target = resolveTaskWriteTarget();
|
|
200
|
+
const stashDir = target.source.path;
|
|
196
201
|
const typeRoot = path.join(stashDir, "tasks");
|
|
197
202
|
if (fs.existsSync(typeRoot))
|
|
198
203
|
warnLegacyMdTaskFiles(typeRoot);
|
|
199
|
-
|
|
204
|
+
await resolveAssetPath(stashDir, "task", normalised);
|
|
205
|
+
const ref = taskAssetRef(normalised);
|
|
200
206
|
const sched = selectBackend();
|
|
207
|
+
let uninstallError;
|
|
208
|
+
let deleteError;
|
|
201
209
|
try {
|
|
202
210
|
await sched.uninstall(normalised);
|
|
203
211
|
}
|
|
204
|
-
|
|
205
|
-
|
|
212
|
+
catch (err) {
|
|
213
|
+
uninstallError = err;
|
|
214
|
+
}
|
|
215
|
+
try {
|
|
216
|
+
await deleteAssetFromSource(target.source, target.config, ref);
|
|
206
217
|
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
deleteError = err;
|
|
220
|
+
}
|
|
221
|
+
if (uninstallError !== undefined)
|
|
222
|
+
throw uninstallError;
|
|
223
|
+
if (deleteError !== undefined)
|
|
224
|
+
throw deleteError;
|
|
225
|
+
commitWriteTargetBoundary(target, `Remove task:${normalised}`);
|
|
207
226
|
return { id: normalised, removed: true, backend: sched.name };
|
|
208
227
|
}
|
|
209
228
|
export async function akmTasksSetEnabled(id, enabled) {
|
|
210
229
|
const normalised = normaliseTaskId(id);
|
|
211
|
-
const
|
|
230
|
+
const target = resolveTaskWriteTarget();
|
|
231
|
+
const stashDir = target.source.path;
|
|
212
232
|
const typeRoot = path.join(stashDir, "tasks");
|
|
213
233
|
if (fs.existsSync(typeRoot))
|
|
214
234
|
warnLegacyMdTaskFiles(typeRoot);
|
|
215
235
|
const filePath = await resolveAssetPath(stashDir, "task", normalised);
|
|
216
236
|
const yaml = fs.readFileSync(filePath, "utf8");
|
|
217
237
|
const updated = setEnabledInYaml(yaml, enabled);
|
|
218
|
-
|
|
238
|
+
const ref = taskAssetRef(normalised);
|
|
239
|
+
await writeAssetToSource(target.source, target.config, ref, updated);
|
|
219
240
|
const sched = selectBackend();
|
|
220
241
|
try {
|
|
221
242
|
// Reinstall from the (just-updated) definition rather than only toggling
|
|
@@ -229,9 +250,10 @@ export async function akmTasksSetEnabled(id, enabled) {
|
|
|
229
250
|
catch (err) {
|
|
230
251
|
// Roll the file back so the YAML source-of-truth and the OS
|
|
231
252
|
// scheduler don't diverge silently when the backend call fails.
|
|
232
|
-
|
|
253
|
+
await writeAssetToSource(target.source, target.config, ref, yaml);
|
|
233
254
|
throw err;
|
|
234
255
|
}
|
|
256
|
+
commitWriteTargetBoundary(target, `Update task:${normalised}`);
|
|
235
257
|
return { id: normalised, enabled, backend: sched.name };
|
|
236
258
|
}
|
|
237
259
|
export async function akmTasksRun(id) {
|
|
@@ -392,6 +414,12 @@ function normaliseTaskId(raw) {
|
|
|
392
414
|
}
|
|
393
415
|
return id;
|
|
394
416
|
}
|
|
417
|
+
function taskAssetRef(id) {
|
|
418
|
+
return { type: "task", name: id };
|
|
419
|
+
}
|
|
420
|
+
function resolveTaskWriteTarget() {
|
|
421
|
+
return resolveWriteTarget(loadConfig());
|
|
422
|
+
}
|
|
395
423
|
function renderTaskYaml(input) {
|
|
396
424
|
const obj = { schedule: input.schedule };
|
|
397
425
|
if (input.workflow) {
|
|
@@ -11,12 +11,11 @@
|
|
|
11
11
|
* `process.exit(1)` after the wrapper when findings exist.
|
|
12
12
|
*/
|
|
13
13
|
import { defineCommand } from "citty";
|
|
14
|
-
import { getStringArg,
|
|
15
|
-
import { defineJsonCommand, output, runWithJsonErrors } from "../cli/shared.js";
|
|
16
|
-
import {
|
|
14
|
+
import { getStringArg, parsePositiveIntFlag } from "../cli/parse-args.js";
|
|
15
|
+
import { defineGroupCommand, defineJsonCommand, output, runWithJsonErrors } from "../cli/shared.js";
|
|
16
|
+
import { resolveStashDir } from "../core/common.js";
|
|
17
17
|
import { loadConfig, resolveConfiguredSources } from "../core/config/config.js";
|
|
18
18
|
import { ConfigError, UsageError } from "../core/errors.js";
|
|
19
|
-
import { getHyphenatedArg, getHyphenatedBoolean } from "../output/context.js";
|
|
20
19
|
import { akmAgentDispatch } from "./agent/agent-dispatch.js";
|
|
21
20
|
import { readKnowledgeInput } from "./read/knowledge.js";
|
|
22
21
|
import { buildWebsiteOptions } from "./sources/add-cli.js";
|
|
@@ -108,7 +107,7 @@ const wikiRemoveCommand = defineJsonCommand({
|
|
|
108
107
|
process.stderr.write("Aborted.\n");
|
|
109
108
|
return;
|
|
110
109
|
}
|
|
111
|
-
const withSources =
|
|
110
|
+
const withSources = args["with-sources"];
|
|
112
111
|
const { removeWiki } = await import("../wiki/wiki.js");
|
|
113
112
|
const { akmIndex } = await import("../indexer/indexer.js");
|
|
114
113
|
const stashDir = resolveStashDir();
|
|
@@ -168,13 +167,6 @@ const wikiStashCommand = defineJsonCommand({
|
|
|
168
167
|
},
|
|
169
168
|
async run({ args }) {
|
|
170
169
|
const { stashRaw } = await import("../wiki/wiki.js");
|
|
171
|
-
const { content, preferredName } = await (async () => {
|
|
172
|
-
if (!isHttpUrl(args.source))
|
|
173
|
-
return readKnowledgeInput(args.source);
|
|
174
|
-
const { fetchWebsiteMarkdownSnapshot } = await import("../sources/website-ingest.js");
|
|
175
|
-
const snapshot = await fetchWebsiteMarkdownSnapshot(args.source);
|
|
176
|
-
return { content: snapshot.content, preferredName: args.as ?? snapshot.preferredName };
|
|
177
|
-
})();
|
|
178
170
|
let stashDir;
|
|
179
171
|
if (args.target) {
|
|
180
172
|
// Resolve the named source to its filesystem path.
|
|
@@ -193,6 +185,7 @@ const wikiStashCommand = defineJsonCommand({
|
|
|
193
185
|
else {
|
|
194
186
|
stashDir = resolveStashDir();
|
|
195
187
|
}
|
|
188
|
+
const { content, preferredName } = await readKnowledgeInput(args.source, { stashDir });
|
|
196
189
|
const result = stashRaw({
|
|
197
190
|
stashDir,
|
|
198
191
|
wikiName: args.name,
|
|
@@ -250,7 +243,7 @@ const wikiIngestCommand = defineJsonCommand({
|
|
|
250
243
|
if (!profileName) {
|
|
251
244
|
throw new UsageError("akm wiki ingest requires an agent profile. Pass --profile <name> or set defaults.agent in config.", "MISSING_REQUIRED_ARGUMENT", "Available profiles are listed under profiles.agent in your config. Run `akm config get profiles.agent` to inspect.");
|
|
252
245
|
}
|
|
253
|
-
const timeoutMs = parsePositiveIntFlag(
|
|
246
|
+
const timeoutMs = parsePositiveIntFlag(args["timeout-ms"], "--timeout-ms");
|
|
254
247
|
const model = getStringArg(args, "model");
|
|
255
248
|
const { getDefaultLlmConfig } = await import("../core/config/config.js");
|
|
256
249
|
const dispatchResult = await akmAgentDispatch({
|
|
@@ -274,34 +267,26 @@ const wikiIngestCommand = defineJsonCommand({
|
|
|
274
267
|
});
|
|
275
268
|
},
|
|
276
269
|
});
|
|
277
|
-
|
|
278
|
-
// (M10) so adding a subcommand can never silently desync from `hasSubcommand`.
|
|
279
|
-
const wikiSubCommands = {
|
|
280
|
-
create: wikiCreateCommand,
|
|
281
|
-
register: wikiRegisterCommand,
|
|
282
|
-
list: wikiListCommand,
|
|
283
|
-
show: wikiShowCommand,
|
|
284
|
-
remove: wikiRemoveCommand,
|
|
285
|
-
pages: wikiPagesCommand,
|
|
286
|
-
search: wikiSearchCommand,
|
|
287
|
-
stash: wikiStashCommand,
|
|
288
|
-
lint: wikiLintCommand,
|
|
289
|
-
ingest: wikiIngestCommand,
|
|
290
|
-
};
|
|
291
|
-
const WIKI_SUBCOMMAND_SET = new Set(Object.keys(wikiSubCommands));
|
|
292
|
-
export const wikiCommand = defineCommand({
|
|
270
|
+
export const wikiCommand = defineGroupCommand({
|
|
293
271
|
meta: {
|
|
294
272
|
name: "wiki",
|
|
295
273
|
description: "Manage multiple markdown wikis (Karpathy-style). akm surfaces (lifecycle, raw/, lint, index); the agent writes pages.",
|
|
296
274
|
},
|
|
297
|
-
subCommands:
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
275
|
+
subCommands: {
|
|
276
|
+
create: wikiCreateCommand,
|
|
277
|
+
register: wikiRegisterCommand,
|
|
278
|
+
list: wikiListCommand,
|
|
279
|
+
show: wikiShowCommand,
|
|
280
|
+
remove: wikiRemoveCommand,
|
|
281
|
+
pages: wikiPagesCommand,
|
|
282
|
+
search: wikiSearchCommand,
|
|
283
|
+
stash: wikiStashCommand,
|
|
284
|
+
lint: wikiLintCommand,
|
|
285
|
+
ingest: wikiIngestCommand,
|
|
286
|
+
},
|
|
287
|
+
async defaultRun() {
|
|
288
|
+
// Default action: list wikis
|
|
289
|
+
const { listWikis } = await import("../wiki/wiki.js");
|
|
290
|
+
output("wiki-list", { wikis: listWikis(resolveStashDir()) });
|
|
306
291
|
},
|
|
307
292
|
});
|
|
@@ -24,7 +24,7 @@ import { resolveSourcesForOrigin } from "../registry/origin-resolve.js";
|
|
|
24
24
|
import { resolveAssetPath } from "../sources/resolve.js";
|
|
25
25
|
import { createWorkflowAsset, formatWorkflowErrors, getWorkflowTemplate, validateWorkflowSource, } from "../workflows/authoring/authoring.js";
|
|
26
26
|
import { hasWorkflowSubcommand, parseWorkflowJsonObject, parseWorkflowStepState, WORKFLOW_STEP_STATES, } from "../workflows/cli.js";
|
|
27
|
-
import { completeWorkflowStep, getNextWorkflowStep, getWorkflowStatus, listWorkflowRuns, resumeWorkflowRun, startWorkflowRun, } from "../workflows/runtime/runs.js";
|
|
27
|
+
import { abandonWorkflowRun, completeWorkflowStep, getNextWorkflowStep, getWorkflowStatus, listWorkflowRuns, resumeWorkflowRun, startWorkflowRun, } from "../workflows/runtime/runs.js";
|
|
28
28
|
const workflowStartCommand = defineJsonCommand({
|
|
29
29
|
meta: {
|
|
30
30
|
name: "start",
|
|
@@ -290,6 +290,19 @@ async function resolveWorkflowFilePath(target) {
|
|
|
290
290
|
}
|
|
291
291
|
throw new UsageError(`Workflow not found for ref: workflow:${parsed.name}`);
|
|
292
292
|
}
|
|
293
|
+
const workflowAbandonCommand = defineJsonCommand({
|
|
294
|
+
meta: {
|
|
295
|
+
name: "abandon",
|
|
296
|
+
description: "Give up on a workflow run: mark it failed so it stops counting as active (resume can reopen it)",
|
|
297
|
+
},
|
|
298
|
+
args: {
|
|
299
|
+
runId: { type: "positional", description: "Workflow run id", required: true },
|
|
300
|
+
},
|
|
301
|
+
async run({ args }) {
|
|
302
|
+
const result = await abandonWorkflowRun(args.runId);
|
|
303
|
+
output("workflow-abandon", result);
|
|
304
|
+
},
|
|
305
|
+
});
|
|
293
306
|
const workflowResumeCommand = defineJsonCommand({
|
|
294
307
|
meta: {
|
|
295
308
|
name: "resume",
|
|
@@ -317,6 +330,7 @@ export const workflowCommand = defineCommand({
|
|
|
317
330
|
create: workflowCreateCommand,
|
|
318
331
|
template: workflowTemplateCommand,
|
|
319
332
|
resume: workflowResumeCommand,
|
|
333
|
+
abandon: workflowAbandonCommand,
|
|
320
334
|
validate: workflowValidateCommand,
|
|
321
335
|
},
|
|
322
336
|
run({ args }) {
|