akm-cli 0.9.0-rc.9 → 0.9.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1770 -44
- package/README.md +38 -47
- package/SECURITY.md +14 -1
- package/STABILITY.md +499 -0
- package/dist/akm +148 -35
- package/dist/{akm-migrate-storage → akm-migrate} +6 -9
- package/dist/assets/hints/cli-hints-full.md +223 -95
- package/dist/assets/hints/cli-hints-short.md +85 -22
- package/dist/assets/improve-strategies/default.json +1 -1
- package/dist/assets/improve-strategies/reflect-distill.json +1 -1
- package/dist/assets/prompts/memory-infer-user.md +2 -3
- package/dist/assets/stash-skeleton/README.md +6 -5
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +20 -9
- package/dist/assets/tasks/core/extract.yml +1 -1
- package/dist/assets/tasks/core/version-check.yml +1 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
- package/dist/assets/templates/html/health.html +1 -3
- package/dist/assets/workflows/workflow-template.md +32 -15
- package/dist/cli/invocation.js +40 -15
- package/dist/cli/parse-args.js +0 -22
- package/dist/cli/retired-commands.js +121 -0
- package/dist/cli/shared.js +154 -22
- package/dist/cli/unknown-flags.js +236 -0
- package/dist/cli-node.mjs +2 -1
- package/dist/cli.js +696 -258
- package/dist/commands/agent/agent-dispatch.js +14 -3
- package/dist/commands/agent/contribute-cli.js +74 -89
- package/dist/commands/completions.js +79 -22
- package/dist/commands/config-cli.js +17 -150
- package/dist/commands/env/env-cli.js +59 -143
- package/dist/commands/env/env.js +12 -163
- package/dist/commands/env/marker-path.js +6 -0
- package/dist/commands/env/secret-cli.js +36 -66
- package/dist/commands/env/secret.js +24 -57
- package/dist/commands/feedback-cli.js +148 -88
- package/dist/commands/health/accept-rate.js +58 -0
- package/dist/commands/health/advisories.js +3 -4
- package/dist/commands/health/checks.js +85 -23
- package/dist/commands/health/html-report.js +7 -10
- package/dist/commands/health/improve-metrics.js +25 -83
- package/dist/commands/health/llm-usage.js +2 -1
- package/dist/commands/health/md-report.js +5 -9
- package/dist/commands/health/metrics.js +62 -20
- package/dist/commands/health/renderers.js +47 -0
- package/dist/commands/health/report-view-model.js +4 -5
- package/dist/commands/health/stash-exposure.js +1 -1
- package/dist/commands/health/surfaces.js +4 -122
- package/dist/commands/health/task-runs.js +3 -67
- package/dist/commands/health/types-improve.js +7 -0
- package/dist/commands/health.js +160 -35
- package/dist/commands/improve/anti-collapse.js +2 -2
- package/dist/commands/improve/autonomy-gate.js +68 -0
- package/dist/commands/improve/collapse-detector.js +41 -40
- package/dist/commands/improve/consolidate/eligibility.js +1 -23
- package/dist/commands/improve/consolidate/merge.js +4 -0
- package/dist/commands/improve/consolidate.js +140 -1000
- package/dist/commands/improve/distill/promote-memory.js +12 -12
- package/dist/commands/improve/distill/quality-gate.js +11 -6
- package/dist/commands/improve/distill.js +58 -69
- package/dist/commands/improve/eligibility.js +101 -55
- package/dist/commands/improve/extract-cli.js +14 -133
- package/dist/commands/improve/improve-cli.js +98 -114
- package/dist/commands/improve/improve-result-file.js +1 -28
- package/dist/commands/improve/improve-strategies.js +8 -5
- package/dist/commands/improve/improve.js +254 -101
- package/dist/commands/improve/locks.js +7 -0
- package/dist/commands/improve/loop-stages.js +182 -20
- package/dist/commands/improve/memory/derived-ref.js +45 -43
- package/dist/commands/improve/memory/memory-belief.js +1 -1
- package/dist/commands/improve/memory/memory-contradiction-detect.js +4 -12
- package/dist/commands/improve/memory/memory-improve.js +14 -5
- package/dist/commands/improve/outcome-loop.js +22 -65
- package/dist/commands/improve/preparation.js +114 -123
- package/dist/commands/improve/proactive-maintenance.js +2 -5
- package/dist/commands/improve/reflect.js +56 -160
- package/dist/commands/improve/run-context.js +5 -0
- package/dist/commands/improve/salience.js +11 -122
- package/dist/commands/improve/session-asset.js +4 -0
- package/dist/commands/improve/source-identity.js +10 -38
- package/dist/commands/lint/base-linter.js +51 -131
- package/dist/commands/lint/env-key-rules.js +31 -47
- package/dist/commands/lint/index.js +444 -88
- package/dist/commands/lint/types.js +22 -1
- package/dist/commands/{events.js → log.js} +33 -38
- package/dist/commands/migrate-cli.js +92 -12
- package/dist/commands/migration-tool.js +46 -0
- package/dist/commands/observability-cli.js +70 -209
- package/dist/commands/proposal/drain.js +101 -29
- package/dist/commands/proposal/proposal-cli.js +76 -48
- package/dist/commands/proposal/proposal.js +54 -18
- package/dist/commands/proposal/propose-cli.js +88 -0
- package/dist/commands/proposal/propose.js +23 -15
- package/dist/commands/proposal/repository.js +718 -279
- package/dist/commands/proposal/validators/proposal-quality-validators.js +2 -8
- package/dist/commands/proposal/validators/proposal-validators.js +55 -7
- package/dist/commands/proposal/validators/proposals.js +4 -7
- package/dist/commands/read/curate.js +34 -53
- package/dist/commands/read/knowledge.js +150 -95
- package/dist/commands/read/registry-search.js +2 -2
- package/dist/commands/read/remember-cli.js +42 -15
- package/dist/commands/read/search-cli.js +180 -78
- package/dist/commands/read/search.js +58 -43
- package/dist/commands/read/show.js +197 -141
- package/dist/commands/registry-cli.js +12 -51
- package/dist/commands/remember.js +14 -57
- package/dist/commands/sources/add-cli.js +100 -31
- package/dist/commands/sources/bundle-cli.js +166 -0
- package/dist/commands/sources/bundle-config-ops.js +7 -2
- package/dist/commands/sources/info.js +30 -7
- package/dist/commands/sources/init.js +12 -12
- package/dist/commands/sources/installed-stashes.js +387 -98
- package/dist/commands/sources/schema-repair.js +3 -2
- package/dist/commands/sources/self-update.js +131 -38
- package/dist/commands/sources/source-add.js +72 -17
- package/dist/commands/sources/source-clone.js +129 -45
- package/dist/commands/sources/source-manage.js +43 -23
- package/dist/commands/sources/sources-cli.js +57 -208
- package/dist/commands/sources/stash-cli.js +46 -53
- package/dist/commands/tasks/tasks-cli.js +91 -97
- package/dist/commands/tasks/tasks.js +284 -423
- package/dist/commands/workflow-cli.js +181 -450
- package/dist/core/abort-deadline.js +28 -0
- package/dist/core/adapter/adapters/agent-skills-adapter.js +67 -5
- package/dist/core/adapter/adapters/akm-adapter.js +60 -38
- package/dist/core/adapter/adapters/akm-lint.js +109 -42
- package/dist/core/adapter/adapters/akm-metadata.js +15 -44
- package/dist/core/adapter/adapters/akm-task-adapter.js +54 -31
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +55 -71
- package/dist/core/adapter/adapters/dotenv-adapter.js +1 -1
- package/dist/core/adapter/adapters/generic-files-adapter.js +2 -0
- package/dist/core/adapter/adapters/index.js +6 -6
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +14 -8
- package/dist/core/adapter/adapters/okf-adapter.js +187 -19
- package/dist/core/adapter/adapters/shared.js +3 -19
- package/dist/core/adapter/adapters/tool-dir-shared.js +13 -6
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +1 -0
- package/dist/core/adapter/detect-adapter.js +17 -0
- package/dist/core/adapter/recognize-match.js +6 -4
- package/dist/core/adapter/validate-context.js +214 -0
- package/dist/core/asset/akm-markdown.js +63 -0
- package/dist/core/asset/asset-placement.js +20 -6
- package/dist/core/asset/asset-ref.js +11 -9
- package/dist/core/asset/frontmatter-lint.js +30 -0
- package/dist/core/asset/frontmatter.js +29 -9
- package/dist/core/asset/markdown.js +40 -51
- package/dist/core/asset/resolve-ref.js +89 -18
- package/dist/core/asset/stash-meta.js +1 -1
- package/dist/core/bundle-id.js +51 -0
- package/dist/core/common.js +218 -44
- package/dist/core/concurrent.js +32 -0
- package/dist/core/config/config-io.js +12 -1
- package/dist/core/config/config-schema.js +35 -8
- package/dist/core/config/config-sources.js +55 -11
- package/dist/core/config/config-walker.js +25 -9
- package/dist/core/config/config.js +9 -48
- package/dist/core/config/experimental.js +21 -0
- package/dist/core/config/schema/embedding.js +5 -1
- package/dist/core/config/schema/experimental.js +30 -0
- package/dist/core/config/schema/improve-processes.js +0 -6
- package/dist/core/config/schema/improve.js +21 -3
- package/dist/core/config/schema/index-config.js +8 -15
- package/dist/core/config/schema/output.js +4 -1
- package/dist/core/config/schema/setup.js +9 -18
- package/dist/core/config/schema/sources-bundles.js +49 -33
- package/dist/core/config/schema/workflow.js +14 -3
- package/dist/core/env-secret-ref.js +76 -46
- package/dist/core/errors.js +43 -12
- package/dist/core/events.js +76 -152
- package/dist/core/file-change.js +6 -5
- package/dist/core/file-lock.js +7 -1
- package/dist/core/fs-txn.js +83 -7
- package/dist/core/git-message.js +2 -2
- package/dist/core/improve-result.js +6 -100
- package/dist/core/json-schema.js +327 -9
- package/dist/core/lesson-lint.js +1 -17
- package/dist/core/logs-db.js +2 -1
- package/dist/core/loopback.js +89 -0
- package/dist/core/migration-operation.js +33 -2
- package/dist/core/mutation-target.js +78 -0
- package/dist/core/parse.js +4 -1
- package/dist/core/path-access.js +107 -0
- package/dist/core/paths.js +17 -20
- package/dist/core/recognition-util.js +12 -14
- package/dist/core/redaction.js +98 -17
- package/dist/core/spawn-env.js +234 -0
- package/dist/core/standards/resolve-standards-context.js +2 -14
- package/dist/core/standards/resolve-stash-standards.js +2 -2
- package/dist/core/standards/resolve-type-conventions.js +2 -2
- package/dist/core/state/migrations.js +41 -18
- package/dist/core/state-db-scope.js +134 -0
- package/dist/core/state-db.js +5 -14
- package/dist/core/structured.js +1 -1
- package/dist/core/subprocess.js +182 -36
- package/dist/core/text-truncation.js +9 -5
- package/dist/core/type-presentation.js +3 -3
- package/dist/core/warn.js +0 -3
- package/dist/core/write-provenance.js +85 -0
- package/dist/core/write-source.js +778 -95
- package/dist/indexer/bundle-identity-guard.js +3 -2
- package/dist/indexer/db/graph-db.js +17 -30
- package/dist/indexer/ensure-index.js +11 -3
- package/dist/indexer/graph/graph-boost.js +9 -34
- package/dist/indexer/graph/graph-extraction.js +8 -5
- package/dist/indexer/index-writer-lock.js +53 -17
- package/dist/indexer/index-written-assets.js +33 -24
- package/dist/indexer/indexer.js +551 -253
- package/dist/indexer/installations.js +14 -96
- package/dist/indexer/passes/dir-staleness.js +16 -9
- package/dist/indexer/passes/memory-inference.js +15 -9
- package/dist/indexer/passes/metadata.js +113 -47
- package/dist/indexer/scan/doc-to-entry.js +38 -1
- package/dist/indexer/scan/drain-dir.js +13 -23
- package/dist/indexer/search/db-search.js +107 -69
- package/dist/indexer/search/fts-query.js +47 -24
- package/dist/indexer/search/ranking-contributors.js +42 -20
- package/dist/indexer/search/ranking.js +18 -99
- package/dist/indexer/search/search-fields.js +7 -2
- package/dist/indexer/search/search-source.js +82 -93
- package/dist/indexer/usage/usage-events.js +0 -89
- package/dist/indexer/walk/file-context.js +2 -1
- package/dist/indexer/walk/matchers.js +30 -43
- package/dist/indexer/walk/path-resolver.js +7 -2
- package/dist/indexer/walk/walker.js +38 -12
- package/dist/integrations/agent/builders.js +0 -6
- package/dist/integrations/agent/config.js +2 -2
- package/dist/integrations/agent/detect.js +49 -19
- package/dist/integrations/agent/engine-fallback.js +76 -0
- package/dist/integrations/agent/engine-resolution.js +24 -11
- package/dist/integrations/agent/model-aliases.js +1 -1
- package/dist/integrations/agent/profiles.js +23 -1
- package/dist/integrations/agent/prompts.js +12 -8
- package/dist/integrations/agent/runner-dispatch.js +4 -2
- package/dist/integrations/agent/runner.js +0 -1
- package/dist/integrations/agent/spawn.js +20 -93
- package/dist/integrations/github.js +1 -1
- package/dist/integrations/harnesses/aider/agent-builder.js +6 -4
- package/dist/integrations/harnesses/amazonq/agent-builder.js +7 -4
- package/dist/integrations/harnesses/claude/session-log.js +0 -10
- package/dist/integrations/harnesses/codex/agent-builder.js +5 -2
- package/dist/integrations/harnesses/copilot/agent-builder.js +5 -3
- package/dist/integrations/harnesses/gemini/agent-builder.js +5 -3
- package/dist/integrations/harnesses/index.js +3 -7
- package/dist/integrations/harnesses/opencode/agent-builder.js +21 -2
- package/dist/integrations/harnesses/opencode/session-log.js +0 -15
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +13 -4
- package/dist/integrations/harnesses/openhands/agent-builder.js +9 -6
- package/dist/integrations/harnesses/pi/agent-builder.js +6 -4
- package/dist/integrations/lockfile.js +132 -8
- package/dist/integrations/session-logs/index.js +3 -28
- package/dist/llm/client.js +136 -100
- package/dist/llm/embedders/remote.js +13 -5
- package/dist/llm/feature-gate.js +4 -12
- package/dist/llm/graph-extract.js +5 -11
- package/dist/llm/memory-infer.js +144 -1
- package/dist/llm/metadata-enhance.js +5 -7
- package/dist/llm/structured-call.js +1 -1
- package/dist/llm/usage-persist.js +26 -5
- package/dist/llm/usage-telemetry.js +25 -2
- package/dist/output/cli-hints.js +1 -2
- package/dist/output/context.js +22 -7
- package/dist/output/format-exempt.js +80 -0
- package/dist/output/generic-render.js +259 -0
- package/dist/output/render-registry.js +57 -0
- package/dist/output/renderers.js +14 -36
- package/dist/output/shapes/curate.js +10 -1
- package/dist/output/shapes/events.js +12 -7
- package/dist/output/shapes/helpers.js +56 -83
- package/dist/output/shapes/migrate.js +8 -0
- package/dist/output/shapes/passthrough.js +7 -41
- package/dist/output/shapes/proposal/producer.js +15 -7
- package/dist/output/shapes.js +2 -9
- package/dist/output/text/{init.js → bundle-create.js} +3 -1
- package/dist/output/text/bundle-show.js +7 -0
- package/dist/output/text/command-format.js +164 -96
- package/dist/output/text/env.js +1 -3
- package/dist/output/text/events.js +8 -7
- package/dist/output/text/health-format.js +103 -0
- package/dist/output/text/health.js +7 -0
- package/dist/output/text/helpers.js +10 -8
- package/dist/output/text/lint-format.js +56 -0
- package/dist/{migrate-storage-node.mjs → output/text/lint.js} +2 -5
- package/dist/output/text/migrate.js +88 -0
- package/dist/output/text/proposal/producer.js +4 -2
- package/dist/output/text/proposal-format.js +44 -72
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/show-directives.js +15 -7
- package/dist/output/text/status-list.js +32 -0
- package/dist/output/text/{save.js → sync.js} +2 -2
- package/dist/output/text/workflow-format.js +24 -203
- package/dist/output/text/workflow.js +1 -7
- package/dist/output/text.js +16 -17
- package/dist/registry/factory.js +4 -6
- package/dist/registry/origin-resolve.js +16 -27
- package/dist/registry/providers/skills-sh.js +3 -3
- package/dist/registry/providers/static-index.js +13 -23
- package/dist/registry/resolve.js +42 -7
- package/dist/registry/semver.js +34 -84
- package/dist/runtime.js +2 -23
- package/dist/scripts/akm-migrate-node.js +60972 -0
- package/dist/scripts/akm-migrate.js +60310 -0
- package/dist/setup/detect.js +42 -15
- package/dist/setup/registry-stash-loader.js +2 -2
- package/dist/setup/setup.js +236 -136
- package/dist/setup/steps/connection.js +7 -9
- package/dist/setup/steps/platforms.js +9 -9
- package/dist/setup/steps/semantic.js +15 -3
- package/dist/setup/steps/sources.js +12 -13
- package/dist/setup/steps/stashdir.js +2 -3
- package/dist/setup/steps/tasks.js +237 -120
- package/dist/sources/freshness.js +1 -1
- package/dist/sources/provider-factory.js +11 -17
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +278 -34
- package/dist/sources/providers/git-provider.js +25 -23
- package/dist/sources/providers/git-stash.js +414 -106
- package/dist/sources/providers/git.js +2 -2
- package/dist/sources/providers/npm.js +16 -19
- package/dist/sources/providers/provider-utils.js +7 -4
- package/dist/sources/providers/sync-from-ref.js +3 -9
- package/dist/sources/providers/website.js +6 -1
- package/dist/sources/resolve.js +6 -5
- package/dist/sources/snapshot-fetchers/bluesky.js +146 -0
- package/dist/sources/snapshot-fetchers/content-extract.js +566 -0
- package/dist/sources/snapshot-fetchers/fetcher-util.js +41 -0
- package/dist/sources/snapshot-fetchers/github.js +100 -0
- package/dist/sources/snapshot-fetchers/host-guard.js +291 -0
- package/dist/sources/snapshot-fetchers/registry.js +17 -1
- package/dist/sources/snapshot-fetchers/robots.js +348 -0
- package/dist/sources/snapshot-fetchers/rss.js +282 -0
- package/dist/sources/snapshot-fetchers/secret-seam.js +42 -0
- package/dist/sources/snapshot-fetchers/website-ingest.js +686 -282
- package/dist/sources/snapshot-fetchers/x.js +910 -0
- package/dist/storage/database.js +13 -1
- package/dist/storage/engines/sqlite-migrations.js +23 -111
- package/dist/storage/managed-db.js +21 -2
- package/dist/storage/repositories/canaries-repository.js +1 -1
- package/dist/storage/repositories/events-repository.js +27 -11
- package/dist/storage/repositories/improve-runs-repository.js +6 -12
- package/dist/storage/repositories/index-connection.js +44 -8
- package/dist/storage/repositories/index-entries-repository.js +157 -241
- package/dist/storage/repositories/index-entry-mapper.js +15 -11
- package/dist/storage/repositories/index-fts-repository.js +5 -2
- package/dist/storage/repositories/index-llm-cache-repository.js +0 -1
- package/dist/storage/repositories/index-meta-repository.js +2 -3
- package/dist/storage/repositories/index-schema.js +10 -25
- package/dist/storage/repositories/index-utility-repository.js +15 -28
- package/dist/storage/repositories/index-vec-repository.js +6 -1
- package/dist/storage/repositories/outcome-repository.js +119 -0
- package/dist/storage/repositories/proposals-repository.js +296 -59
- package/dist/storage/repositories/registry-cache.js +19 -0
- package/dist/storage/repositories/salience-repository.js +172 -0
- package/dist/storage/repositories/task-history-repository.js +15 -13
- package/dist/storage/repositories/workflow-runs-repository.js +118 -53
- package/dist/tasks/backends/cron.js +105 -15
- package/dist/tasks/backends/index.js +1 -1
- package/dist/tasks/backends/launchd.js +85 -38
- package/dist/tasks/backends/schtasks.js +135 -15
- package/dist/tasks/embedded.js +56 -40
- package/dist/tasks/log-redaction.js +156 -0
- package/dist/tasks/parser.js +87 -160
- package/dist/tasks/resolve-akm-bin.js +137 -59
- package/dist/tasks/runner.js +209 -44
- package/dist/tasks/scheduler-invocation.js +220 -10
- package/dist/tasks/schema.js +89 -1
- package/dist/tasks/task-id.js +1 -3
- package/dist/tasks/validator.js +20 -6
- package/dist/workflows/authoring/authoring.js +94 -143
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/concurrency-policy.js +95 -1
- package/dist/workflows/exec/dispatch-redaction.js +114 -0
- package/dist/workflows/exec/exec-unit.js +542 -0
- package/dist/workflows/exec/frozen-judge.js +130 -32
- package/dist/workflows/exec/native-executor.js +513 -274
- package/dist/workflows/exec/param-secrets.js +12 -11
- package/dist/workflows/exec/run-workflow.js +496 -237
- package/dist/workflows/exec/step-work.js +616 -412
- package/dist/workflows/exec/unit-dispatch.js +34 -0
- package/dist/workflows/exec/unit-writer.js +53 -13
- package/dist/workflows/exec/worktree.js +454 -41
- package/dist/workflows/ir/compile.js +166 -271
- package/dist/workflows/ir/freeze.js +119 -42
- package/dist/workflows/ir/params.js +135 -11
- package/dist/workflows/ir/plan-hash.js +1 -1
- package/dist/workflows/ir/schema.js +129 -45
- package/dist/workflows/parser.js +1070 -307
- package/dist/workflows/program/expressions.js +20 -208
- package/dist/workflows/program/schema.js +31 -10
- package/dist/workflows/renderer.js +123 -68
- package/dist/workflows/resource-limits.js +184 -0
- package/dist/workflows/runtime/checkin.js +3 -3
- package/dist/workflows/runtime/plan-classifier.js +16 -75
- package/dist/workflows/runtime/runs.js +331 -132
- package/dist/workflows/runtime/unit-checkin.js +1 -1
- package/dist/workflows/runtime/unit-phases.js +2 -2
- package/dist/workflows/runtime/workflow-asset-loader.js +232 -83
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +47 -38
- package/dist/workflows/validator.js +21 -62
- package/docs/README.md +110 -0
- package/docs/migration/README.md +8 -0
- package/docs/migration/release-notes/0.7.0.md +11 -11
- package/docs/migration/release-notes/0.9.0.md +209 -27
- package/docs/migration/v0.7-to-v0.8.md +48 -48
- package/docs/migration/v0.8-to-v0.9.md +567 -209
- package/docs/migration/v0.9.0-troubleshooting.md +561 -0
- package/docs/reference/README.md +19 -0
- package/docs/reference/bundle-types.md +19 -0
- package/docs/reference/cli.md +2342 -0
- package/docs/reference/configuration.md +371 -0
- package/docs/reference/data-and-telemetry.md +129 -46
- package/docs/reference/supported-formats.md +50 -0
- package/docs/reference/workflow-schema.md +1014 -0
- package/docs/reference/workflows.md +51 -0
- package/package.json +31 -13
- package/schemas/akm-asset-envelope.json +93 -0
- package/schemas/akm-config.json +89 -128
- package/schemas/akm-task.json +27 -5
- package/schemas/akm-workflow.json +157 -81
- package/dist/assets/tasks/core/backup.yml +0 -5
- package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
- package/dist/cli/config-migrate.js +0 -1878
- package/dist/cli/config-validate.js +0 -41
- package/dist/commands/backup-cli.js +0 -56
- package/dist/commands/bundle/bundle-cli.js +0 -68
- package/dist/commands/bundle/bundle.js +0 -219
- package/dist/commands/graph/graph-cli.js +0 -124
- package/dist/commands/graph/graph.js +0 -489
- package/dist/commands/improve/extract-watch.js +0 -140
- package/dist/commands/mv-cli.js +0 -1221
- package/dist/commands/sources/history.js +0 -201
- package/dist/commands/tasks/default-tasks.js +0 -186
- package/dist/core/migration-backup.js +0 -1231
- package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -95
- package/dist/llm/memory-infer-impl.js +0 -138
- package/dist/migrate/legacy/config-source-migration.js +0 -257
- package/dist/migrate/legacy/content-migration.js +0 -350
- package/dist/migrate/legacy/legacy-layout.js +0 -779
- package/dist/migrate/legacy/legacy-paths.js +0 -25
- package/dist/migrate/legacy/legacy-stash-json.js +0 -80
- package/dist/migrate/legacy/proposal-fs-import.js +0 -168
- package/dist/migrate/legacy/task-target-ref-migration.js +0 -278
- package/dist/migrate/legacy/three-db-cutover.js +0 -845
- package/dist/migrate/legacy/workflow-migrations-bodies.js +0 -52
- package/dist/migrate/legacy/workflow-migrations-frozen.js +0 -21
- package/dist/migrate/legacy-ref-grammar.js +0 -214
- package/dist/output/shapes/distill.js +0 -14
- package/dist/output/shapes/history.js +0 -11
- package/dist/output/text/distill.js +0 -6
- package/dist/output/text/enable-disable.js +0 -8
- package/dist/output/text/history.js +0 -6
- package/dist/registry/build-index.js +0 -382
- package/dist/schemas/akm-config.json +0 -4704
- package/dist/schemas/akm-task.json +0 -87
- package/dist/schemas/akm-workflow.json +0 -372
- package/dist/scripts/migrate-storage.js +0 -3816
- package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
- package/dist/workflows/cli.js +0 -53
- package/dist/workflows/exec/brief.js +0 -481
- package/dist/workflows/exec/report.js +0 -1460
- package/dist/workflows/exec/watch.js +0 -116
- package/dist/workflows/program/parser.js +0 -813
- package/dist/workflows/program/project.js +0 -104
|
@@ -2,7 +2,7 @@
|
|
|
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
|
/**
|
|
5
|
-
* launchd backend for `akm
|
|
5
|
+
* launchd backend for `akm task` (macOS default).
|
|
6
6
|
*
|
|
7
7
|
* Each task is written as a per-user LaunchAgent plist at
|
|
8
8
|
* `~/Library/LaunchAgents/com.akm.task.<id>.plist` and registered via
|
|
@@ -29,7 +29,7 @@ import { ConfigError } from "../../core/errors.js";
|
|
|
29
29
|
import { getTaskLogDir } from "../../core/paths.js";
|
|
30
30
|
import { resolveAkmInvocation } from "../resolve-akm-bin.js";
|
|
31
31
|
import { parseSchedule, translateToLaunchd } from "../schedule.js";
|
|
32
|
-
import { buildScheduledTaskInvocation, resolveScheduledTaskContext, } from "../scheduler-invocation.js";
|
|
32
|
+
import { buildScheduledTaskInvocation, parseScheduledTaskArgv, resolveScheduledTaskContext, schedulerContextDescriptor, schedulerContextPath, } from "../scheduler-invocation.js";
|
|
33
33
|
import { escapeXml, nodeExec, nodeFs, runOrThrow } from "./exec-utils.js";
|
|
34
34
|
export const LAUNCHD_LABEL_PREFIX = "com.akm.task.";
|
|
35
35
|
export function LAUNCHD_BACKEND(options = {}) {
|
|
@@ -49,6 +49,7 @@ export function LAUNCHD_BACKEND(options = {}) {
|
|
|
49
49
|
return options.envPath;
|
|
50
50
|
return process.env.PATH ?? "";
|
|
51
51
|
};
|
|
52
|
+
const defaultContextPath = schedulerContextPath(schedulerContextDescriptor(scheduledContext, pathEnv() ?? ""));
|
|
52
53
|
const setEnableState = (id, enabled) => {
|
|
53
54
|
const verb = enabled ? "enable" : "disable";
|
|
54
55
|
runOrThrow(exec, ["launchctl", verb, target(id)], {
|
|
@@ -57,10 +58,10 @@ export function LAUNCHD_BACKEND(options = {}) {
|
|
|
57
58
|
};
|
|
58
59
|
return {
|
|
59
60
|
name: "launchd",
|
|
60
|
-
install(task) {
|
|
61
|
+
install(task, opts) {
|
|
61
62
|
// Capture PATH at install time so launchd (which strips the environment
|
|
62
63
|
// aggressively) can find the same binaries the user sees interactively.
|
|
63
|
-
const xml = buildPlistXml(task, akmArgv, logDir,
|
|
64
|
+
const xml = buildPlistXml(task, [...(opts?.binding ?? akmArgv)], logDir, opts?.contextPath ?? defaultContextPath, opts?.target);
|
|
64
65
|
const file = plistPath(task.id);
|
|
65
66
|
const previousPlist = fsLike.exists(file) ? fsLike.readFile(file) : undefined;
|
|
66
67
|
let previousEnabled = true;
|
|
@@ -201,55 +202,101 @@ export function LAUNCHD_BACKEND(options = {}) {
|
|
|
201
202
|
if (ids.length === 0)
|
|
202
203
|
return [];
|
|
203
204
|
const disabledLabels = readDisabledLabels(exec);
|
|
204
|
-
return ids
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
}
|
|
221
|
-
catch {
|
|
222
|
-
return { id };
|
|
223
|
-
}
|
|
224
|
-
});
|
|
205
|
+
return ids
|
|
206
|
+
.map((id) => inspectInstalledLaunchdTask(id, fsLike.readFile(plistPath(id)), disabledLabels, exec))
|
|
207
|
+
.filter((ref) => ref !== undefined);
|
|
208
|
+
},
|
|
209
|
+
listForRebind() {
|
|
210
|
+
if (!fsLike.exists(agentsDir))
|
|
211
|
+
return [];
|
|
212
|
+
const refs = [];
|
|
213
|
+
for (const file of fsLike.list(agentsDir)) {
|
|
214
|
+
if (!file.startsWith(LAUNCHD_LABEL_PREFIX) || !file.endsWith(".plist"))
|
|
215
|
+
continue;
|
|
216
|
+
const id = file.slice(LAUNCHD_LABEL_PREFIX.length, -".plist".length);
|
|
217
|
+
const installed = extractPlistInvocation(fsLike.readFile(plistPath(id)));
|
|
218
|
+
refs.push({ id, ...(installed?.target !== undefined ? { target: installed.target } : {}) });
|
|
219
|
+
}
|
|
220
|
+
return refs;
|
|
225
221
|
},
|
|
226
|
-
expectedSignature(task) {
|
|
227
|
-
return normalizeSignature(buildPlistXml(task, akmArgv, logDir,
|
|
222
|
+
expectedSignature(task, opts) {
|
|
223
|
+
return normalizeSignature(buildPlistXml(task, [...(opts?.binding ?? akmArgv)], logDir, opts?.contextPath ?? defaultContextPath, opts?.target));
|
|
228
224
|
},
|
|
229
225
|
};
|
|
230
226
|
}
|
|
227
|
+
function inspectInstalledLaunchdTask(id, raw, disabledLabels, exec) {
|
|
228
|
+
const installed = extractPlistInvocation(raw);
|
|
229
|
+
// An invocation that no longer parses (e.g. a pre-0.9 `tasks run` entry
|
|
230
|
+
// surviving the scheduler-ABI respelling) is an orphan of its marker id,
|
|
231
|
+
// not a hard failure: `list()` omits it so `akmTasksSync` treats the id as
|
|
232
|
+
// "not present" and reinstalls it from the current task file.
|
|
233
|
+
if (!installed)
|
|
234
|
+
return undefined;
|
|
235
|
+
const metadata = {
|
|
236
|
+
...(installed.target !== undefined ? { target: installed.target } : {}),
|
|
237
|
+
binding: installed.binding,
|
|
238
|
+
contextPath: installed.contextPath,
|
|
239
|
+
};
|
|
240
|
+
if (!disabledLabels)
|
|
241
|
+
return { id, ...metadata };
|
|
242
|
+
const jobLabel = `${LAUNCHD_LABEL_PREFIX}${id}`;
|
|
243
|
+
try {
|
|
244
|
+
const loaded = exec.run(["launchctl", "print", `gui/${exec.uid()}/${jobLabel}`]);
|
|
245
|
+
if (loaded.status !== 0)
|
|
246
|
+
return { id, ...metadata };
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
return { id, ...metadata };
|
|
250
|
+
}
|
|
251
|
+
try {
|
|
252
|
+
const xml = raw.replace(/<!-- akm-enabled:(?:true|false) -->/, `<!-- akm-enabled:${!disabledLabels.has(jobLabel)} -->`);
|
|
253
|
+
return {
|
|
254
|
+
id,
|
|
255
|
+
signature: normalizeSignature(xml),
|
|
256
|
+
...metadata,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
catch {
|
|
260
|
+
return { id, ...metadata };
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Recover the bundle name embedded as a `--bundle <bundle>` pair in a plist's
|
|
265
|
+
* `<ProgramArguments>`. Returns undefined for the primary/default form.
|
|
266
|
+
*/
|
|
267
|
+
export function extractPlistTarget(xml) {
|
|
268
|
+
return extractPlistInvocation(xml)?.target;
|
|
269
|
+
}
|
|
270
|
+
export function extractPlistInvocation(xml) {
|
|
271
|
+
const block = xml.match(/<key>ProgramArguments<\/key>\s*<array>([\s\S]*?)<\/array>/);
|
|
272
|
+
if (!block)
|
|
273
|
+
return undefined;
|
|
274
|
+
const args = [...block[1].matchAll(/<string>([\s\S]*?)<\/string>/g)].map((m) => decodeXmlEntities(m[1]));
|
|
275
|
+
return parseScheduledTaskArgv(args);
|
|
276
|
+
}
|
|
277
|
+
function decodeXmlEntities(value) {
|
|
278
|
+
return value
|
|
279
|
+
.replaceAll("<", "<")
|
|
280
|
+
.replaceAll(">", ">")
|
|
281
|
+
.replaceAll(""", '"')
|
|
282
|
+
.replaceAll("'", "'")
|
|
283
|
+
.replaceAll("&", "&");
|
|
284
|
+
}
|
|
231
285
|
// ── XML builder (exported for tests) ────────────────────────────────────────
|
|
232
|
-
export function buildPlistXml(task, akmArgv, logDir,
|
|
286
|
+
export function buildPlistXml(task, akmArgv, logDir, contextPath, target) {
|
|
233
287
|
const spec = parseSchedule(task.schedule, "launchd");
|
|
234
288
|
const trigger = translateToLaunchd(spec);
|
|
235
|
-
const invocation = buildScheduledTaskInvocation(akmArgv, task.id,
|
|
289
|
+
const invocation = buildScheduledTaskInvocation(akmArgv, task.id, contextPath, target);
|
|
236
290
|
const argv = invocation.argv;
|
|
237
291
|
const programArgs = argv.map((a) => ` <string>${escapeXml(a)}</string>`).join("\n");
|
|
238
292
|
const logPath = path.join(logDir, `${task.id}.log`);
|
|
239
293
|
const triggerXml = renderLaunchdTrigger(trigger);
|
|
240
|
-
const environment = { ...invocation.environment };
|
|
241
|
-
if (pathEnv !== undefined)
|
|
242
|
-
environment.PATH = pathEnv;
|
|
243
|
-
const envEntries = Object.entries(environment)
|
|
244
|
-
.map(([key, value]) => ` <key>${key}</key>\n <string>${escapeXml(value)}</string>`)
|
|
245
|
-
.join("\n");
|
|
246
|
-
const envVarsXml = ` <key>EnvironmentVariables</key>\n <dict>\n${envEntries}\n </dict>\n`;
|
|
247
294
|
const xml = launchdTemplate
|
|
248
295
|
.replace("<dict>\n", `<dict>\n <!-- akm-enabled:${task.enabled} -->\n`)
|
|
249
296
|
.replace("{{LABEL}}", LAUNCHD_LABEL_PREFIX + escapeXml(task.id))
|
|
250
297
|
.replace("{{PROGRAM_ARGS}}", programArgs)
|
|
251
298
|
.replaceAll("{{LOG_PATH}}", escapeXml(logPath))
|
|
252
|
-
.replace("{{ENV_VARS}}",
|
|
299
|
+
.replace("{{ENV_VARS}}", "")
|
|
253
300
|
.replace("{{TRIGGER_XML}}", triggerXml);
|
|
254
301
|
for (const char of xml) {
|
|
255
302
|
const code = char.codePointAt(0) ?? 0;
|
|
@@ -330,7 +377,7 @@ function defaultAgentsDir() {
|
|
|
330
377
|
// relative path that would write somewhere unexpected.
|
|
331
378
|
const home = os.homedir();
|
|
332
379
|
if (!home) {
|
|
333
|
-
throw new ConfigError("Cannot determine user home directory; launchd backend requires HOME to locate ~/Library/LaunchAgents.", "INVALID_CONFIG_FILE", "Set $HOME (POSIX) or the equivalent before running `akm
|
|
380
|
+
throw new ConfigError("Cannot determine user home directory; launchd backend requires HOME to locate ~/Library/LaunchAgents.", "INVALID_CONFIG_FILE", "Set $HOME (POSIX) or the equivalent before running `akm task` on macOS.");
|
|
334
381
|
}
|
|
335
382
|
return path.join(home, "Library", "LaunchAgents");
|
|
336
383
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
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
|
/**
|
|
5
|
-
* schtasks.exe backend for `akm
|
|
5
|
+
* schtasks.exe backend for `akm task` (Windows default).
|
|
6
6
|
*
|
|
7
7
|
* Each task is registered under the `\akm\` Task Scheduler folder so the
|
|
8
8
|
* backend never touches user-managed tasks. The full task definition is
|
|
@@ -37,7 +37,7 @@ import { ConfigError } from "../../core/errors.js";
|
|
|
37
37
|
import { getTaskLogDir } from "../../core/paths.js";
|
|
38
38
|
import { resolveAkmInvocation } from "../resolve-akm-bin.js";
|
|
39
39
|
import { parseSchedule, translateToSchtasks } from "../schedule.js";
|
|
40
|
-
import { buildScheduledTaskInvocation, resolveScheduledTaskContext, } from "../scheduler-invocation.js";
|
|
40
|
+
import { buildScheduledTaskInvocation, parseScheduledTaskArgv, resolveScheduledTaskContext, schedulerContextDescriptor, schedulerContextPath, } from "../scheduler-invocation.js";
|
|
41
41
|
import { escapeXml, nodeExec, nodeFs, normalizeXmlForUtf16File, runOrThrow, } from "./exec-utils.js";
|
|
42
42
|
export const DEFAULT_FOLDER_PREFIX = "\\akm\\";
|
|
43
43
|
const SIGNATURE_PREFIX = "akm:v1:";
|
|
@@ -48,12 +48,19 @@ export function SCHTASKS_BACKEND(options = {}) {
|
|
|
48
48
|
const logDir = options.logDir ?? getTaskLogDir();
|
|
49
49
|
const folder = options.folderPrefix ?? DEFAULT_FOLDER_PREFIX;
|
|
50
50
|
const scheduledContext = options.scheduledContext ?? resolveScheduledTaskContext();
|
|
51
|
+
const defaultContextPath = schedulerContextPath(schedulerContextDescriptor(scheduledContext, process.env.PATH ?? ""));
|
|
51
52
|
const userSid = options.userSid ?? resolveCurrentUserSid(exec);
|
|
52
53
|
const taskName = (id) => `${folder}${id}`;
|
|
53
54
|
return {
|
|
54
55
|
name: "schtasks",
|
|
55
|
-
install(task) {
|
|
56
|
-
const xml = normalizeXmlForUtf16File(buildSchtasksXml(task, akmArgv, logDir, {
|
|
56
|
+
install(task, opts) {
|
|
57
|
+
const xml = normalizeXmlForUtf16File(buildSchtasksXml(task, akmArgv, logDir, {
|
|
58
|
+
folderPrefix: folder,
|
|
59
|
+
contextPath: opts?.contextPath ?? defaultContextPath,
|
|
60
|
+
userSid,
|
|
61
|
+
binding: [...(opts?.binding ?? akmArgv)],
|
|
62
|
+
...(opts?.target !== undefined ? { target: opts.target } : {}),
|
|
63
|
+
}));
|
|
57
64
|
const query = runOrThrow(exec, ["schtasks", "/Query", "/TN", taskName(task.id), "/XML"], {
|
|
58
65
|
isOk: (r) => r.status === 0 || isMissingTaskResult(r),
|
|
59
66
|
message: (r) => `schtasks /Query failed (exit ${r.status}): ${r.stderr || r.stdout || "no output"}.`,
|
|
@@ -146,26 +153,142 @@ export function SCHTASKS_BACKEND(options = {}) {
|
|
|
146
153
|
ids.push(name.slice(folder.length));
|
|
147
154
|
}
|
|
148
155
|
}
|
|
149
|
-
|
|
156
|
+
const refs = [];
|
|
157
|
+
for (const id of ids) {
|
|
150
158
|
const query = runOrThrow(exec, ["schtasks", "/Query", "/TN", taskName(id), "/XML"], {
|
|
151
159
|
message: (r) => `schtasks /Query /XML for "${taskName(id)}" failed (exit ${r.status}): ${r.stderr || r.stdout || "no output"}.`,
|
|
152
160
|
});
|
|
153
161
|
const signature = installedSignature(query.stdout);
|
|
154
|
-
|
|
162
|
+
const installed = extractSchtasksInvocation(query.stdout);
|
|
163
|
+
// An invocation that no longer parses (e.g. a pre-0.9 `tasks run`
|
|
164
|
+
// entry surviving the scheduler-ABI respelling) is an orphan of its
|
|
165
|
+
// marker id, not a hard failure: omit it so `akmTasksSync` treats the
|
|
166
|
+
// id as "not present" and reinstalls it from the current task file.
|
|
167
|
+
if (!installed)
|
|
168
|
+
continue;
|
|
169
|
+
refs.push({
|
|
170
|
+
id,
|
|
171
|
+
...(signature !== undefined ? { signature } : {}),
|
|
172
|
+
...(installed.target !== undefined ? { target: installed.target } : {}),
|
|
173
|
+
binding: installed.binding,
|
|
174
|
+
contextPath: installed.contextPath,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
return refs;
|
|
178
|
+
},
|
|
179
|
+
listForRebind() {
|
|
180
|
+
const r = runOrThrow(exec, ["schtasks", "/Query", "/FO", "CSV", "/NH"], {
|
|
181
|
+
message: (res) => `schtasks /Query failed (exit ${res.status}): ${res.stderr || res.stdout || "no output"}.`,
|
|
155
182
|
});
|
|
183
|
+
const refs = [];
|
|
184
|
+
for (const line of (r.stdout ?? "").split(/\r?\n/)) {
|
|
185
|
+
const match = line.match(/^"([^"]+)",/);
|
|
186
|
+
const name = match?.[1];
|
|
187
|
+
if (!name?.startsWith(folder))
|
|
188
|
+
continue;
|
|
189
|
+
const id = name.slice(folder.length);
|
|
190
|
+
const query = runOrThrow(exec, ["schtasks", "/Query", "/TN", taskName(id), "/XML"], {
|
|
191
|
+
message: (result) => `schtasks /Query /XML for "${taskName(id)}" failed (exit ${result.status}): ${result.stderr || result.stdout || "no output"}.`,
|
|
192
|
+
});
|
|
193
|
+
const signature = installedSignature(query.stdout);
|
|
194
|
+
const installed = extractSchtasksInvocation(query.stdout);
|
|
195
|
+
refs.push({
|
|
196
|
+
id,
|
|
197
|
+
...(signature !== undefined ? { signature } : {}),
|
|
198
|
+
...(installed?.target !== undefined ? { target: installed.target } : {}),
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
return refs;
|
|
156
202
|
},
|
|
157
|
-
expectedSignature(task) {
|
|
158
|
-
const signature = taskXmlSignature(buildSchtasksXml(task, akmArgv, logDir, {
|
|
203
|
+
expectedSignature(task, opts) {
|
|
204
|
+
const signature = taskXmlSignature(buildSchtasksXml(task, akmArgv, logDir, {
|
|
205
|
+
folderPrefix: folder,
|
|
206
|
+
contextPath: opts?.contextPath ?? defaultContextPath,
|
|
207
|
+
userSid,
|
|
208
|
+
binding: [...(opts?.binding ?? akmArgv)],
|
|
209
|
+
...(opts?.target !== undefined ? { target: opts.target } : {}),
|
|
210
|
+
}));
|
|
159
211
|
if (signature === undefined)
|
|
160
212
|
throw new Error("Failed to fingerprint generated Task Scheduler XML.");
|
|
161
213
|
return signature;
|
|
162
214
|
},
|
|
163
215
|
};
|
|
164
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* Recover the bundle name embedded as a `--bundle <bundle>` pair in the
|
|
219
|
+
* PowerShell `<Arguments>` of an installed Task Scheduler definition. Returns
|
|
220
|
+
* undefined for the primary/default form.
|
|
221
|
+
*/
|
|
222
|
+
export function extractSchtasksTarget(xml) {
|
|
223
|
+
return extractSchtasksInvocation(xml)?.target;
|
|
224
|
+
}
|
|
225
|
+
export function extractSchtasksInvocation(xml) {
|
|
226
|
+
const argsElement = xml.match(/<(?:[\w.-]+:)?Arguments>([\s\S]*?)<\/(?:[\w.-]+:)?Arguments>/i);
|
|
227
|
+
if (!argsElement)
|
|
228
|
+
return undefined;
|
|
229
|
+
const commandLine = decodeXml(argsElement[1]);
|
|
230
|
+
const invocationStart = findPowerShellInvocationOperator(commandLine);
|
|
231
|
+
if (invocationStart === undefined)
|
|
232
|
+
return undefined;
|
|
233
|
+
return parseScheduledTaskArgv(parsePowerShellSingleQuotedArgs(commandLine, invocationStart + 1));
|
|
234
|
+
}
|
|
235
|
+
function findPowerShellInvocationOperator(script) {
|
|
236
|
+
let inSingleQuote = false;
|
|
237
|
+
for (let index = 0; index < script.length; index += 1) {
|
|
238
|
+
const char = script[index];
|
|
239
|
+
if (char === "'") {
|
|
240
|
+
if (inSingleQuote && script[index + 1] === "'") {
|
|
241
|
+
index += 1;
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
inSingleQuote = !inSingleQuote;
|
|
245
|
+
}
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
if (!inSingleQuote && char === "&" && /\s/.test(script[index + 1] ?? ""))
|
|
249
|
+
return index;
|
|
250
|
+
}
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
253
|
+
function parsePowerShellSingleQuotedArgs(script, start) {
|
|
254
|
+
const argv = [];
|
|
255
|
+
let index = start;
|
|
256
|
+
while (index < script.length) {
|
|
257
|
+
while (/\s/.test(script[index] ?? ""))
|
|
258
|
+
index += 1;
|
|
259
|
+
if (script[index] === ";" || script[index] === '"' || index >= script.length)
|
|
260
|
+
break;
|
|
261
|
+
if (script[index] !== "'")
|
|
262
|
+
return [];
|
|
263
|
+
index += 1;
|
|
264
|
+
let value = "";
|
|
265
|
+
let closed = false;
|
|
266
|
+
while (index < script.length) {
|
|
267
|
+
const char = script[index];
|
|
268
|
+
if (char !== "'") {
|
|
269
|
+
value += char;
|
|
270
|
+
index += 1;
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
if (script[index + 1] === "'") {
|
|
274
|
+
value += "'";
|
|
275
|
+
index += 2;
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
index += 1;
|
|
279
|
+
closed = true;
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
if (!closed)
|
|
283
|
+
return [];
|
|
284
|
+
argv.push(value);
|
|
285
|
+
}
|
|
286
|
+
return argv;
|
|
287
|
+
}
|
|
165
288
|
export function buildSchtasksXml(task, akmArgv, logDir, options) {
|
|
166
289
|
const folder = options.folderPrefix ?? DEFAULT_FOLDER_PREFIX;
|
|
167
290
|
const now = options.now ? options.now() : new Date();
|
|
168
|
-
const definition = buildSchtasksDefinition(task, akmArgv, logDir, folder, options.
|
|
291
|
+
const definition = buildSchtasksDefinition(task, options.binding ?? akmArgv, logDir, folder, options.contextPath, options.userSid, options.target);
|
|
169
292
|
const triggerXml = renderSchtasksTrigger(definition.trigger, now);
|
|
170
293
|
return schtasksTemplate
|
|
171
294
|
.replaceAll("{{TASK_ID}}", escapeXml(task.id))
|
|
@@ -178,15 +301,12 @@ export function buildSchtasksXml(task, akmArgv, logDir, options) {
|
|
|
178
301
|
.replace("{{ARGS}}", escapeXml(definition.args))
|
|
179
302
|
.replace("{{LOG_PATH}}", escapeXml(definition.logPath));
|
|
180
303
|
}
|
|
181
|
-
function buildSchtasksDefinition(task, akmArgv, logDir, folder,
|
|
304
|
+
function buildSchtasksDefinition(task, akmArgv, logDir, folder, contextPath, userSid, target) {
|
|
182
305
|
const spec = parseSchedule(task.schedule, "schtasks");
|
|
183
306
|
const trigger = translateToSchtasks(spec);
|
|
184
|
-
const invocation = buildScheduledTaskInvocation(akmArgv, task.id,
|
|
185
|
-
const environment = Object.entries(invocation.environment)
|
|
186
|
-
.map(([key, value]) => `$env:${key}=${quotePowerShell(value)}`)
|
|
187
|
-
.join("; ");
|
|
307
|
+
const invocation = buildScheduledTaskInvocation(akmArgv, task.id, contextPath, target);
|
|
188
308
|
const invoke = `& ${invocation.argv.map((arg) => quotePowerShell(arg)).join(" ")}`;
|
|
189
|
-
const script = `${
|
|
309
|
+
const script = `${invoke}; exit $LASTEXITCODE`;
|
|
190
310
|
const command = "powershell.exe";
|
|
191
311
|
const args = ["-NoLogo", "-NoProfile", "-NonInteractive", "-Command", script].map(quoteArg).join(" ");
|
|
192
312
|
const logPath = path.join(logDir, `${task.id}.log`);
|
package/dist/tasks/embedded.js
CHANGED
|
@@ -2,14 +2,18 @@
|
|
|
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
|
/**
|
|
5
|
-
* Embedded
|
|
5
|
+
* Embedded task templates.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* under `src/assets/tasks
|
|
7
|
+
* Curated sets of read-only YAML task templates ship inside the akm binary
|
|
8
|
+
* under `src/assets/tasks/<category>/` — `core/` (general-purpose maintenance)
|
|
9
|
+
* and `improve/` (the maintainer-oriented multi-cadence improve schedule,
|
|
10
|
+
* folded in from the retired `registerDefaultTasks`/`akm tasks init` path in
|
|
11
|
+
* 0.9, S6). Every category subdirectory is enumerated the same way; adding a
|
|
12
|
+
* new one needs no code change here. Templates are resolved at runtime via
|
|
9
13
|
* `import.meta.dir` (mirroring `SKELETON_DIR` in
|
|
10
14
|
* src/commands/stash-skeleton.ts) and are NOT written to any stash at
|
|
11
|
-
* install
|
|
12
|
-
*
|
|
15
|
+
* install time — the `akm setup` wizard copies a template into the primary
|
|
16
|
+
* stash only when the user opts in (copy-on-enable).
|
|
13
17
|
*
|
|
14
18
|
* Each entry exposes the parsed `command`, `schedule`, and `description`
|
|
15
19
|
* alongside the raw `yaml`, so the wizard can both render a choice and write
|
|
@@ -17,57 +21,69 @@
|
|
|
17
21
|
*/
|
|
18
22
|
import fs from "node:fs";
|
|
19
23
|
import path from "node:path";
|
|
20
|
-
import { parse as yamlParse } from "yaml";
|
|
21
24
|
import { getDirname } from "../runtime.js";
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
import { parseTaskDocument } from "./parser.js";
|
|
26
|
+
/** Directory holding the bundled task template categories. */
|
|
27
|
+
const TASKS_ASSETS_DIR = path.join(getDirname(import.meta.url), "../assets/tasks");
|
|
24
28
|
/**
|
|
25
|
-
* Enumerate the embedded
|
|
26
|
-
* directory. Sorted by id for deterministic
|
|
27
|
-
* if the directory is missing (defensive —
|
|
28
|
-
* crash the wizard).
|
|
29
|
+
* Enumerate the embedded task templates from every category subdirectory of
|
|
30
|
+
* the bundled assets directory. Sorted by category then id for deterministic
|
|
31
|
+
* ordering. Returns an empty array if the directory is missing (defensive —
|
|
32
|
+
* a build without assets should not crash the wizard).
|
|
29
33
|
*/
|
|
30
34
|
export function listEmbeddedTasks() {
|
|
31
|
-
let
|
|
35
|
+
let categories;
|
|
32
36
|
try {
|
|
33
|
-
|
|
37
|
+
categories = fs
|
|
38
|
+
.readdirSync(TASKS_ASSETS_DIR, { withFileTypes: true })
|
|
39
|
+
.filter((entry) => entry.isDirectory())
|
|
40
|
+
.map((entry) => entry.name)
|
|
41
|
+
.sort();
|
|
34
42
|
}
|
|
35
43
|
catch {
|
|
36
44
|
return [];
|
|
37
45
|
}
|
|
38
46
|
const tasks = [];
|
|
39
|
-
for (const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const id = entry.slice(0, -4);
|
|
43
|
-
const filePath = path.join(CORE_TASKS_DIR, entry);
|
|
44
|
-
let yaml;
|
|
47
|
+
for (const category of categories) {
|
|
48
|
+
const categoryDir = path.join(TASKS_ASSETS_DIR, category);
|
|
49
|
+
let entries;
|
|
45
50
|
try {
|
|
46
|
-
|
|
51
|
+
entries = fs.readdirSync(categoryDir);
|
|
47
52
|
}
|
|
48
53
|
catch {
|
|
49
54
|
continue;
|
|
50
55
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
for (const entry of entries.sort()) {
|
|
57
|
+
if (!entry.endsWith(".yml"))
|
|
58
|
+
continue;
|
|
59
|
+
const id = entry.slice(0, -4);
|
|
60
|
+
const filePath = path.join(categoryDir, entry);
|
|
61
|
+
let yaml;
|
|
62
|
+
try {
|
|
63
|
+
yaml = fs.readFileSync(filePath, "utf8");
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
let task;
|
|
69
|
+
try {
|
|
70
|
+
task = parseTaskDocument({ yaml, filePath, id });
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (task.target.kind !== "command")
|
|
76
|
+
continue;
|
|
77
|
+
tasks.push({
|
|
78
|
+
id,
|
|
79
|
+
label: `${category}/${id}`,
|
|
80
|
+
command: task.target.cmd.join(" "),
|
|
81
|
+
schedule: task.schedule,
|
|
82
|
+
description: task.description ?? "",
|
|
83
|
+
enabled: task.enabled,
|
|
84
|
+
yaml,
|
|
85
|
+
});
|
|
57
86
|
}
|
|
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
|
-
const enabled = doc.enabled !== false;
|
|
62
|
-
tasks.push({
|
|
63
|
-
id,
|
|
64
|
-
label: `core/${id}`,
|
|
65
|
-
command,
|
|
66
|
-
schedule,
|
|
67
|
-
description,
|
|
68
|
-
enabled,
|
|
69
|
-
yaml,
|
|
70
|
-
});
|
|
71
87
|
}
|
|
72
88
|
return tasks;
|
|
73
89
|
}
|