akm-cli 0.9.0-beta.6 → 0.9.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +663 -0
- package/README.md +12 -4
- package/dist/akm +38 -0
- package/dist/akm-migrate-storage +38 -0
- package/dist/assets/help/help-improve.md +9 -6
- package/dist/assets/hints/cli-hints-full.md +6 -5
- package/dist/assets/profiles/default.json +9 -4
- package/dist/assets/profiles/frequent.json +1 -1
- package/dist/assets/profiles/memory-focus.json +1 -1
- package/dist/assets/profiles/proactive-maintenance.json +25 -0
- package/dist/assets/profiles/quick.json +1 -1
- package/dist/assets/profiles/recombine-only.json +21 -0
- package/dist/assets/profiles/reflect-distill.json +30 -0
- package/dist/assets/profiles/synthesize.json +15 -0
- package/dist/assets/profiles/thorough.json +1 -1
- package/dist/assets/prompts/consolidate-system.md +23 -0
- package/dist/assets/prompts/contradiction-judge.md +33 -0
- package/dist/assets/prompts/distill-knowledge-system.md +22 -0
- package/dist/assets/prompts/distill-lesson-system.md +36 -0
- package/dist/assets/prompts/extract-session.md +11 -3
- package/dist/assets/prompts/graph-extract-system.md +1 -0
- package/dist/assets/prompts/graph-extract-user-prompt.md +1 -1
- package/dist/assets/prompts/memory-infer-system.md +1 -0
- package/dist/assets/prompts/memory-infer-user.md +5 -0
- package/dist/assets/prompts/metadata-enhance-system.md +1 -0
- package/dist/assets/prompts/procedural-system.md +44 -0
- package/dist/assets/prompts/recombine-system.md +40 -0
- package/dist/assets/prompts/staleness-detect-system.md +6 -0
- package/dist/assets/prompts/validate-summary-judge.md +1 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +39 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +40 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +43 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +43 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +40 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +43 -0
- package/dist/assets/templates/html/health.html +281 -111
- package/dist/assets/wiki/ingest-workflow-template.md +45 -16
- package/dist/assets/wiki/schema-template.md +4 -4
- package/dist/cli/clack.js +56 -0
- package/dist/cli/config-migrate.js +7 -1
- package/dist/cli/confirm.js +1 -1
- package/dist/cli/parse-args.js +46 -1
- package/dist/cli/shared.js +28 -0
- package/dist/cli.js +25 -14
- package/dist/commands/agent/agent-dispatch.js +3 -2
- package/dist/commands/agent/agent-support.js +0 -7
- package/dist/commands/agent/contribute-cli.js +26 -7
- package/dist/commands/config-cli.js +26 -13
- package/dist/commands/env/child-env.js +47 -0
- package/dist/commands/env/env-cli.js +220 -227
- package/dist/commands/env/env.js +14 -67
- package/dist/commands/env/secret-cli.js +140 -138
- package/dist/commands/feedback-cli.js +153 -147
- package/dist/commands/graph/graph-cli.js +5 -13
- package/dist/commands/graph/graph.js +76 -72
- package/dist/commands/health/advisories.js +151 -0
- package/dist/commands/health/checks.js +103 -16
- package/dist/commands/health/html-report.js +447 -81
- package/dist/commands/health/improve-metrics.js +771 -0
- package/dist/commands/health/llm-usage.js +65 -0
- package/dist/commands/health/md-report.js +103 -0
- package/dist/commands/health/metrics.js +278 -0
- package/dist/commands/health/stash-exposure.js +46 -0
- package/dist/commands/health/surfaces.js +216 -0
- package/dist/commands/health/task-runs.js +135 -0
- package/dist/commands/health/types.js +26 -0
- package/dist/commands/health/windows.js +195 -0
- package/dist/commands/health.js +91 -1083
- package/dist/commands/improve/anti-collapse.js +170 -0
- package/dist/commands/improve/calibration.js +161 -0
- package/dist/commands/improve/collapse-detector.js +421 -0
- package/dist/commands/improve/consolidate/chunking.js +141 -0
- package/dist/commands/improve/consolidate/eligibility.js +64 -0
- package/dist/commands/improve/consolidate/merge.js +145 -0
- package/dist/commands/improve/consolidate/sanitize.js +231 -0
- package/dist/commands/{lint.js → improve/consolidate/types.js} +1 -1
- package/dist/commands/improve/consolidate.js +1313 -1278
- package/dist/commands/improve/dedup.js +482 -0
- package/dist/commands/improve/distill/content-repair.js +202 -0
- package/dist/commands/improve/distill/promote-memory.js +229 -0
- package/dist/commands/improve/distill/quality-gate.js +236 -0
- package/dist/commands/improve/distill-guards.js +127 -0
- package/dist/commands/improve/distill-promotion-policy.js +826 -167
- package/dist/commands/improve/distill.js +243 -599
- package/dist/commands/improve/eligibility.js +434 -0
- package/dist/commands/improve/encoding-salience.js +205 -0
- package/dist/commands/improve/extract-cli.js +179 -59
- package/dist/commands/improve/extract-prompt.js +55 -4
- package/dist/commands/improve/extract-watch.js +140 -0
- package/dist/commands/improve/extract.js +409 -43
- package/dist/commands/improve/feedback-valence.js +54 -0
- package/dist/commands/improve/hot-probation.js +45 -0
- package/dist/commands/improve/improve-auto-accept.js +160 -7
- package/dist/commands/improve/improve-cli.js +115 -73
- package/dist/commands/improve/improve-profiles.js +32 -8
- package/dist/commands/improve/improve-result-file.js +15 -25
- package/dist/commands/improve/improve-session.js +58 -0
- package/dist/commands/improve/improve.js +510 -2537
- package/dist/commands/improve/locks.js +154 -0
- package/dist/commands/improve/loop-stages.js +1100 -0
- package/dist/commands/improve/memory/memory-belief.js +14 -15
- package/dist/commands/improve/memory/memory-contradiction-detect.js +83 -60
- package/dist/commands/improve/memory/memory-improve.js +27 -27
- package/dist/commands/improve/outcome-loop.js +270 -0
- package/dist/commands/improve/preparation.js +2002 -0
- package/dist/commands/improve/proactive-maintenance.js +115 -0
- package/dist/commands/improve/procedural.js +398 -0
- package/dist/commands/improve/recombine.js +818 -0
- package/dist/commands/improve/reflect-noise.js +0 -0
- package/dist/commands/improve/reflect.js +212 -45
- package/dist/commands/improve/salience.js +455 -0
- package/dist/commands/improve/schema-similarity-gate.js +168 -0
- package/dist/commands/improve/shared.js +51 -0
- package/dist/commands/improve/triage.js +93 -0
- package/dist/commands/lint/agent-linter.js +19 -24
- package/dist/commands/lint/base-linter.js +173 -60
- package/dist/commands/lint/command-linter.js +19 -24
- package/dist/commands/lint/env-key-rules.js +38 -1
- package/dist/commands/lint/fact-linter.js +39 -0
- package/dist/commands/lint/index.js +31 -13
- package/dist/commands/lint/memory-linter.js +1 -1
- package/dist/commands/lint/registry.js +7 -2
- package/dist/commands/lint/task-linter.js +3 -3
- package/dist/commands/lint/workflow-linter.js +26 -1
- package/dist/commands/observability-cli.js +4 -4
- package/dist/commands/proposal/drain-policies.js +13 -4
- package/dist/commands/proposal/drain.js +45 -51
- package/dist/commands/proposal/legacy-import.js +115 -0
- package/dist/commands/proposal/proposal-cli.js +24 -34
- package/dist/commands/proposal/proposal.js +7 -1
- package/dist/commands/proposal/propose.js +8 -3
- package/dist/commands/proposal/repository.js +829 -0
- package/dist/commands/proposal/validators/proposal-quality-validators.js +9 -8
- package/dist/commands/proposal/validators/proposals.js +93 -882
- package/dist/commands/read/curate.js +419 -103
- package/dist/commands/read/knowledge.js +10 -3
- package/dist/commands/read/remember-cli.js +133 -138
- package/dist/commands/read/search-cli.js +15 -8
- package/dist/commands/read/search.js +22 -11
- package/dist/commands/read/show.js +106 -14
- package/dist/commands/registry-cli.js +76 -87
- package/dist/commands/remember.js +11 -12
- package/dist/commands/sources/add-cli.js +91 -95
- package/dist/commands/sources/history.js +1 -1
- package/dist/commands/sources/init.js +66 -18
- package/dist/commands/sources/installed-stashes.js +11 -3
- package/dist/commands/sources/schema-repair.js +44 -46
- package/dist/commands/sources/self-update.js +2 -2
- package/dist/commands/sources/source-add.js +7 -3
- package/dist/commands/sources/sources-cli.js +3 -3
- package/dist/commands/sources/stash-cli.js +29 -41
- package/dist/commands/sources/stash-skeleton.js +57 -8
- package/dist/commands/tasks/default-tasks.js +15 -2
- package/dist/commands/tasks/tasks-cli.js +20 -29
- package/dist/commands/tasks/tasks.js +39 -11
- package/dist/commands/wiki-cli.js +23 -38
- package/dist/commands/workflow-cli.js +15 -1
- package/dist/core/asset/asset-registry.js +3 -1
- package/dist/core/asset/asset-spec.js +21 -4
- package/dist/core/asset/frontmatter.js +188 -167
- package/dist/core/asset/markdown.js +8 -0
- package/dist/core/authoring-rules.js +92 -0
- package/dist/core/common.js +4 -23
- package/dist/core/concurrent.js +10 -1
- package/dist/core/config/config-io.js +10 -1
- package/dist/core/config/config-migration.js +18 -40
- package/dist/core/config/config-schema.js +389 -58
- package/dist/core/config/config-types.js +3 -3
- package/dist/core/config/config.js +67 -22
- package/dist/core/deep-merge.js +38 -0
- package/dist/core/errors.js +1 -0
- package/dist/core/eval/rank-metrics.js +113 -0
- package/dist/core/events.js +4 -7
- package/dist/core/improve-types.js +47 -8
- package/dist/core/logs-db.js +14 -75
- package/dist/core/parse.js +36 -16
- package/dist/core/paths.js +21 -18
- package/dist/core/standards/resolve-standards-context.js +87 -0
- package/dist/core/standards/resolve-stash-standards.js +99 -0
- package/dist/core/standards/resolve-type-conventions.js +66 -0
- package/dist/core/state/migrations.js +770 -0
- package/dist/core/state-db.js +142 -1091
- package/dist/core/structured.js +69 -0
- package/dist/core/time.js +53 -0
- package/dist/core/warn.js +21 -0
- package/dist/core/write-source.js +37 -0
- package/dist/indexer/db/db.js +356 -780
- package/dist/indexer/db/entry-mapper.js +41 -0
- package/dist/indexer/db/graph-db.js +129 -86
- package/dist/indexer/db/llm-cache.js +2 -2
- package/dist/indexer/db/schema.js +516 -0
- package/dist/indexer/ensure-index.js +103 -24
- package/dist/indexer/feedback/utility-policy.js +75 -0
- package/dist/indexer/graph/graph-boost.js +51 -41
- package/dist/indexer/graph/graph-extraction.js +207 -4
- package/dist/indexer/index-writer-lock.js +106 -0
- package/dist/indexer/index-written-assets.js +105 -0
- package/dist/indexer/indexer.js +291 -310
- package/dist/indexer/passes/dir-staleness.js +114 -0
- package/dist/indexer/passes/memory-inference.js +13 -5
- package/dist/indexer/passes/metadata.js +20 -0
- package/dist/indexer/read-preflight.js +23 -0
- package/dist/indexer/search/db-search.js +89 -13
- package/dist/indexer/search/fts-query.js +51 -0
- package/dist/indexer/search/ranking-contributors.js +95 -9
- package/dist/indexer/search/ranking.js +79 -3
- package/dist/indexer/search/search-fields.js +6 -0
- package/dist/indexer/search/search-source.js +32 -21
- package/dist/indexer/search/semantic-status.js +4 -0
- package/dist/indexer/walk/matchers.js +9 -0
- package/dist/indexer/walk/walker.js +21 -13
- package/dist/integrations/agent/builders.js +39 -13
- package/dist/integrations/agent/config.js +20 -59
- package/dist/integrations/agent/detect.js +9 -0
- package/dist/integrations/agent/index.js +3 -19
- package/dist/integrations/agent/model-aliases.js +7 -2
- package/dist/integrations/agent/profiles.js +7 -1
- package/dist/integrations/agent/prompts.js +75 -9
- package/dist/integrations/agent/runner-dispatch.js +59 -0
- package/dist/integrations/agent/runner.js +13 -9
- package/dist/integrations/agent/spawn.js +69 -67
- package/dist/integrations/harnesses/claude/agent-builder.js +1 -1
- package/dist/integrations/harnesses/claude/index.js +2 -0
- package/dist/integrations/harnesses/claude/session-log.js +11 -1
- package/dist/integrations/harnesses/index.js +2 -3
- package/dist/integrations/harnesses/opencode/agent-builder.js +1 -1
- package/dist/integrations/harnesses/opencode/index.js +2 -0
- package/dist/integrations/harnesses/opencode/session-log.js +173 -3
- package/dist/integrations/harnesses/opencode-sdk/index.js +2 -2
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +98 -17
- package/dist/integrations/harnesses/types.js +1 -0
- package/dist/integrations/session-logs/index.js +16 -0
- package/dist/llm/call-ai.js +2 -2
- package/dist/llm/client.js +57 -15
- package/dist/llm/embedder.js +67 -4
- package/dist/llm/embedders/cache.js +3 -1
- package/dist/llm/embedders/deterministic.js +66 -0
- package/dist/llm/embedders/local.js +73 -3
- package/dist/llm/feature-gate.js +16 -15
- package/dist/llm/graph-extract.js +67 -44
- package/dist/llm/memory-infer-impl.js +138 -0
- package/dist/llm/memory-infer.js +1 -127
- package/dist/llm/metadata-enhance.js +44 -31
- package/dist/llm/structured-call.js +49 -0
- package/dist/migrate-storage-node.mjs +8 -0
- package/dist/output/context.js +5 -5
- package/dist/output/renderers.js +85 -14
- package/dist/output/shapes/curate.js +14 -2
- package/dist/output/shapes/helpers.js +0 -3
- package/dist/output/shapes/passthrough.js +2 -1
- package/dist/output/text/helpers.js +29 -1
- package/dist/output/text/workflow.js +1 -0
- package/dist/registry/providers/skills-sh.js +21 -147
- package/dist/registry/providers/static-index.js +15 -157
- package/dist/registry/resolve.js +27 -9
- package/dist/runtime.js +25 -1
- package/dist/scripts/migrate-storage.js +2718 -2354
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +891 -597
- package/dist/setup/detect.js +9 -0
- package/dist/setup/legacy-config.js +106 -0
- package/dist/setup/prompt.js +57 -0
- package/dist/setup/providers.js +14 -0
- package/dist/setup/registry-stash-loader.js +12 -0
- package/dist/setup/semantic-assets.js +124 -0
- package/dist/setup/setup.js +52 -1614
- package/dist/setup/steps/connection.js +734 -0
- package/dist/setup/steps/output.js +31 -0
- package/dist/setup/steps/platforms.js +124 -0
- package/dist/setup/steps/semantic.js +27 -0
- package/dist/setup/steps/sources.js +222 -0
- package/dist/setup/steps/stashdir.js +42 -0
- package/dist/setup/steps/tasks.js +152 -0
- package/dist/sources/include.js +6 -2
- package/dist/sources/providers/filesystem.js +0 -1
- package/dist/sources/providers/git-install.js +210 -0
- package/dist/sources/providers/git-provider.js +234 -0
- package/dist/sources/providers/git-stash.js +248 -0
- package/dist/sources/providers/git.js +10 -661
- package/dist/sources/providers/npm.js +2 -6
- package/dist/sources/providers/provider-utils.js +13 -7
- package/dist/sources/providers/sync-from-ref.js +9 -1
- package/dist/sources/providers/tar-utils.js +16 -8
- package/dist/sources/providers/website.js +9 -5
- package/dist/sources/website-ingest.js +187 -29
- package/dist/sources/wiki-fetchers/registry.js +53 -0
- package/dist/sources/wiki-fetchers/youtube.js +239 -0
- package/dist/storage/database.js +45 -10
- package/dist/storage/managed-db.js +82 -0
- package/dist/storage/repositories/canaries-repository.js +107 -0
- package/dist/storage/repositories/consolidation-repository.js +38 -0
- package/dist/storage/repositories/embeddings-repository.js +72 -0
- package/dist/storage/repositories/events-repository.js +187 -0
- package/dist/storage/repositories/extract-sessions-repository.js +96 -0
- package/dist/storage/repositories/improve-runs-repository.js +146 -0
- package/dist/storage/repositories/index-db.js +14 -8
- package/dist/storage/repositories/proposals-repository.js +220 -0
- package/dist/storage/repositories/recombine-repository.js +213 -0
- package/dist/storage/repositories/registry-cache.js +93 -0
- package/dist/storage/repositories/registry-index-cache-repository.js +46 -0
- package/dist/storage/repositories/task-history-repository.js +93 -0
- package/dist/storage/sqlite-pragmas.js +146 -0
- package/dist/tasks/backends/cron.js +1 -1
- package/dist/tasks/backends/index.js +9 -0
- package/dist/tasks/backends/launchd.js +1 -1
- package/dist/tasks/backends/schtasks.js +1 -1
- package/dist/tasks/{resolveAkmBin.js → resolve-akm-bin.js} +2 -2
- package/dist/tasks/runner.js +15 -13
- package/dist/text-import-hook.mjs +0 -0
- package/dist/wiki/wiki.js +52 -11
- package/dist/workflows/cli.js +1 -0
- package/dist/workflows/db.js +3 -4
- package/dist/workflows/runtime/runs.js +43 -118
- package/dist/workflows/runtime/workflow-asset-loader.js +125 -0
- package/dist/workflows/validate-summary.js +2 -7
- package/docs/README.md +69 -18
- package/docs/data-and-telemetry.md +5 -4
- package/docs/migration/release-notes/0.7.0.md +1 -1
- package/docs/migration/release-notes/0.9.0.md +39 -0
- package/package.json +10 -10
- package/dist/assets/tasks/core/update-stashes.yml +0 -4
- package/dist/commands/db-cli.js +0 -23
- package/dist/indexer/db/db-backup.js +0 -376
- package/dist/indexer/passes/staleness-detect.js +0 -488
package/dist/tasks/runner.js
CHANGED
|
@@ -33,13 +33,14 @@ import { loadConfig } from "../core/config/config.js";
|
|
|
33
33
|
import { NotFoundError, rethrowIfTestIsolationError } from "../core/errors.js";
|
|
34
34
|
import { buildTaskRunId, insertTaskLogLines, openLogsDatabase, } from "../core/logs-db.js";
|
|
35
35
|
import { getTaskLogDir } from "../core/paths.js";
|
|
36
|
-
import {
|
|
36
|
+
import { withStateDb } from "../core/state-db.js";
|
|
37
37
|
import { error } from "../core/warn.js";
|
|
38
38
|
import { requireAgentProfile, runAgent } from "../integrations/agent/index.js";
|
|
39
39
|
import { resolveProcessAgentProfile } from "../integrations/agent/config.js";
|
|
40
40
|
import { resolveRunner } from "../integrations/agent/runner.js";
|
|
41
41
|
import { spawn } from "../runtime.js";
|
|
42
42
|
import { resolveAssetPath } from "../sources/resolve.js";
|
|
43
|
+
import { getTaskHistory, queryTaskHistory, upsertTaskHistory } from "../storage/repositories/task-history-repository.js";
|
|
43
44
|
import { startWorkflowRun } from "../workflows/runtime/runs.js";
|
|
44
45
|
import { parseTaskDocument } from "./parser.js";
|
|
45
46
|
export async function runTask(id, options = {}) {
|
|
@@ -131,6 +132,11 @@ async function runCommandTask(input) {
|
|
|
131
132
|
stdout: "pipe",
|
|
132
133
|
stderr: "pipe",
|
|
133
134
|
cwd: process.env.HOME ?? "/tmp",
|
|
135
|
+
// Stamp task-runner provenance so any akm invocation in the command tree
|
|
136
|
+
// records usage events as machine traffic, not user demand (DRIFT-6).
|
|
137
|
+
// A more specific stamp already in the environment (e.g. improve's
|
|
138
|
+
// AKM_EVENT_SOURCE=improve on its child spawns) still wins in children.
|
|
139
|
+
env: { ...process.env, AKM_EVENT_SOURCE: process.env.AKM_EVENT_SOURCE ?? "task" },
|
|
134
140
|
});
|
|
135
141
|
let timer;
|
|
136
142
|
let timedOut = false;
|
|
@@ -351,6 +357,10 @@ async function runPromptTask(input) {
|
|
|
351
357
|
timeoutMs: agentTimeoutMs,
|
|
352
358
|
cwd: stashDir,
|
|
353
359
|
...agentOptions,
|
|
360
|
+
// Stamp task-runner provenance for any akm invocation the agent makes
|
|
361
|
+
// (DRIFT-6: agent-task traffic must not be recorded as user demand).
|
|
362
|
+
// Caller-supplied env still wins on conflicts.
|
|
363
|
+
env: { AKM_EVENT_SOURCE: "task", ...agentOptions?.env },
|
|
354
364
|
});
|
|
355
365
|
const finishedAt = now();
|
|
356
366
|
const log = renderPromptLog({ task, profileName: profile.name, result });
|
|
@@ -460,8 +470,7 @@ function persistRunLog(input) {
|
|
|
460
470
|
// ── history ─────────────────────────────────────────────────────────────────
|
|
461
471
|
function appendHistory(result) {
|
|
462
472
|
try {
|
|
463
|
-
|
|
464
|
-
try {
|
|
473
|
+
withStateDb((db) => {
|
|
465
474
|
upsertTaskHistory(db, {
|
|
466
475
|
task_id: result.id,
|
|
467
476
|
status: result.status,
|
|
@@ -477,10 +486,7 @@ function appendHistory(result) {
|
|
|
477
486
|
profile: result.target.kind === "prompt" ? result.target.profile : undefined,
|
|
478
487
|
}),
|
|
479
488
|
});
|
|
480
|
-
}
|
|
481
|
-
finally {
|
|
482
|
-
db.close();
|
|
483
|
-
}
|
|
489
|
+
});
|
|
484
490
|
}
|
|
485
491
|
catch (err) {
|
|
486
492
|
rethrowIfTestIsolationError(err);
|
|
@@ -488,8 +494,7 @@ function appendHistory(result) {
|
|
|
488
494
|
}
|
|
489
495
|
}
|
|
490
496
|
export function readTaskHistory(options = {}) {
|
|
491
|
-
|
|
492
|
-
try {
|
|
497
|
+
return withStateDb((db) => {
|
|
493
498
|
let rows;
|
|
494
499
|
if (options.id) {
|
|
495
500
|
const row = getTaskHistory(db, options.id);
|
|
@@ -503,10 +508,7 @@ export function readTaskHistory(options = {}) {
|
|
|
503
508
|
return rows.slice(0, options.limit);
|
|
504
509
|
}
|
|
505
510
|
return rows;
|
|
506
|
-
}
|
|
507
|
-
finally {
|
|
508
|
-
db.close();
|
|
509
|
-
}
|
|
511
|
+
});
|
|
510
512
|
}
|
|
511
513
|
/**
|
|
512
514
|
* Convert a `TaskHistoryRow` from state.db back to a `TaskRunResult` shape
|
|
File without changes
|
package/dist/wiki/wiki.js
CHANGED
|
@@ -58,6 +58,8 @@ export const SCHEMA_MD = "schema.md";
|
|
|
58
58
|
export const INDEX_MD = "index.md";
|
|
59
59
|
export const LOG_MD = "log.md";
|
|
60
60
|
export const RAW_SUBDIR = "raw";
|
|
61
|
+
/** Canonical location for agent-authored pages, mirroring RAW_SUBDIR. */
|
|
62
|
+
export const PAGES_SUBDIR = "pages";
|
|
61
63
|
/** Files at a wiki root that are not pages. */
|
|
62
64
|
const WIKI_SPECIAL_FILES = new Set([SCHEMA_MD, INDEX_MD, LOG_MD]);
|
|
63
65
|
const WIKI_NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
@@ -224,6 +226,43 @@ function readSchemaDescription(wikiDir) {
|
|
|
224
226
|
return undefined;
|
|
225
227
|
}
|
|
226
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* Load a wiki's `schema.md` body and frontmatter.
|
|
231
|
+
*
|
|
232
|
+
* Unlike {@link readSchemaDescription} (which returns only the frontmatter
|
|
233
|
+
* `description` for `listWikis` summaries), this returns the markdown **body**
|
|
234
|
+
* — everything after the closing `---` of the frontmatter — which is where the
|
|
235
|
+
* page contract, operations, and hard rules live. The body is the rulebook
|
|
236
|
+
* injected into the write-time prompt for wiki-page edits.
|
|
237
|
+
*
|
|
238
|
+
* Swallow-and-degrade like the existing reader: a missing file, an unresolvable
|
|
239
|
+
* wiki dir, or malformed content yields `{ body: "", frontmatter: {} }`. Never
|
|
240
|
+
* throws.
|
|
241
|
+
*/
|
|
242
|
+
export function loadWikiSchema(stashRoot, name) {
|
|
243
|
+
const empty = { body: "", frontmatter: {} };
|
|
244
|
+
let wikiDir;
|
|
245
|
+
try {
|
|
246
|
+
wikiDir = resolveWikiDir(stashRoot, name);
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
return empty;
|
|
250
|
+
}
|
|
251
|
+
let raw;
|
|
252
|
+
try {
|
|
253
|
+
raw = fs.readFileSync(path.join(wikiDir, SCHEMA_MD), "utf8");
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
return empty;
|
|
257
|
+
}
|
|
258
|
+
try {
|
|
259
|
+
const parsed = parseFrontmatter(raw);
|
|
260
|
+
return { body: parsed.content, frontmatter: parsed.data };
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
return empty;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
227
266
|
function toIsoDate(ms) {
|
|
228
267
|
return new Date(ms).toISOString();
|
|
229
268
|
}
|
|
@@ -369,18 +408,20 @@ export function createWiki(stashDir, name) {
|
|
|
369
408
|
fs.writeFileSync(absPath, content, "utf8");
|
|
370
409
|
created.push(absPath);
|
|
371
410
|
}
|
|
372
|
-
// Ensure raw/
|
|
373
|
-
// Handle the dir-exists-but-no-.gitkeep case too (partial scaffolds,
|
|
411
|
+
// Ensure raw/ and pages/ exist with a .gitkeep so empty wikis survive clean
|
|
412
|
+
// clones. Handle the dir-exists-but-no-.gitkeep case too (partial scaffolds,
|
|
374
413
|
// user-created directories) so the invariant always holds after `create`.
|
|
375
|
-
const
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
414
|
+
for (const subdir of [RAW_SUBDIR, PAGES_SUBDIR]) {
|
|
415
|
+
const dir = path.join(wikiDir, subdir);
|
|
416
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
417
|
+
const gitkeepPath = path.join(dir, ".gitkeep");
|
|
418
|
+
if (fs.existsSync(gitkeepPath)) {
|
|
419
|
+
skipped.push(gitkeepPath);
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
fs.writeFileSync(gitkeepPath, "", "utf8");
|
|
423
|
+
created.push(gitkeepPath);
|
|
424
|
+
}
|
|
384
425
|
}
|
|
385
426
|
return { name, ref: `wiki:${name}`, path: wikiDir, created, skipped };
|
|
386
427
|
}
|
package/dist/workflows/cli.js
CHANGED
package/dist/workflows/db.js
CHANGED
|
@@ -6,6 +6,7 @@ import path from "node:path";
|
|
|
6
6
|
import { getWorkflowDbPath } from "../core/paths.js";
|
|
7
7
|
import { openDatabase } from "../storage/database.js";
|
|
8
8
|
import { runMigrations as runSqliteMigrations } from "../storage/engines/sqlite-migrations.js";
|
|
9
|
+
import { applyStandardPragmas } from "../storage/sqlite-pragmas.js";
|
|
9
10
|
/**
|
|
10
11
|
* workflow.db — Durable SQLite database for workflow run state.
|
|
11
12
|
*
|
|
@@ -46,12 +47,10 @@ export function openWorkflowDatabase(dbPath = getWorkflowDbPath()) {
|
|
|
46
47
|
fs.mkdirSync(dir, { recursive: true });
|
|
47
48
|
}
|
|
48
49
|
const db = openDatabase(dbPath);
|
|
49
|
-
db.exec("PRAGMA journal_mode = WAL");
|
|
50
50
|
// #589: 30 s busy timeout, matching index.db / state.db. Without it the
|
|
51
51
|
// default is 0 ms, so any concurrent writer fails immediately with
|
|
52
|
-
// SQLITE_BUSY.
|
|
53
|
-
db
|
|
54
|
-
db.exec("PRAGMA foreign_keys = ON");
|
|
52
|
+
// SQLITE_BUSY. #628: journal_mode is configurable via AKM_SQLITE_JOURNAL_MODE.
|
|
53
|
+
applyStandardPragmas(db, { dataDir: dir });
|
|
55
54
|
ensureBaseSchema(db);
|
|
56
55
|
runMigrations(db);
|
|
57
56
|
return db;
|
|
@@ -2,23 +2,16 @@
|
|
|
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 { randomUUID } from "node:crypto";
|
|
5
|
-
import fs from "node:fs";
|
|
6
5
|
import { parseAssetRef } from "../../core/asset/asset-ref.js";
|
|
7
6
|
import { loadConfig } from "../../core/config/config.js";
|
|
8
7
|
import { NotFoundError, UsageError } from "../../core/errors.js";
|
|
9
8
|
import { appendEvent } from "../../core/events.js";
|
|
10
|
-
import { getDbPath } from "../../core/paths.js";
|
|
11
|
-
import { closeDatabase, openExistingDatabase } from "../../indexer/db/db.js";
|
|
12
|
-
import { resolveSourceEntries } from "../../indexer/search/search-source.js";
|
|
13
|
-
import { resolveSourcesForOrigin } from "../../registry/origin-resolve.js";
|
|
14
|
-
import { resolveAssetPath } from "../../sources/resolve.js";
|
|
15
9
|
import { withWorkflowRunsRepo, } from "../../storage/repositories/workflow-runs-repository.js";
|
|
16
|
-
import { formatWorkflowErrors } from "../authoring/authoring.js";
|
|
17
10
|
import { getCurrentWorkflowScopeKey } from "../authoring/scope-key.js";
|
|
18
|
-
import { parseWorkflow } from "../parser.js";
|
|
19
11
|
import { validateStepSummary } from "../validate-summary.js";
|
|
20
12
|
import { resolveAgentIdentity } from "./agent-identity.js";
|
|
21
13
|
import { evaluateCheckin } from "./checkin.js";
|
|
14
|
+
import { loadWorkflowAsset, resolveWorkflowEntryId } from "./workflow-asset-loader.js";
|
|
22
15
|
export async function startWorkflowRun(ref, params = {}, options) {
|
|
23
16
|
const asset = await loadWorkflowAsset(ref);
|
|
24
17
|
return withWorkflowRunsRepo(async (repo) => {
|
|
@@ -74,10 +67,15 @@ export async function startWorkflowRun(ref, params = {}, options) {
|
|
|
74
67
|
})));
|
|
75
68
|
});
|
|
76
69
|
const result = await getWorkflowStatus(runId);
|
|
70
|
+
// 07 P1-B: emit only the run id + status — NOT the raw workflowTitle (which
|
|
71
|
+
// comes verbatim from the workflow asset's frontmatter and is therefore
|
|
72
|
+
// attacker-influenceable). Keeping raw titles out of the events stream
|
|
73
|
+
// shrinks the injectable footprint for any consumer that re-surfaces events
|
|
74
|
+
// into agent context.
|
|
77
75
|
appendEvent({
|
|
78
76
|
eventType: "workflow_started",
|
|
79
77
|
ref: ref,
|
|
80
|
-
metadata: { runId: result.run.id,
|
|
78
|
+
metadata: { runId: result.run.id, status: result.run.status },
|
|
81
79
|
});
|
|
82
80
|
return result;
|
|
83
81
|
});
|
|
@@ -164,6 +162,42 @@ export async function resumeWorkflowRun(runId) {
|
|
|
164
162
|
return buildWorkflowRunDetail(updated, steps);
|
|
165
163
|
});
|
|
166
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Give up on a run (08-F6): flip it to `failed` so it stops counting as
|
|
167
|
+
* active — the run-level verb the concurrency-guard message in
|
|
168
|
+
* {@link startWorkflowRun} advertises. Terminal-state runs are refused;
|
|
169
|
+
* {@link resumeWorkflowRun} can reopen an abandoned run if it was a mistake.
|
|
170
|
+
*/
|
|
171
|
+
export async function abandonWorkflowRun(runId) {
|
|
172
|
+
return withWorkflowRunsRepo((repo) => {
|
|
173
|
+
const run = readWorkflowRun(repo, runId);
|
|
174
|
+
if (run.status === "completed" || run.status === "failed") {
|
|
175
|
+
throw new UsageError(`Workflow run ${run.id} is already ${run.status}.`);
|
|
176
|
+
}
|
|
177
|
+
const now = new Date().toISOString();
|
|
178
|
+
repo.updateRunState({
|
|
179
|
+
status: "failed",
|
|
180
|
+
currentStepId: run.current_step_id,
|
|
181
|
+
updatedAt: now,
|
|
182
|
+
completedAt: now,
|
|
183
|
+
checkinArmedAt: now,
|
|
184
|
+
runId: run.id,
|
|
185
|
+
});
|
|
186
|
+
const updated = {
|
|
187
|
+
...run,
|
|
188
|
+
status: "failed",
|
|
189
|
+
updated_at: now,
|
|
190
|
+
completed_at: now,
|
|
191
|
+
checkin_armed_at: now,
|
|
192
|
+
};
|
|
193
|
+
const steps = readWorkflowRunSteps(repo, run.id);
|
|
194
|
+
const detail = buildWorkflowRunDetail(updated, steps);
|
|
195
|
+
// Same injectable-footprint rule as workflow_started (07 P1-B): ids and
|
|
196
|
+
// status only, never the frontmatter-derived title.
|
|
197
|
+
appendEvent({ eventType: "workflow_abandoned", ref: run.workflow_ref, metadata: { runId: run.id } });
|
|
198
|
+
return detail;
|
|
199
|
+
});
|
|
200
|
+
}
|
|
167
201
|
export async function completeWorkflowStep(input) {
|
|
168
202
|
// Read the step (read-only) up front so the LLM validation gate runs OUTSIDE
|
|
169
203
|
// the write transaction — a slow/hung LLM must never hold a db write lock.
|
|
@@ -299,115 +333,6 @@ async function resolveRunSpecifier(repo, specifier, params) {
|
|
|
299
333
|
const started = await startWorkflowRun(ref, params ?? {});
|
|
300
334
|
return { run: readWorkflowRun(repo, started.run.id), autoStarted: true };
|
|
301
335
|
}
|
|
302
|
-
async function loadWorkflowAsset(ref) {
|
|
303
|
-
const parsed = parseAssetRef(ref);
|
|
304
|
-
if (parsed.type !== "workflow") {
|
|
305
|
-
throw new UsageError(`Expected a workflow ref (workflow:<name>), got "${ref}".`);
|
|
306
|
-
}
|
|
307
|
-
const config = loadConfig();
|
|
308
|
-
const allSources = resolveSourceEntries(undefined, config);
|
|
309
|
-
const searchSources = resolveSourcesForOrigin(parsed.origin, allSources);
|
|
310
|
-
let assetPath;
|
|
311
|
-
let sourcePath;
|
|
312
|
-
for (const source of searchSources) {
|
|
313
|
-
try {
|
|
314
|
-
assetPath = await resolveAssetPath(source.path, "workflow", parsed.name);
|
|
315
|
-
sourcePath = source.path;
|
|
316
|
-
break;
|
|
317
|
-
}
|
|
318
|
-
catch {
|
|
319
|
-
/* continue */
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
if (!assetPath) {
|
|
323
|
-
throw new NotFoundError(`Workflow not found for ref: workflow:${parsed.name}`);
|
|
324
|
-
}
|
|
325
|
-
const resolvedSourcePath = sourcePath ?? config.stashDir ?? assetPath;
|
|
326
|
-
const fullRef = `${parsed.origin ? `${parsed.origin}//` : ""}workflow:${parsed.name}`;
|
|
327
|
-
const cached = readWorkflowDocumentFromIndex(resolvedSourcePath, fullRef);
|
|
328
|
-
const document = cached ?? loadWorkflowDocumentFromDisk(assetPath);
|
|
329
|
-
return projectAsset(document, fullRef, assetPath, resolvedSourcePath);
|
|
330
|
-
}
|
|
331
|
-
function loadWorkflowDocumentFromDisk(assetPath) {
|
|
332
|
-
const content = fs.readFileSync(assetPath, "utf8");
|
|
333
|
-
const result = parseWorkflow(content, { path: assetPath });
|
|
334
|
-
if (!result.ok) {
|
|
335
|
-
throw new UsageError(formatWorkflowErrors(assetPath, result.errors));
|
|
336
|
-
}
|
|
337
|
-
return result.document;
|
|
338
|
-
}
|
|
339
|
-
function readWorkflowDocumentFromIndex(sourcePath, ref) {
|
|
340
|
-
const dbPath = getDbPath();
|
|
341
|
-
if (!fs.existsSync(dbPath))
|
|
342
|
-
return null;
|
|
343
|
-
const db = openExistingDatabase(dbPath);
|
|
344
|
-
try {
|
|
345
|
-
const parsed = parseAssetRef(ref);
|
|
346
|
-
const entryKey = `${sourcePath}:${parsed.type}:${parsed.name}`;
|
|
347
|
-
const row = db
|
|
348
|
-
.prepare(`SELECT wd.document_json AS document_json
|
|
349
|
-
FROM workflow_documents wd
|
|
350
|
-
JOIN entries e ON e.id = wd.entry_id
|
|
351
|
-
WHERE e.entry_type = 'workflow' AND e.entry_key = ?
|
|
352
|
-
LIMIT 1`)
|
|
353
|
-
.get(entryKey);
|
|
354
|
-
if (!row)
|
|
355
|
-
return null;
|
|
356
|
-
try {
|
|
357
|
-
return JSON.parse(row.document_json);
|
|
358
|
-
}
|
|
359
|
-
catch {
|
|
360
|
-
return null;
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
finally {
|
|
364
|
-
closeDatabase(db);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
function projectAsset(doc, ref, assetPath, sourcePath) {
|
|
368
|
-
return {
|
|
369
|
-
ref,
|
|
370
|
-
path: assetPath,
|
|
371
|
-
sourcePath,
|
|
372
|
-
title: doc.title,
|
|
373
|
-
...(doc.parameters
|
|
374
|
-
? {
|
|
375
|
-
parameters: doc.parameters.map((p) => ({
|
|
376
|
-
name: p.name,
|
|
377
|
-
...(p.description ? { description: p.description } : {}),
|
|
378
|
-
})),
|
|
379
|
-
}
|
|
380
|
-
: {}),
|
|
381
|
-
steps: doc.steps.map((s) => ({
|
|
382
|
-
id: s.id,
|
|
383
|
-
title: s.title,
|
|
384
|
-
instructions: s.instructions.text,
|
|
385
|
-
...(s.completionCriteria ? { completionCriteria: s.completionCriteria.map((c) => c.text) } : {}),
|
|
386
|
-
sequenceIndex: s.sequenceIndex,
|
|
387
|
-
})),
|
|
388
|
-
};
|
|
389
|
-
}
|
|
390
|
-
function resolveWorkflowEntryId(sourcePath, ref) {
|
|
391
|
-
const dbPath = getDbPath();
|
|
392
|
-
if (!fs.existsSync(dbPath))
|
|
393
|
-
return null;
|
|
394
|
-
const db = openExistingDatabase(dbPath);
|
|
395
|
-
try {
|
|
396
|
-
const parsed = parseAssetRef(ref);
|
|
397
|
-
const entryKey = `${sourcePath}:${parsed.type}:${parsed.name}`;
|
|
398
|
-
const row = db
|
|
399
|
-
.prepare(`SELECT id
|
|
400
|
-
FROM entries
|
|
401
|
-
WHERE entry_type = 'workflow'
|
|
402
|
-
AND entry_key = ?
|
|
403
|
-
LIMIT 1`)
|
|
404
|
-
.get(entryKey);
|
|
405
|
-
return row?.id ?? null;
|
|
406
|
-
}
|
|
407
|
-
finally {
|
|
408
|
-
closeDatabase(db);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
336
|
function readWorkflowRun(repo, runId) {
|
|
412
337
|
const run = repo.getRunById(runId);
|
|
413
338
|
if (!run) {
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
import { parseAssetRef } from "../../core/asset/asset-ref.js";
|
|
6
|
+
import { loadConfig } from "../../core/config/config.js";
|
|
7
|
+
import { NotFoundError, UsageError } from "../../core/errors.js";
|
|
8
|
+
import { getDbPath } from "../../core/paths.js";
|
|
9
|
+
import { resolveSourceEntries } from "../../indexer/search/search-source.js";
|
|
10
|
+
import { resolveSourcesForOrigin } from "../../registry/origin-resolve.js";
|
|
11
|
+
import { resolveAssetPath } from "../../sources/resolve.js";
|
|
12
|
+
import { withIndexDb } from "../../storage/repositories/index-db.js";
|
|
13
|
+
import { formatWorkflowErrors } from "../authoring/authoring.js";
|
|
14
|
+
import { parseWorkflow } from "../parser.js";
|
|
15
|
+
/**
|
|
16
|
+
* Resolve a `workflow:<name>` ref to a fully-projected {@link WorkflowAsset}.
|
|
17
|
+
*
|
|
18
|
+
* Prefers the parsed document cached in `index.db` (fast path) and falls back to
|
|
19
|
+
* reading + parsing the source file from disk. Pure loading/parsing concern —
|
|
20
|
+
* extracted from the run repository so run orchestration no longer owns asset
|
|
21
|
+
* resolution.
|
|
22
|
+
*/
|
|
23
|
+
export async function loadWorkflowAsset(ref) {
|
|
24
|
+
const parsed = parseAssetRef(ref);
|
|
25
|
+
if (parsed.type !== "workflow") {
|
|
26
|
+
throw new UsageError(`Expected a workflow ref (workflow:<name>), got "${ref}".`);
|
|
27
|
+
}
|
|
28
|
+
const config = loadConfig();
|
|
29
|
+
const allSources = resolveSourceEntries(undefined, config);
|
|
30
|
+
const searchSources = resolveSourcesForOrigin(parsed.origin, allSources);
|
|
31
|
+
let assetPath;
|
|
32
|
+
let sourcePath;
|
|
33
|
+
for (const source of searchSources) {
|
|
34
|
+
try {
|
|
35
|
+
assetPath = await resolveAssetPath(source.path, "workflow", parsed.name);
|
|
36
|
+
sourcePath = source.path;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
/* continue */
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (!assetPath) {
|
|
44
|
+
throw new NotFoundError(`Workflow not found for ref: workflow:${parsed.name}`);
|
|
45
|
+
}
|
|
46
|
+
const resolvedSourcePath = sourcePath ?? config.stashDir ?? assetPath;
|
|
47
|
+
const fullRef = `${parsed.origin ? `${parsed.origin}//` : ""}workflow:${parsed.name}`;
|
|
48
|
+
const cached = readWorkflowDocumentFromIndex(resolvedSourcePath, fullRef);
|
|
49
|
+
const document = cached ?? loadWorkflowDocumentFromDisk(assetPath);
|
|
50
|
+
return projectAsset(document, fullRef, assetPath, resolvedSourcePath);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Resolve the `entries.id` for an indexed workflow, or null when the index
|
|
54
|
+
* database does not yet exist or has no matching entry.
|
|
55
|
+
*/
|
|
56
|
+
export function resolveWorkflowEntryId(sourcePath, ref) {
|
|
57
|
+
if (!fs.existsSync(getDbPath()))
|
|
58
|
+
return null;
|
|
59
|
+
const parsed = parseAssetRef(ref);
|
|
60
|
+
const entryKey = `${sourcePath}:${parsed.type}:${parsed.name}`;
|
|
61
|
+
return withIndexDb((db) => {
|
|
62
|
+
const row = db
|
|
63
|
+
.prepare(`SELECT id
|
|
64
|
+
FROM entries
|
|
65
|
+
WHERE entry_type = 'workflow'
|
|
66
|
+
AND entry_key = ?
|
|
67
|
+
LIMIT 1`)
|
|
68
|
+
.get(entryKey);
|
|
69
|
+
return row?.id ?? null;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function loadWorkflowDocumentFromDisk(assetPath) {
|
|
73
|
+
const content = fs.readFileSync(assetPath, "utf8");
|
|
74
|
+
const result = parseWorkflow(content, { path: assetPath });
|
|
75
|
+
if (!result.ok) {
|
|
76
|
+
throw new UsageError(formatWorkflowErrors(assetPath, result.errors));
|
|
77
|
+
}
|
|
78
|
+
return result.document;
|
|
79
|
+
}
|
|
80
|
+
function readWorkflowDocumentFromIndex(sourcePath, ref) {
|
|
81
|
+
if (!fs.existsSync(getDbPath()))
|
|
82
|
+
return null;
|
|
83
|
+
const parsed = parseAssetRef(ref);
|
|
84
|
+
const entryKey = `${sourcePath}:${parsed.type}:${parsed.name}`;
|
|
85
|
+
return withIndexDb((db) => {
|
|
86
|
+
const row = db
|
|
87
|
+
.prepare(`SELECT wd.document_json AS document_json
|
|
88
|
+
FROM workflow_documents wd
|
|
89
|
+
JOIN entries e ON e.id = wd.entry_id
|
|
90
|
+
WHERE e.entry_type = 'workflow' AND e.entry_key = ?
|
|
91
|
+
LIMIT 1`)
|
|
92
|
+
.get(entryKey);
|
|
93
|
+
if (!row)
|
|
94
|
+
return null;
|
|
95
|
+
try {
|
|
96
|
+
return JSON.parse(row.document_json);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
function projectAsset(doc, ref, assetPath, sourcePath) {
|
|
104
|
+
return {
|
|
105
|
+
ref,
|
|
106
|
+
path: assetPath,
|
|
107
|
+
sourcePath,
|
|
108
|
+
title: doc.title,
|
|
109
|
+
...(doc.parameters
|
|
110
|
+
? {
|
|
111
|
+
parameters: doc.parameters.map((p) => ({
|
|
112
|
+
name: p.name,
|
|
113
|
+
...(p.description ? { description: p.description } : {}),
|
|
114
|
+
})),
|
|
115
|
+
}
|
|
116
|
+
: {}),
|
|
117
|
+
steps: doc.steps.map((s) => ({
|
|
118
|
+
id: s.id,
|
|
119
|
+
title: s.title,
|
|
120
|
+
instructions: s.instructions.text,
|
|
121
|
+
...(s.completionCriteria ? { completionCriteria: s.completionCriteria.map((c) => c.text) } : {}),
|
|
122
|
+
sequenceIndex: s.sequenceIndex,
|
|
123
|
+
})),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
@@ -16,14 +16,9 @@
|
|
|
16
16
|
*
|
|
17
17
|
* @module workflows/validate-summary
|
|
18
18
|
*/
|
|
19
|
+
import validateSummaryJudgePrompt from "../assets/prompts/validate-summary-judge.md" with { type: "text" };
|
|
19
20
|
import { parseJsonResponse } from "../core/parse.js";
|
|
20
|
-
const JUDGE_SYSTEM =
|
|
21
|
-
"Given a step's completion criteria and a summary of the work an agent claims to have done, " +
|
|
22
|
-
"judge whether the summary provides concrete evidence that EVERY criterion is satisfied. " +
|
|
23
|
-
"Be skeptical: vague, hand-wavy, or unsubstantiated claims do NOT satisfy a criterion. " +
|
|
24
|
-
'Respond with ONLY a JSON object: {"complete": boolean, "missing": string[], "feedback": string}. ' +
|
|
25
|
-
'"missing" lists the exact criteria that are not yet satisfied; "feedback" is a short directive ' +
|
|
26
|
-
"telling the agent what to finish or fix. No prose, no markdown fences.";
|
|
21
|
+
const JUDGE_SYSTEM = validateSummaryJudgePrompt;
|
|
27
22
|
function buildUserPrompt(input) {
|
|
28
23
|
const criteria = input.completionCriteria.map((c, i) => `${i + 1}. ${c}`).join("\n");
|
|
29
24
|
return [
|
package/docs/README.md
CHANGED
|
@@ -4,50 +4,101 @@
|
|
|
4
4
|
|
|
5
5
|
- [Concepts](concepts.md) -- Stashes, registries, asset types, and refs
|
|
6
6
|
- [Getting Started](getting-started.md) -- Quick setup guide
|
|
7
|
+
- [Local Development](local-development.md) -- Dogfooding akm while editing its own source
|
|
7
8
|
- [Agent Install Guide](agents/agent-install.md) -- Step-by-step automated install for agents
|
|
8
9
|
- [Stash Maker's Guide](stash-makers.md) -- Build and share a stash on GitHub, npm, or a network directory
|
|
9
10
|
- [Wikis](wikis.md) -- Multi-wiki knowledge bases (Karpathy-style)
|
|
10
11
|
|
|
12
|
+
## Configuration & Data
|
|
13
|
+
|
|
14
|
+
- [Configuration](configuration.md) -- Providers, settings, and Ollama setup
|
|
15
|
+
- [Configuring Agent Profiles](configuration-agent-profiles.md) -- How akm runs a coding agent, CLI or API
|
|
16
|
+
- [Data & Telemetry](data-and-telemetry.md) -- Exactly what akm reads and writes on your machine (no remote telemetry)
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
|
|
20
|
+
- [Workflows](features/workflows.md) -- Structured, resumable multi-step procedures
|
|
21
|
+
- [Search & Discovery](features/search-discovery.md) -- Finding assets without knowing their exact name
|
|
22
|
+
- [Knowledge Management](features/knowledge-management.md) -- Lessons, incidents, and research as first-class assets
|
|
23
|
+
- [Sources & Registries](features/sources-registries.md) -- Where assets come from and how to find more
|
|
24
|
+
- [Wiki Snapshot Fetchers](features/wiki-snapshot-fetchers.md) -- Pluggable fetchers for URL-based knowledge reads
|
|
25
|
+
- [Agent Integration](features/agent-integration.md) -- Wiring akm into any shell-capable coding agent
|
|
26
|
+
- [The Improvement Loop](features/improvement-loop.md) -- How the stash adapts from usage and feedback
|
|
27
|
+
|
|
11
28
|
## Upgrading
|
|
12
29
|
|
|
13
30
|
- [Roadmap](roadmap.md) -- High-level focus for the 0.9 and 1.0 releases
|
|
14
|
-
- [v1 migration guide](migration/v1.md) -- The path from 0.x to v1.0
|
|
15
|
-
- [
|
|
16
|
-
- [
|
|
31
|
+
- [v1 migration guide](migration/v1.md) -- The path from 0.x to v1.0
|
|
32
|
+
- [v0.8 -> v0.9 migration guide](migration/v0.8-to-v0.9.md) -- Current-cycle breaking changes
|
|
33
|
+
- [Release notes (latest: 0.9.0)](migration/release-notes/0.9.0.md) -- Per-release notes; see the [release-notes index](migration/release-notes/README.md) for every version
|
|
34
|
+
- [v0.5 -> v0.6 migration guide](migration/v0.5-to-v0.6.md) -- Every breaking change with before/after code, publisher checklist, and troubleshooting
|
|
17
35
|
|
|
18
36
|
## Reference
|
|
19
37
|
|
|
20
38
|
- [CLI](cli.md) -- All `akm` commands and flags
|
|
21
39
|
- [Registry](registry.md) -- Registries, search, hosting, and managing sources
|
|
22
|
-
- [
|
|
23
|
-
- [Filesystem](technical/filesystem.md) -- Directory layout plus `.stash.json` deprecation and migration notes
|
|
40
|
+
- [akm-eval](akm-eval.md) -- Standalone toolkit for measuring whether `akm improve` is working
|
|
24
41
|
|
|
25
|
-
##
|
|
42
|
+
## Agents
|
|
26
43
|
|
|
27
|
-
- [
|
|
28
|
-
- [
|
|
29
|
-
|
|
30
|
-
|
|
44
|
+
- [AGENTS.md](agents/AGENTS.md) -- The system-prompt reference agents load to use akm
|
|
45
|
+
- [Curate Workmap](agents/curate-workmap.md) -- Read before changing `akm curate` ranking or output
|
|
46
|
+
|
|
47
|
+
## Architecture
|
|
48
|
+
|
|
49
|
+
- [Architecture](technical/architecture.md) -- How akm's sources, cache, index, and registries fit together
|
|
50
|
+
- [Runtime Boundary Design](architecture/runtime-boundary-design.md) -- Isolating `bun:sqlite`/`Bun.*` from the core
|
|
51
|
+
- [Brain Workflow (diagram)](architecture/brain-workflow.html) -- Visual map of the improve/self-learning loop
|
|
52
|
+
|
|
53
|
+
## Example Stash
|
|
54
|
+
|
|
55
|
+
- [Example Stash](example-stash/README.md) -- A documentation-backed example stash showing how asset types fit together
|
|
56
|
+
|
|
57
|
+
## Analysis
|
|
31
58
|
|
|
32
|
-
|
|
59
|
+
- [Indexer Vertical Slice Refactor Plan](analysis/indexer-vertical-slice-refactor-plan.md)
|
|
60
|
+
- [Indexer Refactor Review (Expert Options)](analysis/indexer-refactor-expert-options.md)
|
|
33
61
|
|
|
34
|
-
|
|
62
|
+
## Design (unshipped work)
|
|
35
63
|
|
|
36
|
-
|
|
64
|
+
- [Self-Improvement, Self-Learning & Memory Reference Index](design/self-improvement-learning-memory-reference-index.md) -- Master index for every unshipped improve/self-learning/memory design doc, with a subsystem-to-doc status table
|
|
37
65
|
|
|
66
|
+
Every doc under `docs/design/` must carry a `Status` / `Supersedes` / `Date` header (pre-existing docs are grandfathered until next touched). When a design ships, the shipping PR moves it to `docs/archive/` in the same PR.
|
|
67
|
+
|
|
68
|
+
## Archive
|
|
69
|
+
|
|
70
|
+
- [Archive](archive/README.md) -- Design and implementation plans whose work has already shipped, retained as ADR-style records
|
|
71
|
+
|
|
72
|
+
## Internals (technical/)
|
|
73
|
+
|
|
74
|
+
- [Filesystem](technical/filesystem.md) -- Directory layout plus `.stash.json` deprecation and migration notes
|
|
38
75
|
- [Search](technical/search.md) -- Hybrid search architecture and scoring
|
|
39
76
|
- [Indexing](technical/indexing.md) -- How the search index is built
|
|
40
77
|
- [Classification](technical/classification.md) -- Matcher and renderer behavior
|
|
78
|
+
- [Storage Locations](technical/storage-locations.md) -- Authoritative inventory of every on-disk read/write path
|
|
79
|
+
- [Improve Workflow](technical/improve-workflow.md) -- `akm improve` command surface and pipeline reference
|
|
80
|
+
- [Health Advisories](technical/health-advisories.md) -- `akm health` advisory-to-action map for operators
|
|
81
|
+
- [Fresh-Host Rebuild Runbook](technical/fresh-host-rebuild-runbook.md) -- Rebuild an akm install on a new machine
|
|
82
|
+
- [Ranking Ablation & Saturation Analysis](technical/ranking-ablation-and-saturation-analysis.md) -- Reproducible contributor-ablation measurement and the score-saturation trap
|
|
41
83
|
- [Functional Contract Patterns](technical/functional-contract-patterns.md) -- Quick reference for contributor pipelines and small process contracts
|
|
42
|
-
- [
|
|
43
|
-
- [Architecture Cleanup Checklist](technical/architecture-cleanup-checklist.md) -- Living checklist for executing the cleanup plan with parity gates, reviews, and git hygiene
|
|
44
|
-
- [Show Response](technical/show-response.md) -- `akm show` output fields by asset type
|
|
84
|
+
- [Test Coverage Guide](technical/test-coverage-guide.md) -- High-value testing areas
|
|
45
85
|
- [Testing Workflow](technical/testing-workflow.md) -- End-to-end, Docker, deployment, and upgrade validation
|
|
46
86
|
- [Ref Format](technical/ref.md) -- Wire format for asset references
|
|
47
|
-
- [Test Coverage Guide](technical/test-coverage-guide.md) -- High-value testing areas
|
|
48
87
|
- [Core Principles](technical/akm-core-principles.md) -- Design principles and constraints
|
|
49
|
-
-
|
|
88
|
+
- [Claude Code workflows vs. akm workflows](technical/claude-code-vs-akm-workflows.md) -- Comparing the two things that share a name
|
|
89
|
+
- [Extending akm workflows into a harness-agnostic orchestration engine](technical/akm-workflows-orchestration-plan.md) -- Current formalized plan, supersedes part of the doc above
|
|
90
|
+
|
|
91
|
+
## Official Ecosystem Repositories
|
|
92
|
+
|
|
93
|
+
- [itlackey/akm-stash](https://github.com/itlackey/akm-stash) -- the official onboarding stash with ready-made assets you can install with `akm add`
|
|
94
|
+
- [itlackey/akm-registry](https://github.com/itlackey/akm-registry) -- the official registry index that powers built-in discovery
|
|
95
|
+
- [itlackey/akm-plugins](https://github.com/itlackey/akm-plugins) -- optional integrations for tools like OpenCode
|
|
96
|
+
- [itlackey/akm-bench](https://github.com/itlackey/akm-bench) -- the standalone benchmark and evaluation repo for akm
|
|
50
97
|
|
|
51
98
|
## Posts
|
|
52
99
|
|
|
53
100
|
- [Blog posts](posts/) -- Articles and posts about akm
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
New docs, in five lines: keep one current-truth doc per subsystem, don't fork a second one. Unshipped designs live in `docs/design/` with a mandatory `Status` / `Supersedes` / `Date` header. The PR that ships the design moves its doc to `docs/archive/` in that same PR. Cite code by symbol and memories by search-terms -- not line numbers or exact refs, both rot. Nothing in `docs/` may reference `.plans/` (it's scratch -- promote the content or drop the link); no new improve-analysis docs until the 30-clean-day gate.
|