akm-cli 0.8.1 → 0.9.0-beta.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 +258 -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/stash-skeleton/README.md +76 -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/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 +51 -14
- package/dist/cli-node.mjs +26 -0
- package/dist/cli.js +171 -3857
- 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 +240 -3
- package/dist/commands/config-edit.js +344 -0
- 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.js +101 -249
- package/dist/commands/{consolidate.js → improve/consolidate.js} +52 -40
- 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} +185 -26
- package/dist/commands/{improve-auto-accept.js → improve/improve-auto-accept.js} +4 -4
- package/dist/commands/{improve-cli.js → improve/improve-cli.js} +45 -23
- package/dist/commands/{improve-profiles.js → improve/improve-profiles.js} +13 -7
- package/dist/commands/{improve-result-file.js → improve/improve-result-file.js} +10 -5
- package/dist/commands/{improve.js → improve/improve.js} +536 -248
- 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/{reflect.js → improve/reflect.js} +33 -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 → proposal/drain-policies.js} +3 -3
- package/dist/commands/{proposal-drain.js → proposal/drain.js} +15 -10
- package/dist/commands/proposal/proposal-cli.js +478 -0
- package/dist/commands/{proposal.js → proposal/proposal.js} +5 -5
- 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 +13 -7
- 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} +77 -44
- package/dist/commands/registry-cli.js +8 -8
- package/dist/commands/remember.js +8 -8
- 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} +10 -5
- 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/sources/stash-skeleton.js +79 -0
- 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/asset/stash-meta.js +110 -0
- 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} +45 -1
- 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/paths.js +2 -2
- package/dist/{setup/ripgrep-install.js → core/ripgrep/install.js} +2 -2
- package/dist/{setup/ripgrep-resolve.js → core/ripgrep/resolve.js} +2 -2
- package/dist/core/state-db.js +88 -46
- 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} +126 -116
- 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} +92 -23
- 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} +16 -1
- 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 +131 -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/output/context.js +6 -44
- 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 +2 -4
- 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 +54 -39
- 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 +1594 -673
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +240 -166
- package/dist/setup/detect.js +338 -9
- package/dist/setup/harness-config-import.js +56 -0
- package/dist/setup/registry-stash-loader.js +99 -0
- package/dist/setup/setup.js +664 -96
- 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 +28 -15
- 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 +50 -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 +16 -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,6 +2,38 @@
|
|
|
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 { spawnSync } from "node:child_process";
|
|
5
|
+
import fs from "node:fs";
|
|
6
|
+
/**
|
|
7
|
+
* Default exec strategy: run commands synchronously via {@link spawnCommand}.
|
|
8
|
+
*
|
|
9
|
+
* This is the shared default for every task backend's `exec` seam. Backends
|
|
10
|
+
* that need extra fields (e.g. launchd's `uid()`) spread this and add them.
|
|
11
|
+
*/
|
|
12
|
+
export function nodeExec() {
|
|
13
|
+
return {
|
|
14
|
+
run(args) {
|
|
15
|
+
return spawnCommand(args);
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Default filesystem strategy for the shared subset of the backend `fs` seam
|
|
21
|
+
* (`writeFile` + `ensureDir`), backed by `node:fs`.
|
|
22
|
+
*
|
|
23
|
+
* Backends spread this and add their own members. Note `removeFile` is NOT
|
|
24
|
+
* shared here: the launchd and schtasks defaults differ observably (schtasks
|
|
25
|
+
* swallows errors; launchd does not), so each keeps its own.
|
|
26
|
+
*/
|
|
27
|
+
export function nodeFs() {
|
|
28
|
+
return {
|
|
29
|
+
writeFile(file, content) {
|
|
30
|
+
fs.writeFileSync(file, content, { encoding: "utf8" });
|
|
31
|
+
},
|
|
32
|
+
ensureDir(dir) {
|
|
33
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
5
37
|
/**
|
|
6
38
|
* Run a command synchronously, normalizing null results to safe defaults.
|
|
7
39
|
* args[0] is the binary; args[1..] are its arguments.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
import { CRON_BACKEND } from "./cron";
|
|
5
|
-
import { LAUNCHD_BACKEND } from "./launchd";
|
|
6
|
-
import { SCHTASKS_BACKEND } from "./schtasks";
|
|
4
|
+
import { CRON_BACKEND } from "./cron.js";
|
|
5
|
+
import { LAUNCHD_BACKEND } from "./launchd.js";
|
|
6
|
+
import { SCHTASKS_BACKEND } from "./schtasks.js";
|
|
7
7
|
export function selectBackend(options = {}) {
|
|
8
8
|
const platform = options.platform ?? process.platform;
|
|
9
9
|
switch (platform) {
|
|
@@ -25,11 +25,11 @@ import fs from "node:fs";
|
|
|
25
25
|
import os from "node:os";
|
|
26
26
|
import path from "node:path";
|
|
27
27
|
import launchdTemplate from "../../assets/backends/launchd-template.xml" with { type: "text" };
|
|
28
|
-
import { ConfigError } from "../../core/errors";
|
|
29
|
-
import { getTaskLogDir } from "../../core/paths";
|
|
30
|
-
import { resolveAkmInvocation } from "../resolveAkmBin";
|
|
31
|
-
import { parseSchedule, translateToLaunchd } from "../schedule";
|
|
32
|
-
import { escapeXml,
|
|
28
|
+
import { ConfigError } from "../../core/errors.js";
|
|
29
|
+
import { getTaskLogDir } from "../../core/paths.js";
|
|
30
|
+
import { resolveAkmInvocation } from "../resolveAkmBin.js";
|
|
31
|
+
import { parseSchedule, translateToLaunchd } from "../schedule.js";
|
|
32
|
+
import { escapeXml, nodeExec, nodeFs } from "./exec-utils.js";
|
|
33
33
|
export const LAUNCHD_LABEL_PREFIX = "com.akm.task.";
|
|
34
34
|
export function LAUNCHD_BACKEND(options = {}) {
|
|
35
35
|
const exec = options.exec ?? defaultLaunchdExec();
|
|
@@ -152,9 +152,7 @@ function defaultAgentsDir() {
|
|
|
152
152
|
}
|
|
153
153
|
function defaultLaunchdExec() {
|
|
154
154
|
return {
|
|
155
|
-
|
|
156
|
-
return spawnCommand(args);
|
|
157
|
-
},
|
|
155
|
+
...nodeExec(),
|
|
158
156
|
uid() {
|
|
159
157
|
const fn = process.getuid;
|
|
160
158
|
return typeof fn === "function" ? fn.call(process) : 0;
|
|
@@ -163,15 +161,10 @@ function defaultLaunchdExec() {
|
|
|
163
161
|
}
|
|
164
162
|
function defaultLaunchdFs() {
|
|
165
163
|
return {
|
|
166
|
-
|
|
167
|
-
fs.writeFileSync(file, content, { encoding: "utf8" });
|
|
168
|
-
},
|
|
164
|
+
...nodeFs(),
|
|
169
165
|
removeFile(file) {
|
|
170
166
|
fs.rmSync(file, { force: true });
|
|
171
167
|
},
|
|
172
|
-
ensureDir(dir) {
|
|
173
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
174
|
-
},
|
|
175
168
|
list(dir) {
|
|
176
169
|
try {
|
|
177
170
|
return fs.readdirSync(dir);
|
|
@@ -33,11 +33,11 @@ import fs from "node:fs";
|
|
|
33
33
|
import os from "node:os";
|
|
34
34
|
import path from "node:path";
|
|
35
35
|
import schtasksTemplate from "../../assets/backends/schtasks-template.xml" with { type: "text" };
|
|
36
|
-
import { ConfigError } from "../../core/errors";
|
|
37
|
-
import { getTaskLogDir } from "../../core/paths";
|
|
38
|
-
import { resolveAkmInvocation } from "../resolveAkmBin";
|
|
39
|
-
import { parseSchedule, translateToSchtasks } from "../schedule";
|
|
40
|
-
import { escapeXml,
|
|
36
|
+
import { ConfigError } from "../../core/errors.js";
|
|
37
|
+
import { getTaskLogDir } from "../../core/paths.js";
|
|
38
|
+
import { resolveAkmInvocation } from "../resolveAkmBin.js";
|
|
39
|
+
import { parseSchedule, translateToSchtasks } from "../schedule.js";
|
|
40
|
+
import { escapeXml, nodeExec, nodeFs } from "./exec-utils.js";
|
|
41
41
|
export const DEFAULT_FOLDER_PREFIX = "\\akm\\";
|
|
42
42
|
export function SCHTASKS_BACKEND(options = {}) {
|
|
43
43
|
const exec = options.exec ?? defaultSchtasksExec();
|
|
@@ -186,17 +186,11 @@ function quoteArg(s) {
|
|
|
186
186
|
return `"${s.replace(/"/g, '\\"')}"`;
|
|
187
187
|
}
|
|
188
188
|
function defaultSchtasksExec() {
|
|
189
|
-
return
|
|
190
|
-
run(args) {
|
|
191
|
-
return spawnCommand(args);
|
|
192
|
-
},
|
|
193
|
-
};
|
|
189
|
+
return nodeExec();
|
|
194
190
|
}
|
|
195
191
|
function defaultSchtasksFs() {
|
|
196
192
|
return {
|
|
197
|
-
|
|
198
|
-
fs.writeFileSync(file, content, { encoding: "utf8" });
|
|
199
|
-
},
|
|
193
|
+
...nodeFs(),
|
|
200
194
|
removeFile(file) {
|
|
201
195
|
try {
|
|
202
196
|
fs.rmSync(file, { force: true });
|
|
@@ -205,9 +199,6 @@ function defaultSchtasksFs() {
|
|
|
205
199
|
/* ignore */
|
|
206
200
|
}
|
|
207
201
|
},
|
|
208
|
-
ensureDir(dir) {
|
|
209
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
210
|
-
},
|
|
211
202
|
tmpdir() {
|
|
212
203
|
return os.tmpdir();
|
|
213
204
|
},
|
|
@@ -0,0 +1,71 @@
|
|
|
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
|
+
/**
|
|
5
|
+
* Embedded core task templates.
|
|
6
|
+
*
|
|
7
|
+
* A curated set of read-only YAML task templates ships inside the akm binary
|
|
8
|
+
* under `src/assets/tasks/core/`. They are resolved at runtime via
|
|
9
|
+
* `import.meta.dir` (mirroring `SKELETON_DIR` in
|
|
10
|
+
* src/commands/stash-skeleton.ts) and are NOT written to any stash at
|
|
11
|
+
* install/init time — the `akm setup` wizard copies a template into the
|
|
12
|
+
* primary stash only when the user opts in (copy-on-enable).
|
|
13
|
+
*
|
|
14
|
+
* Each entry exposes the parsed `command`, `schedule`, and `description`
|
|
15
|
+
* alongside the raw `yaml`, so the wizard can both render a choice and write
|
|
16
|
+
* the file verbatim (with an optional schedule edit applied).
|
|
17
|
+
*/
|
|
18
|
+
import fs from "node:fs";
|
|
19
|
+
import path from "node:path";
|
|
20
|
+
import { parse as yamlParse } from "yaml";
|
|
21
|
+
import { getDirname } from "../runtime.js";
|
|
22
|
+
/** Directory holding the bundled core task templates. */
|
|
23
|
+
const CORE_TASKS_DIR = path.join(getDirname(import.meta.url), "../assets/tasks/core");
|
|
24
|
+
/**
|
|
25
|
+
* Enumerate the embedded core task templates from the bundled assets
|
|
26
|
+
* directory. Sorted by id for deterministic ordering. Returns an empty array
|
|
27
|
+
* if the directory is missing (defensive — a build without assets should not
|
|
28
|
+
* crash the wizard).
|
|
29
|
+
*/
|
|
30
|
+
export function listEmbeddedTasks() {
|
|
31
|
+
let entries;
|
|
32
|
+
try {
|
|
33
|
+
entries = fs.readdirSync(CORE_TASKS_DIR);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
const tasks = [];
|
|
39
|
+
for (const entry of entries.sort()) {
|
|
40
|
+
if (!entry.endsWith(".yml"))
|
|
41
|
+
continue;
|
|
42
|
+
const id = entry.slice(0, -4);
|
|
43
|
+
const filePath = path.join(CORE_TASKS_DIR, entry);
|
|
44
|
+
let yaml;
|
|
45
|
+
try {
|
|
46
|
+
yaml = fs.readFileSync(filePath, "utf8");
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
let doc;
|
|
52
|
+
try {
|
|
53
|
+
doc = yamlParse(yaml) ?? {};
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const command = typeof doc.command === "string" ? doc.command : "";
|
|
59
|
+
const schedule = typeof doc.schedule === "string" ? doc.schedule : "";
|
|
60
|
+
const description = typeof doc.description === "string" ? doc.description : "";
|
|
61
|
+
tasks.push({
|
|
62
|
+
id,
|
|
63
|
+
label: `core/${id}`,
|
|
64
|
+
command,
|
|
65
|
+
schedule,
|
|
66
|
+
description,
|
|
67
|
+
yaml,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return tasks;
|
|
71
|
+
}
|
package/dist/tasks/parser.js
CHANGED
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
*/
|
|
36
36
|
import path from "node:path";
|
|
37
37
|
import { parse as parseYaml } from "yaml";
|
|
38
|
-
import { UsageError } from "../core/errors";
|
|
39
|
-
import { TASK_SCHEMA_VERSION } from "./schema";
|
|
38
|
+
import { UsageError } from "../core/errors.js";
|
|
39
|
+
import { TASK_SCHEMA_VERSION } from "./schema.js";
|
|
40
40
|
export function parseTaskDocument(input) {
|
|
41
41
|
const { yaml, filePath, id } = input;
|
|
42
42
|
let data;
|
|
@@ -24,7 +24,7 @@ import { spawnSync } from "node:child_process";
|
|
|
24
24
|
import fs from "node:fs";
|
|
25
25
|
import path from "node:path";
|
|
26
26
|
import { fileURLToPath } from "node:url";
|
|
27
|
-
import { ConfigError } from "../core/errors";
|
|
27
|
+
import { ConfigError } from "../core/errors.js";
|
|
28
28
|
export function resolveAkmInvocation(options = {}) {
|
|
29
29
|
const env = options.env ?? process.env;
|
|
30
30
|
const override = env.AKM_BIN?.trim();
|
package/dist/tasks/runner.js
CHANGED
|
@@ -24,19 +24,21 @@
|
|
|
24
24
|
*/
|
|
25
25
|
import fs from "node:fs";
|
|
26
26
|
import path from "node:path";
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
27
|
+
import { assertNever } from "../core/assert.js";
|
|
28
|
+
import { parseAssetRef } from "../core/asset/asset-ref.js";
|
|
29
|
+
import { resolveStashDir } from "../core/common.js";
|
|
30
|
+
import { loadConfig } from "../core/config/config.js";
|
|
31
|
+
import { NotFoundError, rethrowIfTestIsolationError } from "../core/errors.js";
|
|
32
|
+
import { getTaskLogDir } from "../core/paths.js";
|
|
33
|
+
import { getTaskHistory, openStateDatabase, queryTaskHistory, upsertTaskHistory } from "../core/state-db.js";
|
|
34
|
+
import { error } from "../core/warn.js";
|
|
35
|
+
import { requireAgentProfile, runAgent } from "../integrations/agent/index.js";
|
|
36
|
+
import { resolveProcessAgentProfile } from "../integrations/agent/config.js";
|
|
37
|
+
import { resolveRunner } from "../integrations/agent/runner.js";
|
|
38
|
+
import { spawn } from "../runtime.js";
|
|
39
|
+
import { resolveAssetPath } from "../sources/resolve.js";
|
|
40
|
+
import { startWorkflowRun } from "../workflows/runtime/runs.js";
|
|
41
|
+
import { parseTaskDocument } from "./parser.js";
|
|
40
42
|
export async function runTask(id, options = {}) {
|
|
41
43
|
const stashDir = options.stashDir ?? resolveStashDir();
|
|
42
44
|
const runAgentImpl = options.runAgentImpl ?? runAgent;
|
|
@@ -111,7 +113,7 @@ async function runCommandTask(input) {
|
|
|
111
113
|
let stderr = "";
|
|
112
114
|
let exitCode = null;
|
|
113
115
|
try {
|
|
114
|
-
const proc =
|
|
116
|
+
const proc = spawn(cmd, {
|
|
115
117
|
stdin: "ignore",
|
|
116
118
|
stdout: "pipe",
|
|
117
119
|
stderr: "pipe",
|
|
@@ -222,8 +224,19 @@ async function runWorkflowTask(input) {
|
|
|
222
224
|
* returns (multi-step workflows pause for user input); recording them as
|
|
223
225
|
* "completed" would be misleading. We preserve "active" as a first-class
|
|
224
226
|
* task status with exit code 0 — the OS scheduler treats it as success.
|
|
227
|
+
*
|
|
228
|
+
* The parameter is typed as the runtime's `WorkflowRunStatus` union (plus the
|
|
229
|
+
* `undefined` that `detail?.run.status` can produce when no detail is present).
|
|
230
|
+
* Every union member is handled explicitly and the `default` arm calls
|
|
231
|
+
* `assertNever`, so adding a new `WorkflowRunStatus` variant without mapping it
|
|
232
|
+
* here is a *compile* error rather than silently collapsing to "completed".
|
|
233
|
+
* The previous silent `default: "completed"` is preserved only for the
|
|
234
|
+
* `undefined` (no-detail) case, which is handled up front.
|
|
225
235
|
*/
|
|
226
236
|
function mapWorkflowStatus(status) {
|
|
237
|
+
// No run detail → treat as completed (unchanged from the prior silent default).
|
|
238
|
+
if (status === undefined)
|
|
239
|
+
return "completed";
|
|
227
240
|
switch (status) {
|
|
228
241
|
case "completed":
|
|
229
242
|
case "blocked":
|
|
@@ -231,7 +244,7 @@ function mapWorkflowStatus(status) {
|
|
|
231
244
|
case "active":
|
|
232
245
|
return status;
|
|
233
246
|
default:
|
|
234
|
-
return "
|
|
247
|
+
return assertNever(status, "mapWorkflowStatus");
|
|
235
248
|
}
|
|
236
249
|
}
|
|
237
250
|
function renderWorkflowLog(input) {
|
package/dist/tasks/schedule.js
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* Linux may fail to translate when copied to macOS/Windows. `tasks sync`
|
|
27
27
|
* re-validates against the local backend and surfaces any incompatibility.
|
|
28
28
|
*/
|
|
29
|
-
import { UsageError } from "../core/errors";
|
|
29
|
+
import { UsageError } from "../core/errors.js";
|
|
30
30
|
const ALIAS_TO_CRON = {
|
|
31
31
|
"@hourly": "0 * * * *",
|
|
32
32
|
"@daily": "0 0 * * *",
|
package/dist/tasks/validator.js
CHANGED
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import fs from "node:fs";
|
|
18
18
|
import path from "node:path";
|
|
19
|
-
import { parseAssetRef } from "../core/asset-ref";
|
|
20
|
-
import { resolveStashDir } from "../core/common";
|
|
21
|
-
import { loadConfig } from "../core/config";
|
|
22
|
-
import { NotFoundError } from "../core/errors";
|
|
23
|
-
import { requireAgentProfile } from "../integrations/agent";
|
|
24
|
-
import { resolveAssetPath } from "../sources/resolve";
|
|
25
|
-
import { parseSchedule } from "./schedule";
|
|
19
|
+
import { parseAssetRef } from "../core/asset/asset-ref.js";
|
|
20
|
+
import { resolveStashDir } from "../core/common.js";
|
|
21
|
+
import { loadConfig } from "../core/config/config.js";
|
|
22
|
+
import { NotFoundError } from "../core/errors.js";
|
|
23
|
+
import { requireAgentProfile } from "../integrations/agent/index.js";
|
|
24
|
+
import { resolveAssetPath } from "../sources/resolve.js";
|
|
25
|
+
import { parseSchedule } from "./schedule.js";
|
|
26
26
|
export async function validateTaskDocument(task, options) {
|
|
27
27
|
// Schedule must parse and translate.
|
|
28
28
|
parseSchedule(task.schedule, options.backend);
|
|
@@ -0,0 +1,51 @@
|
|
|
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
|
+
|
|
5
|
+
// Node ESM loader hook: support `import x from "./foo.md" with { type: "text" }`.
|
|
6
|
+
//
|
|
7
|
+
// Bun has a built-in text loader; Node does not (it only understands
|
|
8
|
+
// `type: "json"`). akm embeds prompt/template assets via `with { type: "text" }`
|
|
9
|
+
// imports that are statically hoisted into the module graph, so Node fails at
|
|
10
|
+
// load time with ERR_UNKNOWN_FILE_EXTENSION / unsupported import attribute
|
|
11
|
+
// before any command runs. This hook makes Node treat those imports as a module
|
|
12
|
+
// whose default export is the file's UTF-8 contents — byte-identical to Bun's
|
|
13
|
+
// text loader. It is ONLY registered on the Node entry path (see cli-node.mjs);
|
|
14
|
+
// Bun never loads it, so the Bun runtime is untouched.
|
|
15
|
+
|
|
16
|
+
import { readFile } from "node:fs/promises";
|
|
17
|
+
import { fileURLToPath } from "node:url";
|
|
18
|
+
|
|
19
|
+
const TEXT_EXTENSIONS = new Set([".md", ".xml", ".txt", ".sql"]);
|
|
20
|
+
|
|
21
|
+
function isTextImport(url, importAttributes) {
|
|
22
|
+
if (importAttributes && importAttributes.type === "text") return true;
|
|
23
|
+
const i = url.lastIndexOf(".");
|
|
24
|
+
if (i === -1) return false;
|
|
25
|
+
return TEXT_EXTENSIONS.has(url.slice(i).toLowerCase().split("?")[0]);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function load(url, context, nextLoad) {
|
|
29
|
+
if (url.startsWith("file:") && isTextImport(url, context.importAttributes)) {
|
|
30
|
+
const text = await readFile(fileURLToPath(url), "utf8");
|
|
31
|
+
return {
|
|
32
|
+
format: "module",
|
|
33
|
+
shortCircuit: true,
|
|
34
|
+
source: `export default ${JSON.stringify(text)};`,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return nextLoad(url, context);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Node validates import attributes against the resolved format and rejects an
|
|
41
|
+
// unknown `type: "text"` during resolution. Strip the attribute here so our
|
|
42
|
+
// `load` hook (above) can take over; the assertion has already served its
|
|
43
|
+
// purpose of routing to text handling.
|
|
44
|
+
export async function resolve(specifier, context, nextResolve) {
|
|
45
|
+
const result = await nextResolve(specifier, context);
|
|
46
|
+
if (result.importAttributes && result.importAttributes.type === "text") {
|
|
47
|
+
const { type, ...rest } = result.importAttributes;
|
|
48
|
+
return { ...result, importAttributes: rest };
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
51
|
+
}
|
package/dist/version.js
CHANGED
|
@@ -3,13 +3,14 @@
|
|
|
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
|
// Version: prefer compile-time define, then package.json, then fallback
|
|
7
8
|
export const pkgVersion = (() => {
|
|
8
9
|
// Injected at compile time via `bun build --define`
|
|
9
10
|
if (typeof AKM_VERSION !== "undefined")
|
|
10
11
|
return AKM_VERSION;
|
|
11
12
|
try {
|
|
12
|
-
const pkgPath = path.resolve(import.meta.
|
|
13
|
+
const pkgPath = path.resolve(getDirname(import.meta.url), "../package.json");
|
|
13
14
|
if (fs.existsSync(pkgPath)) {
|
|
14
15
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
15
16
|
if (typeof pkg.version === "string")
|
package/dist/wiki/wiki.js
CHANGED
|
@@ -45,13 +45,13 @@ import fs from "node:fs";
|
|
|
45
45
|
import path from "node:path";
|
|
46
46
|
import { parse as yamlParse } from "yaml";
|
|
47
47
|
import ingestWorkflowTemplate from "../assets/wiki/ingest-workflow-template.md" with { type: "text" };
|
|
48
|
-
import { akmSearch } from "../commands/search";
|
|
49
|
-
import {
|
|
50
|
-
import {
|
|
51
|
-
import {
|
|
52
|
-
import {
|
|
53
|
-
import { resolveSourceEntries } from "../indexer/search-source";
|
|
54
|
-
import { buildIndexMd, buildLogMd, buildSchemaMd } from "./wiki-templates";
|
|
48
|
+
import { akmSearch } from "../commands/read/search.js";
|
|
49
|
+
import { parseFrontmatter, parseFrontmatterBlock } from "../core/asset/frontmatter.js";
|
|
50
|
+
import { isWithin, todayIso } from "../core/common.js";
|
|
51
|
+
import { getSources, loadUserConfig, saveConfig } from "../core/config/config.js";
|
|
52
|
+
import { NotFoundError, UsageError } from "../core/errors.js";
|
|
53
|
+
import { resolveSourceEntries } from "../indexer/search/search-source.js";
|
|
54
|
+
import { buildIndexMd, buildLogMd, buildSchemaMd } from "./wiki-templates.js";
|
|
55
55
|
// ── Constants ───────────────────────────────────────────────────────────────
|
|
56
56
|
export const WIKIS_SUBDIR = "wikis";
|
|
57
57
|
export const SCHEMA_MD = "schema.md";
|
|
@@ -3,12 +3,12 @@
|
|
|
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 workflowTemplate from "
|
|
7
|
-
import { resolveAssetPathFromName } from "
|
|
8
|
-
import { isWithin, resolveStashDir } from "
|
|
9
|
-
import { UsageError } from "
|
|
10
|
-
import { warn } from "
|
|
11
|
-
import { parseWorkflow } from "
|
|
6
|
+
import workflowTemplate from "../../assets/workflows/workflow-template.md" with { type: "text" };
|
|
7
|
+
import { resolveAssetPathFromName } from "../../core/asset/asset-spec.js";
|
|
8
|
+
import { isWithin, resolveStashDir } from "../../core/common.js";
|
|
9
|
+
import { UsageError } from "../../core/errors.js";
|
|
10
|
+
import { warn } from "../../core/warn.js";
|
|
11
|
+
import { parseWorkflow } from "../parser.js";
|
|
12
12
|
const DEFAULT_WORKFLOW_TEMPLATE = renderWorkflowTemplate({
|
|
13
13
|
title: "Example Workflow",
|
|
14
14
|
firstStepTitle: "First Step",
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
5
|
import fs from "node:fs";
|
|
6
6
|
import path from "node:path";
|
|
7
|
-
import { isWithin, resolveStashDir, safeRealpath, toPosix } from "
|
|
7
|
+
import { isWithin, resolveStashDir, safeRealpath, toPosix } from "../../core/common.js";
|
|
8
8
|
const PROJECT_CONFIG_RELATIVE_PATH = path.join(".akm", "config.json");
|
|
9
9
|
export function getCurrentWorkflowScopeKey() {
|
|
10
10
|
const anchor = resolveWorkflowScopeAnchor(process.cwd());
|
package/dist/workflows/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
import { UsageError } from "../core/errors";
|
|
4
|
+
import { UsageError } from "../core/errors.js";
|
|
5
5
|
export const WORKFLOW_STEP_STATES = [
|
|
6
6
|
"completed",
|
|
7
7
|
"blocked",
|
package/dist/workflows/db.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
import { Database } from "bun:sqlite";
|
|
5
4
|
import fs from "node:fs";
|
|
6
5
|
import path from "node:path";
|
|
7
|
-
import { getWorkflowDbPath } from "../core/paths";
|
|
6
|
+
import { getWorkflowDbPath } from "../core/paths.js";
|
|
7
|
+
import { openDatabase } from "../storage/database.js";
|
|
8
|
+
import { runMigrations as runSqliteMigrations } from "../storage/engines/sqlite-migrations.js";
|
|
8
9
|
/**
|
|
9
10
|
* workflow.db — Durable SQLite database for workflow run state.
|
|
10
11
|
*
|
|
@@ -44,7 +45,7 @@ export function openWorkflowDatabase(dbPath = getWorkflowDbPath()) {
|
|
|
44
45
|
if (!fs.existsSync(dir)) {
|
|
45
46
|
fs.mkdirSync(dir, { recursive: true });
|
|
46
47
|
}
|
|
47
|
-
const db =
|
|
48
|
+
const db = openDatabase(dbPath);
|
|
48
49
|
db.exec("PRAGMA journal_mode = WAL");
|
|
49
50
|
db.exec("PRAGMA foreign_keys = ON");
|
|
50
51
|
ensureBaseSchema(db);
|
|
@@ -102,6 +103,13 @@ function ensureBaseSchema(db) {
|
|
|
102
103
|
ON workflow_run_steps(run_id, sequence_index);
|
|
103
104
|
`);
|
|
104
105
|
}
|
|
106
|
+
// ── Migration engine ─────────────────────────────────────────────────────────
|
|
107
|
+
//
|
|
108
|
+
// The runner itself (ensureMigrationsTable + runMigrations) lives in the shared
|
|
109
|
+
// engine at src/storage/engines/sqlite-migrations.ts. This module owns its own
|
|
110
|
+
// MIGRATIONS array plus the pre-versioning `bootstrap` hook, and delegates
|
|
111
|
+
// application to that shared runner. The {@link Migration} interface is imported
|
|
112
|
+
// from there.
|
|
105
113
|
/**
|
|
106
114
|
* All workflow.db migrations in application order. New migrations are
|
|
107
115
|
* APPENDED — never inserted in the middle or reordered.
|
|
@@ -121,29 +129,50 @@ const MIGRATIONS = [
|
|
|
121
129
|
ON workflow_runs(scope_key, workflow_ref, status);
|
|
122
130
|
`,
|
|
123
131
|
},
|
|
132
|
+
// ── Migration 002 — record agent harness + session identity ──────────────────
|
|
133
|
+
//
|
|
134
|
+
// Persists the agent harness identifier (e.g. "claude-code", "opencode") and
|
|
135
|
+
// the platform-native session id that owns each workflow run. This is the
|
|
136
|
+
// first concrete slice of #501 / #506: capturing *who* is driving a run so a
|
|
137
|
+
// future (separately-approved) monitor can correlate workflow runs with
|
|
138
|
+
// session activity. Both columns are nullable — runs started outside an agent
|
|
139
|
+
// harness, and all pre-existing runs, simply have NULL identity.
|
|
140
|
+
{
|
|
141
|
+
id: "002-add-agent-identity",
|
|
142
|
+
up: `
|
|
143
|
+
ALTER TABLE workflow_runs ADD COLUMN agent_harness TEXT;
|
|
144
|
+
ALTER TABLE workflow_runs ADD COLUMN agent_session_id TEXT;
|
|
145
|
+
|
|
146
|
+
CREATE INDEX IF NOT EXISTS idx_workflow_runs_agent_session
|
|
147
|
+
ON workflow_runs(agent_harness, agent_session_id);
|
|
148
|
+
`,
|
|
149
|
+
},
|
|
150
|
+
// ── Migration 003 — check-in arming + per-step summary (#506) ────────────────
|
|
151
|
+
//
|
|
152
|
+
// Builds on the agent identity recorded by migration 002. Arms a file-signal
|
|
153
|
+
// check-in (a timestamp, NOT a background thread — see
|
|
154
|
+
// docs/technical/workflow-agent-checkin-adr.md) so a stalled run can be
|
|
155
|
+
// re-targeted with a `continue` directive, and adds a per-step `summary`
|
|
156
|
+
// column so step/workflow completion can capture and validate a required
|
|
157
|
+
// summary of work done. Both columns are nullable.
|
|
158
|
+
{
|
|
159
|
+
id: "003-checkin-and-step-summary",
|
|
160
|
+
up: `
|
|
161
|
+
ALTER TABLE workflow_runs ADD COLUMN checkin_armed_at TEXT;
|
|
162
|
+
ALTER TABLE workflow_run_steps ADD COLUMN summary TEXT;
|
|
163
|
+
`,
|
|
164
|
+
},
|
|
124
165
|
];
|
|
125
166
|
/**
|
|
126
167
|
* Stable id of the scope_key migration. Exported for bootstrap detection and
|
|
127
168
|
* tests.
|
|
128
169
|
*/
|
|
129
170
|
const SCOPE_KEY_MIGRATION_ID = "001-add-scope-key";
|
|
130
|
-
/**
|
|
131
|
-
* Create the migrations table if it does not exist. Called unconditionally on
|
|
132
|
-
* every open so a fresh database bootstraps correctly.
|
|
133
|
-
*/
|
|
134
|
-
function ensureMigrationsTable(db) {
|
|
135
|
-
db.exec(`
|
|
136
|
-
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
137
|
-
id TEXT PRIMARY KEY,
|
|
138
|
-
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
139
|
-
);
|
|
140
|
-
`);
|
|
141
|
-
}
|
|
142
171
|
/**
|
|
143
172
|
* Detect whether a column exists on a given table.
|
|
144
173
|
*/
|
|
145
174
|
function hasColumn(db, table, column) {
|
|
146
|
-
const rows = db.
|
|
175
|
+
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
147
176
|
return rows.some((r) => r.name === column);
|
|
148
177
|
}
|
|
149
178
|
/**
|
|
@@ -171,24 +200,13 @@ function bootstrapPreVersioningDb(db) {
|
|
|
171
200
|
/**
|
|
172
201
|
* Apply every pending migration in a single transaction per migration.
|
|
173
202
|
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
203
|
+
* Delegates to the shared SQLite migration engine, passing the
|
|
204
|
+
* `bootstrapPreVersioningDb` hook so databases created before this file gained
|
|
205
|
+
* migration tracking back-fill their scope_key row instead of re-running the
|
|
206
|
+
* ALTER.
|
|
178
207
|
*
|
|
179
208
|
* Called automatically by {@link openWorkflowDatabase}.
|
|
180
209
|
*/
|
|
181
210
|
export function runMigrations(db) {
|
|
182
|
-
|
|
183
|
-
bootstrapPreVersioningDb(db);
|
|
184
|
-
const appliedRows = db.prepare("SELECT id FROM schema_migrations").all();
|
|
185
|
-
const applied = new Set(appliedRows.map((r) => r.id));
|
|
186
|
-
for (const migration of MIGRATIONS) {
|
|
187
|
-
if (applied.has(migration.id))
|
|
188
|
-
continue;
|
|
189
|
-
db.transaction(() => {
|
|
190
|
-
db.exec(migration.up);
|
|
191
|
-
db.prepare("INSERT INTO schema_migrations (id) VALUES (?)").run(migration.id);
|
|
192
|
-
})();
|
|
193
|
-
}
|
|
211
|
+
runSqliteMigrations(db, MIGRATIONS, { bootstrap: bootstrapPreVersioningDb });
|
|
194
212
|
}
|
package/dist/workflows/parser.js
CHANGED
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
* line spans, accumulating `WorkflowError`s rather than throwing.
|
|
12
12
|
*/
|
|
13
13
|
import { parse as yamlParse } from "yaml";
|
|
14
|
-
import { parseFrontmatterBlock } from "../core/frontmatter";
|
|
15
|
-
import { parseMarkdownToc } from "../core/markdown";
|
|
16
|
-
import { WORKFLOW_SCHEMA_VERSION, } from "./schema";
|
|
17
|
-
import { runSemanticChecks } from "./validator";
|
|
14
|
+
import { parseFrontmatterBlock } from "../core/asset/frontmatter.js";
|
|
15
|
+
import { parseMarkdownToc } from "../core/asset/markdown.js";
|
|
16
|
+
import { WORKFLOW_SCHEMA_VERSION, } from "./schema.js";
|
|
17
|
+
import { runSemanticChecks } from "./validator.js";
|
|
18
18
|
const WORKFLOW_TITLE_PREFIX = "Workflow:";
|
|
19
19
|
const STEP_PREFIX = "Step:";
|
|
20
20
|
const STEP_ID_LINE = /^Step ID:\s+(.+?)\s*$/;
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
* uses the flat `WorkflowStepDefinition` type for backwards compatibility)
|
|
10
10
|
* and into search hints for the indexer.
|
|
11
11
|
*/
|
|
12
|
-
import { makeAssetRef } from "../core/asset-ref";
|
|
13
|
-
import { UsageError } from "../core/errors";
|
|
14
|
-
import { registerMetadataContributor } from "../indexer/metadata-contributors";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
12
|
+
import { makeAssetRef } from "../core/asset/asset-ref.js";
|
|
13
|
+
import { UsageError } from "../core/errors.js";
|
|
14
|
+
import { registerMetadataContributor } from "../indexer/passes/metadata-contributors.js";
|
|
15
|
+
import { parseWorkflow } from "./parser.js";
|
|
16
|
+
import { cacheWorkflowDocument } from "./runtime/document-cache.js";
|
|
17
17
|
function shellQuote(value) {
|
|
18
18
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
19
19
|
}
|