akm-cli 0.9.0-rc.0 → 0.9.0-rc.13
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 +1283 -22
- package/README.md +62 -37
- package/SECURITY.md +46 -31
- package/dist/akm +162 -38
- package/dist/akm-migrate +44 -0
- package/dist/assets/backends/schtasks-template.xml +2 -1
- package/dist/assets/hints/cli-hints-full.md +268 -118
- package/dist/assets/hints/cli-hints-short.md +87 -24
- package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
- package/dist/assets/improve-strategies/frequent.json +15 -0
- package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
- package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
- package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
- package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
- package/dist/assets/improve-strategies/reflect-distill.json +30 -0
- package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
- package/dist/assets/prompts/consolidate-system.md +5 -5
- package/dist/assets/prompts/extract-session.md +2 -6
- package/dist/assets/prompts/memory-infer-user.md +2 -3
- package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
- package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
- package/dist/assets/prompts/reflect-output-repair.md +3 -0
- package/dist/assets/prompts/workflow-unit-preamble.md +26 -0
- package/dist/assets/stash-skeleton/README.md +38 -10
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
- package/dist/assets/tasks/core/extract.yml +3 -2
- package/dist/assets/tasks/core/improve.yml +2 -1
- package/dist/assets/tasks/core/index-refresh.yml +1 -0
- package/dist/assets/tasks/core/sync.yml +1 -0
- package/dist/assets/tasks/core/version-check.yml +2 -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 +5 -4
- package/dist/assets/workflows/workflow-template.md +31 -15
- package/dist/cli/invocation.js +279 -0
- package/dist/cli/parse-args.js +5 -90
- package/dist/cli/retired-commands.js +78 -0
- package/dist/cli/shared.js +158 -48
- package/dist/cli-node.mjs +2 -1
- package/dist/cli.js +747 -293
- package/dist/commands/agent/agent-dispatch.js +19 -18
- package/dist/commands/agent/agent-support.js +0 -24
- package/dist/commands/agent/contribute-cli.js +43 -97
- package/dist/commands/completions.js +80 -23
- package/dist/commands/config-cli.js +44 -281
- package/dist/commands/env/env-binding.js +99 -0
- package/dist/commands/env/env-cli.js +84 -224
- package/dist/commands/env/env.js +12 -163
- package/dist/commands/env/marker-path.js +6 -0
- package/dist/commands/env/secret-cli.js +45 -61
- package/dist/commands/env/secret.js +32 -62
- package/dist/commands/feedback-cli.js +179 -85
- package/dist/commands/health/accept-rate.js +58 -0
- package/dist/commands/health/advisories.js +7 -8
- package/dist/commands/health/checks.js +279 -94
- package/dist/commands/health/html-report.js +197 -578
- package/dist/commands/health/improve-metrics.js +277 -246
- package/dist/commands/health/llm-usage.js +19 -19
- package/dist/commands/health/md-report.js +16 -7
- package/dist/commands/health/metrics.js +67 -32
- package/dist/commands/health/renderers.js +47 -0
- package/dist/commands/health/report-view-model.js +508 -0
- package/dist/commands/health/stash-exposure.js +1 -1
- package/dist/commands/health/surfaces.js +16 -56
- package/dist/commands/health/task-runs.js +3 -67
- package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
- package/dist/commands/health/types-improve.js +29 -0
- package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
- package/dist/commands/health/types-result.js +7 -0
- package/dist/commands/health/types-runs.js +4 -0
- package/dist/commands/health/types-session-log.js +4 -0
- package/dist/commands/health/types-windows.js +4 -0
- package/dist/commands/health/types.js +26 -21
- package/dist/commands/health/windows.js +2 -3
- package/dist/commands/health.js +296 -167
- package/dist/commands/improve/anti-collapse.js +5 -5
- package/dist/commands/improve/autonomy-gate.js +68 -0
- package/dist/commands/improve/collapse-detector.js +65 -52
- package/dist/commands/improve/consolidate/chunking.js +9 -7
- package/dist/commands/improve/consolidate/eligibility.js +1 -23
- package/dist/commands/improve/consolidate/merge.js +4 -0
- package/dist/commands/improve/consolidate.js +454 -1354
- package/dist/commands/improve/content-hash.js +39 -0
- package/dist/commands/improve/distill/content-repair.js +4 -10
- package/dist/commands/improve/distill/promote-memory.js +89 -64
- package/dist/commands/improve/distill/quality-gate.js +118 -42
- package/dist/commands/improve/distill-guards.js +1 -1
- package/dist/commands/improve/distill-promotion-policy.js +33 -888
- package/dist/commands/improve/distill.js +607 -363
- package/dist/commands/improve/eligibility.js +165 -79
- package/dist/commands/improve/extract-cli.js +35 -126
- package/dist/commands/improve/extract-prompt.js +6 -35
- package/dist/commands/improve/extract.js +640 -391
- package/dist/commands/improve/feedback-valence.js +2 -12
- package/dist/commands/improve/improve-cli.js +134 -135
- package/dist/commands/improve/improve-result-file.js +30 -50
- package/dist/commands/improve/improve-run-types.js +4 -0
- package/dist/commands/improve/improve-strategies.js +135 -0
- package/dist/commands/improve/improve.js +904 -701
- package/dist/commands/improve/locks.js +64 -111
- package/dist/commands/improve/loop-stages.js +1110 -923
- package/dist/commands/improve/memory/derived-ref.js +124 -0
- package/dist/commands/improve/memory/memory-belief.js +79 -7
- package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
- package/dist/commands/improve/memory/memory-improve.js +25 -37
- package/dist/commands/improve/outcome-loop.js +25 -88
- package/dist/commands/improve/preparation.js +1034 -813
- package/dist/commands/improve/proactive-maintenance.js +34 -9
- package/dist/commands/improve/proposal-envelope.js +31 -0
- package/dist/commands/improve/reflect.js +983 -794
- package/dist/commands/improve/run-context.js +119 -0
- package/dist/commands/improve/salience.js +24 -127
- package/dist/commands/improve/session-asset.js +7 -3
- package/dist/commands/improve/shared.js +14 -34
- package/dist/commands/improve/source-identity.js +28 -0
- package/dist/commands/improve/triage.js +20 -17
- package/dist/commands/lint/base-linter.js +340 -313
- package/dist/commands/lint/env-key-rules.js +31 -47
- package/dist/commands/lint/index.js +185 -30
- package/dist/commands/{events.js → log.js} +28 -38
- package/dist/commands/migrate-cli.js +54 -0
- package/dist/commands/migration-tool.js +55 -0
- package/dist/commands/observability-cli.js +70 -208
- package/dist/commands/proposal/diff-format.js +50 -0
- package/dist/commands/proposal/drain-policies.js +0 -6
- package/dist/commands/proposal/drain.js +91 -40
- package/dist/commands/proposal/proposal-cli.js +134 -132
- package/dist/commands/proposal/proposal-types.js +56 -0
- package/dist/commands/proposal/proposal.js +83 -65
- package/dist/commands/proposal/propose-cli.js +88 -0
- package/dist/commands/proposal/propose.js +105 -88
- package/dist/commands/proposal/repository.js +1303 -278
- package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
- package/dist/commands/proposal/validators/proposal-validators.js +61 -12
- package/dist/commands/proposal/validators/proposals.js +6 -8
- package/dist/commands/read/curate.js +78 -73
- package/dist/commands/read/knowledge.js +510 -13
- package/dist/commands/read/registry-search.js +2 -2
- package/dist/commands/read/remember-cli.js +84 -15
- package/dist/commands/read/search-cli.js +203 -96
- package/dist/commands/read/search.js +126 -94
- package/dist/commands/read/show.js +226 -250
- package/dist/commands/registry-cli.js +34 -60
- package/dist/commands/remember.js +18 -57
- package/dist/commands/sources/add-cli.js +104 -49
- package/dist/commands/sources/bundle-cli.js +166 -0
- package/dist/commands/sources/bundle-config-ops.js +63 -0
- package/dist/commands/sources/info.js +27 -15
- package/dist/commands/sources/init.js +30 -40
- package/dist/commands/sources/installed-stashes.js +469 -172
- package/dist/commands/sources/migration-help.js +7 -4
- package/dist/commands/sources/schema-repair.js +10 -9
- package/dist/commands/sources/self-update.js +182 -121
- package/dist/commands/sources/source-add.js +169 -178
- package/dist/commands/sources/source-clone.js +144 -41
- package/dist/commands/sources/source-manage.js +94 -59
- package/dist/commands/sources/sources-cli.js +64 -205
- package/dist/commands/sources/stash-cli.js +91 -54
- package/dist/commands/sources/stash-skeleton.js +1 -1
- package/dist/commands/tasks/tasks-cli.js +106 -104
- package/dist/commands/tasks/tasks.js +445 -262
- package/dist/commands/workflow-cli.js +232 -121
- package/dist/core/action-contributors.js +1 -1
- package/dist/core/activation-policy.js +49 -0
- package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
- package/dist/core/adapter/adapters/akm-adapter.js +528 -0
- package/dist/core/adapter/adapters/akm-lint.js +392 -0
- package/dist/core/adapter/adapters/akm-metadata.js +387 -0
- package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
- package/dist/core/adapter/adapters/claude-adapter.js +61 -0
- package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
- package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
- package/dist/core/adapter/adapters/index.js +80 -0
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
- package/dist/core/adapter/adapters/okf-adapter.js +391 -0
- package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
- package/dist/core/adapter/adapters/shared.js +286 -0
- package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
- package/dist/core/adapter/bundle-adapter.js +4 -0
- package/dist/core/adapter/detect-adapter.js +17 -0
- package/dist/core/adapter/recognize-match.js +44 -0
- package/dist/core/adapter/registry.js +56 -0
- package/dist/core/adapter/types.js +4 -0
- package/dist/core/asset/akm-markdown.js +30 -0
- package/dist/core/asset/asset-placement.js +243 -0
- package/dist/core/asset/asset-ref.js +110 -79
- package/dist/core/asset/asset-serialize.js +20 -0
- package/dist/core/asset/frontmatter.js +28 -12
- package/dist/core/asset/markdown.js +40 -51
- package/dist/core/asset/resolve-ref.js +274 -0
- package/dist/core/asset/stash-meta.js +2 -2
- package/dist/core/bundle-id.js +51 -0
- package/dist/core/common.js +281 -86
- package/dist/core/config/config-io.js +42 -128
- package/dist/core/config/config-schema.js +233 -834
- package/dist/core/config/config-sources.js +162 -39
- package/dist/core/config/config-types.js +16 -11
- package/dist/core/config/config-version.js +29 -0
- package/dist/core/config/config-walker.js +126 -37
- package/dist/core/config/config.js +154 -331
- package/dist/core/config/deep-merge.js +41 -0
- package/dist/core/config/engine-semantics.js +28 -0
- package/dist/core/config/experimental.js +21 -0
- package/dist/core/config/schema/embedding.js +38 -0
- package/dist/core/config/schema/engines.js +116 -0
- package/dist/core/config/schema/experimental.js +47 -0
- package/dist/core/config/schema/feedback.js +31 -0
- package/dist/core/config/schema/improve-processes.js +389 -0
- package/dist/core/config/schema/improve.js +94 -0
- package/dist/core/config/schema/index-config.js +176 -0
- package/dist/core/config/schema/output.js +18 -0
- package/dist/core/config/schema/primitives.js +94 -0
- package/dist/core/config/schema/search.js +30 -0
- package/dist/core/config/schema/setup.js +18 -0
- package/dist/core/config/schema/sources-bundles.js +169 -0
- package/dist/core/config/schema/workflow.js +29 -0
- package/dist/core/env-secret-ref.js +155 -20
- package/dist/core/errors.js +17 -15
- package/dist/core/events-types.js +4 -0
- package/dist/core/events.js +46 -128
- package/dist/core/extra-params.js +62 -0
- package/dist/core/file-change.js +17 -0
- package/dist/core/file-lock.js +202 -57
- package/dist/core/fs-txn.js +392 -0
- package/dist/core/git-message.js +59 -0
- package/dist/core/improve-result.js +167 -0
- package/dist/core/json-schema.js +142 -0
- package/dist/core/lesson-lint.js +1 -17
- package/dist/core/logs-db.js +1 -1
- package/dist/core/maintenance-barrier.js +135 -0
- package/dist/core/migration-operation.js +44 -0
- package/dist/core/mutation-target.js +78 -0
- package/dist/core/paths.js +22 -25
- package/dist/core/platform.js +10 -0
- package/dist/core/recognition-util.js +128 -0
- package/dist/core/redaction.js +392 -0
- package/dist/core/standards/resolve-standards-context.js +36 -65
- package/dist/core/standards/resolve-stash-standards.js +2 -2
- package/dist/core/standards/resolve-type-conventions.js +5 -5
- package/dist/core/state/migrations.js +242 -11
- package/dist/core/state-db.js +98 -10
- package/dist/core/structured.js +1 -1
- package/dist/core/subprocess.js +303 -0
- package/dist/core/text-truncation.js +9 -5
- package/dist/core/time.js +20 -0
- package/dist/core/type-presentation.js +130 -0
- package/dist/core/warn.js +0 -3
- package/dist/core/write-source.js +834 -118
- package/dist/indexer/bundle-identity-guard.js +92 -0
- package/dist/indexer/db/graph-db.js +1 -25
- package/dist/indexer/db/llm-cache.js +1 -1
- package/dist/indexer/ensure-index.js +30 -9
- package/dist/indexer/graph/graph-boost.js +9 -30
- package/dist/indexer/graph/graph-extraction.js +41 -27
- package/dist/indexer/graph/graph-types.js +4 -0
- package/dist/indexer/index-writer-lock.js +93 -49
- package/dist/indexer/index-written-assets.js +100 -53
- package/dist/indexer/indexer.js +746 -329
- package/dist/indexer/init.js +18 -25
- package/dist/indexer/installations.js +142 -0
- package/dist/indexer/passes/dir-staleness.js +18 -10
- package/dist/indexer/passes/memory-inference.js +25 -15
- package/dist/indexer/passes/metadata.js +412 -243
- package/dist/indexer/scan/doc-to-entry.js +160 -0
- package/dist/indexer/scan/drain-dir.js +134 -0
- package/dist/indexer/search/db-search.js +292 -108
- package/dist/indexer/search/fts-query.js +64 -0
- package/dist/indexer/search/ranking-contributors.js +145 -25
- package/dist/indexer/search/ranking-types.js +4 -0
- package/dist/indexer/search/ranking.js +28 -71
- package/dist/indexer/search/search-attribution.js +67 -0
- package/dist/indexer/search/search-fields.js +18 -3
- package/dist/indexer/search/search-hit-enrichers.js +30 -40
- package/dist/indexer/search/search-source.js +157 -111
- package/dist/indexer/search/semantic-status.js +4 -1
- package/dist/indexer/usage/usage-events.js +10 -30
- package/dist/indexer/walk/file-context.js +3 -45
- package/dist/indexer/walk/matchers.js +42 -34
- package/dist/indexer/walk/path-resolver.js +11 -5
- package/dist/indexer/walk/walker.js +42 -14
- package/dist/integrations/agent/builder-shared.js +7 -0
- package/dist/integrations/agent/builders.js +5 -56
- package/dist/integrations/agent/config.js +3 -143
- package/dist/integrations/agent/detect.js +17 -2
- package/dist/integrations/agent/engine-resolution.js +231 -0
- package/dist/integrations/agent/index.js +1 -2
- package/dist/integrations/agent/model-aliases.js +16 -2
- package/dist/integrations/agent/profiles.js +36 -62
- package/dist/integrations/agent/prompts.js +46 -18
- package/dist/integrations/agent/runner-dispatch.js +93 -4
- package/dist/integrations/agent/runner.js +76 -208
- package/dist/integrations/agent/spawn.js +88 -196
- package/dist/integrations/harnesses/aider/agent-builder.js +114 -0
- package/dist/integrations/harnesses/aider/index.js +48 -0
- package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
- package/dist/integrations/harnesses/amazonq/agent-builder.js +147 -0
- package/dist/integrations/harnesses/amazonq/index.js +45 -0
- package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
- package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
- package/dist/integrations/harnesses/claude/config-import.js +1 -3
- package/dist/integrations/harnesses/claude/index.js +24 -35
- package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
- package/dist/integrations/harnesses/claude/session-log.js +27 -75
- package/dist/integrations/harnesses/codex/agent-builder.js +138 -0
- package/dist/integrations/harnesses/codex/index.js +52 -0
- package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
- package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
- package/dist/integrations/harnesses/copilot/index.js +48 -0
- package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
- package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
- package/dist/integrations/harnesses/gemini/index.js +48 -0
- package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
- package/dist/integrations/harnesses/ids.js +24 -0
- package/dist/integrations/harnesses/index.js +54 -34
- package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
- package/dist/integrations/harnesses/opencode/config-import.js +1 -3
- package/dist/integrations/harnesses/opencode/index.js +14 -32
- package/dist/integrations/harnesses/opencode/session-log.js +67 -125
- package/dist/integrations/harnesses/opencode-sdk/harness.js +51 -0
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
- package/dist/integrations/harnesses/openhands/agent-builder.js +128 -0
- package/dist/integrations/harnesses/openhands/index.js +48 -0
- package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
- package/dist/integrations/harnesses/pi/agent-builder.js +97 -0
- package/dist/integrations/harnesses/pi/index.js +45 -0
- package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
- package/dist/integrations/harnesses/shared.js +17 -0
- package/dist/integrations/harnesses/types.js +43 -32
- package/dist/integrations/lockfile.js +211 -24
- package/dist/integrations/session-logs/index.js +36 -39
- package/dist/integrations/session-logs/provider-base.js +113 -0
- package/dist/llm/client.js +182 -110
- package/dist/llm/embedders/deterministic.js +2 -2
- package/dist/llm/embedders/remote.js +21 -9
- package/dist/llm/feature-gate.js +17 -57
- package/dist/llm/graph-extract.js +12 -13
- package/dist/llm/index-passes.js +8 -42
- package/dist/llm/memory-infer.js +144 -1
- package/dist/llm/metadata-enhance.js +45 -30
- package/dist/llm/structured-call.js +16 -8
- package/dist/llm/usage-persist.js +30 -5
- package/dist/llm/usage-telemetry.js +59 -6
- package/dist/output/cli-hints.js +1 -2
- package/dist/output/command-registry.js +27 -0
- package/dist/output/context.js +22 -7
- package/dist/output/format-exempt.js +80 -0
- package/dist/output/generic-render.js +251 -0
- package/dist/output/html-render.js +11 -16
- package/dist/output/render-registry.js +57 -0
- package/dist/output/renderers.js +14 -279
- package/dist/output/shapes/curate.js +10 -1
- package/dist/output/shapes/events.js +12 -7
- package/dist/output/shapes/helpers.js +58 -84
- package/dist/output/shapes/passthrough.js +11 -39
- package/dist/output/shapes/proposal/producer.js +15 -7
- package/dist/output/shapes/registry.js +12 -6
- package/dist/output/shapes.js +0 -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 +562 -0
- package/dist/output/text/env.js +1 -3
- package/dist/output/text/events.js +8 -7
- package/dist/output/text/helpers.js +15 -1164
- package/dist/output/text/proposal/producer.js +4 -2
- package/dist/output/text/proposal-format.js +202 -0
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/registry.js +12 -6
- package/dist/output/text/show-directives.js +117 -0
- package/dist/output/text/show-format.js +103 -0
- package/dist/output/text/sync.js +5 -0
- package/dist/output/text/workflow-format.js +332 -0
- package/dist/output/text/workflow.js +3 -2
- package/dist/output/text.js +10 -19
- 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 +15 -25
- package/dist/registry/resolve.js +43 -94
- package/dist/registry/semver.js +43 -0
- package/dist/runtime.js +81 -12
- package/dist/scripts/akm-migrate.js +35529 -0
- package/dist/setup/detect.js +5 -7
- package/dist/setup/detected-engines.js +136 -0
- package/dist/setup/engine-config.js +100 -0
- package/dist/setup/registry-stash-loader.js +3 -3
- package/dist/setup/semantic-assets.js +12 -9
- package/dist/setup/setup.js +444 -208
- package/dist/setup/steps/connection-shared.js +120 -0
- package/dist/setup/steps/connection.js +108 -305
- package/dist/setup/steps/platforms.js +13 -12
- package/dist/setup/steps/semantic.js +15 -3
- package/dist/setup/steps/sources.js +21 -15
- package/dist/setup/steps/stashdir.js +6 -4
- package/dist/setup/steps/tasks.js +236 -119
- package/dist/setup/steps.js +3 -2
- package/dist/sources/freshness.js +39 -0
- 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 +54 -56
- package/dist/sources/providers/git-stash.js +420 -91
- package/dist/sources/providers/git.js +2 -2
- package/dist/sources/providers/npm.js +16 -19
- package/dist/sources/providers/provider-utils.js +47 -22
- package/dist/sources/providers/sync-from-ref.js +3 -9
- package/dist/sources/providers/website.js +2 -2
- package/dist/sources/resolve.js +11 -10
- package/dist/sources/snapshot-fetchers/types.js +4 -0
- package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
- package/dist/storage/database.js +60 -4
- package/dist/storage/engines/sqlite-migrations.js +156 -5
- package/dist/storage/locations.js +1 -2
- package/dist/storage/repositories/canaries-repository.js +1 -1
- package/dist/storage/repositories/events-repository.js +51 -11
- package/dist/storage/repositories/improve-runs-repository.js +6 -32
- package/dist/storage/repositories/index-connection.js +79 -0
- package/dist/storage/repositories/index-db.js +4 -3
- package/dist/storage/repositories/index-entries-repository.js +863 -0
- package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
- package/dist/storage/repositories/index-entry-types.js +4 -0
- package/dist/storage/repositories/index-fts-repository.js +167 -0
- package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
- package/dist/storage/repositories/index-meta-repository.js +49 -0
- package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
- package/dist/storage/repositories/index-sql.js +12 -0
- package/dist/storage/repositories/index-utility-repository.js +356 -0
- package/dist/storage/repositories/index-vec-repository.js +250 -0
- package/dist/storage/repositories/outcome-repository.js +119 -0
- package/dist/storage/repositories/proposals-repository.js +317 -75
- package/dist/storage/repositories/registry-cache.js +1 -1
- package/dist/storage/repositories/salience-repository.js +172 -0
- package/dist/storage/repositories/task-history-repository.js +110 -3
- package/dist/storage/repositories/workflow-runs-repository.js +240 -19
- package/dist/tasks/backends/cron.js +169 -46
- package/dist/tasks/backends/exec-utils.js +76 -3
- package/dist/tasks/backends/index.js +6 -9
- package/dist/tasks/backends/launchd.js +292 -55
- package/dist/tasks/backends/schtasks.js +557 -70
- package/dist/tasks/backends/types.js +4 -0
- package/dist/tasks/command-executable.js +93 -0
- package/dist/tasks/embedded.js +56 -38
- package/dist/tasks/parser.js +156 -64
- package/dist/tasks/resolve-akm-bin.js +144 -51
- package/dist/tasks/runner.js +377 -209
- package/dist/tasks/schedule.js +108 -19
- package/dist/tasks/scheduler-invocation.js +296 -0
- package/dist/tasks/schema.js +1 -1
- package/dist/tasks/task-id.js +35 -0
- package/dist/tasks/validator.js +30 -16
- package/dist/text-import-hook.mjs +1 -1
- package/dist/workflows/authoring/authoring.js +104 -43
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/cli.js +0 -16
- package/dist/workflows/concurrency-policy.js +15 -0
- package/dist/workflows/exec/brief.js +450 -0
- package/dist/workflows/exec/frozen-judge.js +47 -0
- package/dist/workflows/exec/native-executor.js +1038 -0
- package/dist/workflows/exec/param-secrets.js +115 -0
- package/dist/workflows/exec/report.js +1460 -0
- package/dist/workflows/exec/run-workflow.js +602 -0
- package/dist/workflows/exec/scheduler.js +71 -0
- package/dist/workflows/exec/step-work.js +1190 -0
- package/dist/workflows/exec/unit-writer.js +23 -0
- package/dist/workflows/exec/workflow-engine-gate.js +67 -0
- package/dist/workflows/exec/worktree.js +171 -0
- package/dist/workflows/ir/compile.js +246 -0
- package/dist/workflows/ir/freeze.js +233 -0
- package/dist/workflows/ir/params.js +54 -0
- package/dist/workflows/ir/plan-hash.js +68 -0
- package/dist/workflows/ir/schema.js +540 -0
- package/dist/workflows/parser.js +878 -304
- package/dist/workflows/program/expressions.js +181 -0
- package/dist/workflows/program/schema.js +51 -0
- package/dist/workflows/renderer.js +100 -45
- package/dist/workflows/resource-limits.js +22 -0
- package/dist/workflows/runtime/agent-identity.js +59 -14
- package/dist/workflows/runtime/checkin.js +1 -1
- package/dist/workflows/runtime/plan-classifier.js +131 -0
- package/dist/workflows/runtime/runs.js +376 -119
- package/dist/workflows/runtime/unit-checkin.js +45 -0
- package/dist/workflows/runtime/unit-phases.js +20 -0
- package/dist/workflows/runtime/workflow-asset-loader.js +241 -40
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +2 -3
- package/dist/workflows/validator.js +52 -30
- package/docs/README.md +42 -78
- package/docs/migration/README.md +8 -0
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +9 -8
- package/docs/migration/release-notes/0.9.0.md +158 -14
- package/docs/migration/v0.7-to-v0.8.md +46 -47
- package/docs/migration/v0.8-to-v0.9.md +844 -0
- package/docs/reference/README.md +12 -0
- package/docs/reference/data-and-telemetry.md +333 -0
- package/package.json +21 -17
- package/schemas/akm-asset-envelope.json +93 -0
- package/schemas/akm-config.json +4636 -0
- package/schemas/akm-task.json +87 -0
- package/schemas/akm-workflow.json +373 -0
- package/dist/akm-migrate-storage +0 -38
- package/dist/assets/help/help-accept.md +0 -12
- package/dist/assets/help/help-improve.md +0 -84
- package/dist/assets/help/help-proposals.md +0 -17
- package/dist/assets/help/help-propose.md +0 -17
- package/dist/assets/help/help-reject.md +0 -11
- package/dist/assets/profiles/frequent.json +0 -13
- package/dist/assets/profiles/recombine-only.json +0 -21
- package/dist/assets/profiles/reflect-distill.json +0 -30
- package/dist/assets/profiles/synthesize.json +0 -15
- package/dist/assets/prompts/procedural-system.md +0 -44
- package/dist/assets/prompts/recombine-system.md +0 -40
- package/dist/assets/prompts/staleness-detect-system.md +0 -6
- package/dist/assets/tasks/core/backup.yml +0 -4
- package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
- package/dist/assets/templates/html/default.html +0 -78
- package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
- package/dist/assets/wiki/index-template.md +0 -12
- package/dist/assets/wiki/ingest-workflow-template.md +0 -83
- package/dist/assets/wiki/log-template.md +0 -8
- package/dist/assets/wiki/schema-template.md +0 -61
- package/dist/cli/config-migrate.js +0 -150
- package/dist/cli/config-validate.js +0 -39
- package/dist/commands/graph/graph-cli.js +0 -124
- package/dist/commands/graph/graph.js +0 -487
- package/dist/commands/improve/calibration.js +0 -161
- package/dist/commands/improve/dedup.js +0 -482
- package/dist/commands/improve/extract-watch.js +0 -140
- package/dist/commands/improve/hot-probation.js +0 -45
- package/dist/commands/improve/improve-auto-accept.js +0 -276
- package/dist/commands/improve/improve-profiles.js +0 -168
- package/dist/commands/improve/procedural.js +0 -398
- package/dist/commands/improve/recombine.js +0 -818
- package/dist/commands/improve/schema-similarity-gate.js +0 -168
- package/dist/commands/lint/agent-linter.js +0 -44
- package/dist/commands/lint/command-linter.js +0 -44
- package/dist/commands/lint/default-linter.js +0 -16
- package/dist/commands/lint/fact-linter.js +0 -39
- package/dist/commands/lint/knowledge-linter.js +0 -16
- package/dist/commands/lint/memory-linter.js +0 -61
- package/dist/commands/lint/registry.js +0 -41
- package/dist/commands/lint/skill-linter.js +0 -45
- package/dist/commands/lint/task-linter.js +0 -50
- package/dist/commands/lint/workflow-linter.js +0 -81
- package/dist/commands/proposal/legacy-import.js +0 -115
- package/dist/commands/sources/history.js +0 -196
- package/dist/commands/tasks/default-tasks.js +0 -186
- package/dist/commands/wiki-cli.js +0 -292
- package/dist/core/asset/asset-registry.js +0 -76
- package/dist/core/asset/asset-spec.js +0 -259
- package/dist/core/config/config-migration.js +0 -602
- package/dist/core/deep-merge.js +0 -38
- package/dist/core/eval/rank-metrics.js +0 -113
- package/dist/core/ripgrep/install.js +0 -163
- package/dist/core/ripgrep/resolve.js +0 -81
- package/dist/indexer/db/db.js +0 -1413
- package/dist/indexer/manifest.js +0 -170
- package/dist/indexer/passes/metadata-contributors.js +0 -31
- package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
- package/dist/integrations/harnesses/opencode-sdk/index.js +0 -49
- package/dist/llm/call-ai.js +0 -62
- package/dist/llm/memory-infer-impl.js +0 -138
- 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/output/text/wiki.js +0 -16
- package/dist/registry/build-index.js +0 -386
- package/dist/scripts/migrate-storage.js +0 -19108
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -9411
- package/dist/scripts/migrations/v16-to-v17.js +0 -141
- package/dist/setup/legacy-config.js +0 -106
- package/dist/storage/repositories/consolidation-repository.js +0 -38
- package/dist/storage/repositories/recombine-repository.js +0 -213
- package/dist/wiki/wiki-templates.js +0 -15
- package/dist/wiki/wiki.js +0 -1012
- package/dist/workflows/db.js +0 -215
- package/docs/data-and-telemetry.md +0 -226
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
/**
|
|
5
|
+
* OpenAI Codex CLI agent command builder (P2, plan §"The adapter contract" /
|
|
6
|
+
* §"Capability matrix").
|
|
7
|
+
*
|
|
8
|
+
* Translates a platform-agnostic {@link AgentDispatchRequest} into the exact
|
|
9
|
+
* headless argv the `codex` CLI expects:
|
|
10
|
+
*
|
|
11
|
+
* codex exec --sandbox workspace-write [--model <m>] --json [--output-schema <file>] -- "<prompt>"
|
|
12
|
+
*
|
|
13
|
+
* Capability-matrix facts this builder encodes (July 2026 research):
|
|
14
|
+
* - Headless invocation is the `exec` subcommand (`codex exec "<p>"`), not a
|
|
15
|
+
* flag. The built-in codex profiles carry `args: []`, so the builder
|
|
16
|
+
* prepends `exec` itself; a user profile that already pins `exec` as its
|
|
17
|
+
* first arg is not doubled.
|
|
18
|
+
* - `--json` switches stdout to a JSONL event stream — the input contract of
|
|
19
|
+
* `./result-extractor.ts`. Always emitted, mirroring how the Claude builder
|
|
20
|
+
* always emits `--print`: dispatch is the captured, non-interactive path.
|
|
21
|
+
* - Codex is the NATIVE-SCHEMA tier (plan §"Structured-output
|
|
22
|
+
* normalization"): `req.schema` is written to a temp file and passed via
|
|
23
|
+
* `--output-schema <file>`. The file is tiny, uniquely named under the OS
|
|
24
|
+
* temp dir, and intentionally NOT cleaned up here — `BuiltCommand` has no
|
|
25
|
+
* post-run hook, and the spawned process reads the file after `build()`
|
|
26
|
+
* returns. OS temp reaping owns the lifecycle. The engine still validates
|
|
27
|
+
* the output defensively (the constrained output is trusted but verified).
|
|
28
|
+
* - `codex exec` has no system-prompt flag; `req.systemPrompt` is folded
|
|
29
|
+
* into the prompt payload (system text first, blank line, then the task),
|
|
30
|
+
* after the `--` end-of-options separator so it can never be parsed as a
|
|
31
|
+
* flag.
|
|
32
|
+
* - Tool policy is omitted, but the builder DOES inject `--sandbox
|
|
33
|
+
* workspace-write` so dispatched units can write to their working
|
|
34
|
+
* directory. `codex exec` defaults to a read-only sandbox that silently
|
|
35
|
+
* blocks file writes; without this flag the unit returns "workspace is
|
|
36
|
+
* read-only" and the engine marks the step complete with no real mutation.
|
|
37
|
+
* `--ask-for-approval` is NOT injected — that flag only exists on the
|
|
38
|
+
* interactive `codex` command, not on `codex exec`, and exec mode is
|
|
39
|
+
* already non-approval-blocking. Profile-supplied `--sandbox` flags
|
|
40
|
+
* (long or short form) are preserved (not duplicated).
|
|
41
|
+
* - Resume is the `codex exec resume <id>` SUBCOMMAND, not a flag, so it is
|
|
42
|
+
* not expressible through `AgentDispatchRequest` (which has no session
|
|
43
|
+
* field yet); {@link codexResumeArgs} exposes the argv prefix for the
|
|
44
|
+
* integration task that wires session-id reuse from `workflow_run_units`.
|
|
45
|
+
* - `req.effort` stays unconsumed (reserved; codex would take it as
|
|
46
|
+
* `-c model_reasoning_effort=<v>` — left to the integration task so the
|
|
47
|
+
* shared request contract's "no builder consumes it yet" note stays true).
|
|
48
|
+
*
|
|
49
|
+
* Registered: `codexBuilder` is `CodexHarness.agentBuilder` (`./index.ts`),
|
|
50
|
+
* one of the ten harnesses `HARNESS_REGISTRY` constructs
|
|
51
|
+
* (`harnesses/index.ts`); `agent/builders.ts` derives `BUILTIN_BUILDERS` from
|
|
52
|
+
* that registry, so this builder is reachable under the `"codex"` platform
|
|
53
|
+
* name without any further wiring.
|
|
54
|
+
*/
|
|
55
|
+
import { mkdtempSync, writeFileSync } from "node:fs";
|
|
56
|
+
import { tmpdir } from "node:os";
|
|
57
|
+
import { join } from "node:path";
|
|
58
|
+
import { assertNotFlag, resolveDispatchModel } from "../../agent/builder-shared.js";
|
|
59
|
+
/**
|
|
60
|
+
* Write a node's JSON Schema to a fresh temp file for `--output-schema`.
|
|
61
|
+
*
|
|
62
|
+
* A unique `mkdtemp` directory per build avoids collisions between concurrent
|
|
63
|
+
* fan-out units dispatching in the same process. Returns the absolute file
|
|
64
|
+
* path (the value handed to the flag).
|
|
65
|
+
*/
|
|
66
|
+
export function writeCodexOutputSchemaFile(schema) {
|
|
67
|
+
const dir = mkdtempSync(join(tmpdir(), "akm-codex-schema-"));
|
|
68
|
+
const file = join(dir, "output-schema.json");
|
|
69
|
+
writeFileSync(file, `${JSON.stringify(schema, null, 2)}\n`, "utf8");
|
|
70
|
+
return file;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Argv prefix that resumes a previous codex session: `exec resume <id>`.
|
|
74
|
+
* Codex resume is a subcommand chain, not a flag. The harness-native session
|
|
75
|
+
* id comes from the unit row (stored opportunistically by the result
|
|
76
|
+
* extractor); akm never depends on it (plan §"Session, MCP, and identity").
|
|
77
|
+
*/
|
|
78
|
+
export function codexResumeArgs(sessionId) {
|
|
79
|
+
assertNotFlag(sessionId, "sessionId");
|
|
80
|
+
return ["exec", "resume", sessionId];
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Return `base` plus the `--sandbox workspace-write` flag that makes `codex exec`
|
|
84
|
+
* able to write to its working directory. `codex exec` defaults to a read-only
|
|
85
|
+
* sandbox that silently blocks file writes — without this flag the unit returns
|
|
86
|
+
* "workspace is read-only" and the engine marks the step complete with no real
|
|
87
|
+
* mutation. If the profile already pins `--sandbox` (long or short form) the
|
|
88
|
+
* default is not duplicated.
|
|
89
|
+
*
|
|
90
|
+
* Note: `--ask-for-approval` is an *interactive* codex flag only — `codex exec`
|
|
91
|
+
* does not accept it (it errors with "unexpected argument"). Non-interactive
|
|
92
|
+
* exec mode is implicitly non-approval-blocking; `--sandbox workspace-write`
|
|
93
|
+
* alone is sufficient for dispatched units.
|
|
94
|
+
*/
|
|
95
|
+
function ensureSandboxFlags(base) {
|
|
96
|
+
const out = [...base];
|
|
97
|
+
if (!out.includes("--sandbox") && !out.includes("-s")) {
|
|
98
|
+
out.push("--sandbox", "workspace-write");
|
|
99
|
+
}
|
|
100
|
+
return out;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* OpenAI Codex builder.
|
|
104
|
+
* Command shape: codex exec --sandbox workspace-write [--model <m>] --json [--output-schema <file>] -- "<prompt>"
|
|
105
|
+
*/
|
|
106
|
+
export const codexBuilder = {
|
|
107
|
+
platform: "codex",
|
|
108
|
+
build(profile, req) {
|
|
109
|
+
assertNotFlag(req.systemPrompt, "systemPrompt");
|
|
110
|
+
assertNotFlag(req.model, "model");
|
|
111
|
+
// Built-in codex profiles ship `args: []`; headless dispatch is the `exec`
|
|
112
|
+
// subcommand. Don't double it when a user profile already pins it.
|
|
113
|
+
const extra = profile.args[0] === "exec" ? profile.args.slice(1) : [...profile.args];
|
|
114
|
+
// `codex exec` defaults to a read-only sandbox that silently blocks file
|
|
115
|
+
// writes — dispatched units would return "workspace is read-only" and the
|
|
116
|
+
// engine would mark them complete with no real mutation. Force
|
|
117
|
+
// `workspace-write` (writes scoped to cwd) unless the profile already pins
|
|
118
|
+
// its own --sandbox flag (`--ask-for-approval` is not injectable here —
|
|
119
|
+
// see ensureSandboxFlags).
|
|
120
|
+
const sandboxArgs = ensureSandboxFlags(extra);
|
|
121
|
+
const args = ["exec", ...sandboxArgs];
|
|
122
|
+
if (req.model) {
|
|
123
|
+
const resolved = resolveDispatchModel(req, profile, "codex");
|
|
124
|
+
args.push("--model", resolved);
|
|
125
|
+
}
|
|
126
|
+
// JSONL event stream on stdout — the codex result extractor's input.
|
|
127
|
+
args.push("--json");
|
|
128
|
+
if (req.schema) {
|
|
129
|
+
// Native-schema tier: pass the node schema straight through.
|
|
130
|
+
args.push("--output-schema", writeCodexOutputSchemaFile(req.schema));
|
|
131
|
+
}
|
|
132
|
+
// No system-prompt flag exists on `codex exec` — fold it into the prompt.
|
|
133
|
+
const prompt = req.systemPrompt ? `${req.systemPrompt}\n\n${req.prompt}` : req.prompt;
|
|
134
|
+
args.push("--");
|
|
135
|
+
args.push(prompt);
|
|
136
|
+
return { argv: [profile.bin, ...args] };
|
|
137
|
+
},
|
|
138
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
/**
|
|
5
|
+
* OpenAI Codex CLI harness (P2 integration, plan §"The adapter contract").
|
|
6
|
+
*
|
|
7
|
+
* Per-harness barrel gathering the Codex integration surfaces:
|
|
8
|
+
* - agent command builder → ./agent-builder.ts (codexBuilder)
|
|
9
|
+
* - result extractor → ./result-extractor.ts (codexResultExtractor)
|
|
10
|
+
*
|
|
11
|
+
* It also defines {@link CodexHarness}, the {@link AkmHarness} descriptor that
|
|
12
|
+
* `HARNESS_REGISTRY` registers. Dispatch-only: no native session-log reader or
|
|
13
|
+
* config importer yet.
|
|
14
|
+
*/
|
|
15
|
+
import { caps } from "../shared.js";
|
|
16
|
+
import { BaseHarness } from "../types.js";
|
|
17
|
+
import { codexBuilder } from "./agent-builder.js";
|
|
18
|
+
import { codexResultExtractor } from "./result-extractor.js";
|
|
19
|
+
export { codexBuilder, codexResumeArgs, writeCodexOutputSchemaFile } from "./agent-builder.js";
|
|
20
|
+
export { codexResultExtractor } from "./result-extractor.js";
|
|
21
|
+
/**
|
|
22
|
+
* OpenAI Codex CLI.
|
|
23
|
+
*
|
|
24
|
+
* Canonical id is `'codex'`; no alias or distinct runtime identity.
|
|
25
|
+
*/
|
|
26
|
+
export class CodexHarness extends BaseHarness {
|
|
27
|
+
id = "codex";
|
|
28
|
+
displayName = "OpenAI Codex CLI";
|
|
29
|
+
aliases = [];
|
|
30
|
+
agentBuilder = codexBuilder;
|
|
31
|
+
resultExtractor = codexResultExtractor;
|
|
32
|
+
// ── Workflow-engine descriptor (plan §"Capability matrix", P2) ────────────
|
|
33
|
+
// akm spawns `codex exec` locally per unit ⇒ local-runner.
|
|
34
|
+
pattern = "local-runner";
|
|
35
|
+
// `--output-schema <file>` enforces a caller-supplied JSON schema natively.
|
|
36
|
+
structuredOutput = "native-schema";
|
|
37
|
+
// No flag-shaped resume: codex resume is the `exec resume <id>` SUBCOMMAND
|
|
38
|
+
// chain (see `codexResumeArgs` in ./agent-builder.ts).
|
|
39
|
+
// Presence flag: CODEX_SANDBOX is stamped only on processes codex itself
|
|
40
|
+
// spawns inside its sandbox, so it genuinely means "running under codex" —
|
|
41
|
+
// but its VALUE (e.g. "seatbelt") is a sandbox mode, not a session id, so it
|
|
42
|
+
// is registered as `presenceEnv` (harness inference only), never
|
|
43
|
+
// `identityEnv` (whose values persist as agent_session_id). CODEX_HOME (the
|
|
44
|
+
// matrix's other candidate) is deliberately NOT registered anywhere: it is a
|
|
45
|
+
// user config-dir var commonly exported in shell profiles, so it would stamp
|
|
46
|
+
// identity onto manual runs (see `AkmHarness.presenceEnv`).
|
|
47
|
+
presenceEnv = ["CODEX_SANDBOX"];
|
|
48
|
+
capabilities = caps({
|
|
49
|
+
agentDispatch: true,
|
|
50
|
+
detection: true,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
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
|
+
function isRecord(value) {
|
|
5
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
function asNonEmptyString(value) {
|
|
8
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
9
|
+
}
|
|
10
|
+
/** Interpret one parsed JSONL event in either codex event dialect. */
|
|
11
|
+
function interpretEvent(event) {
|
|
12
|
+
// Legacy protocol: {"id":..., "msg":{"type": ...}}
|
|
13
|
+
const msg = event.msg;
|
|
14
|
+
if (isRecord(msg)) {
|
|
15
|
+
switch (msg.type) {
|
|
16
|
+
case "session_configured":
|
|
17
|
+
return { sessionId: asNonEmptyString(msg.session_id) };
|
|
18
|
+
case "agent_message":
|
|
19
|
+
return { agentMessage: asNonEmptyString(msg.message) };
|
|
20
|
+
case "task_complete":
|
|
21
|
+
return { finalMessage: asNonEmptyString(msg.last_agent_message) };
|
|
22
|
+
default:
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// Newer protocol: flat {"type": "thread.started" | "item.completed" | ...}
|
|
27
|
+
switch (event.type) {
|
|
28
|
+
case "thread.started":
|
|
29
|
+
return { sessionId: asNonEmptyString(event.thread_id) };
|
|
30
|
+
case "item.completed": {
|
|
31
|
+
const item = event.item;
|
|
32
|
+
if (isRecord(item) && item.type === "agent_message") {
|
|
33
|
+
return { agentMessage: asNonEmptyString(item.text) };
|
|
34
|
+
}
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
default:
|
|
38
|
+
return {};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Codex result extractor: JSONL event stream (either dialect) → final agent
|
|
43
|
+
* message + opportunistic session id, with a plain-stdout fallback.
|
|
44
|
+
*/
|
|
45
|
+
export const codexResultExtractor = (result) => {
|
|
46
|
+
let sessionId = result.sessionId;
|
|
47
|
+
let lastAgentMessage;
|
|
48
|
+
let finalMessage;
|
|
49
|
+
for (const line of result.stdout.split("\n")) {
|
|
50
|
+
const trimmed = line.trim();
|
|
51
|
+
// Every codex event line is a JSON object; skip banner/noise lines cheaply.
|
|
52
|
+
if (!trimmed.startsWith("{"))
|
|
53
|
+
continue;
|
|
54
|
+
let parsed;
|
|
55
|
+
try {
|
|
56
|
+
parsed = JSON.parse(trimmed);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
continue; // not a complete JSON line (e.g. wrapped text) — ignore
|
|
60
|
+
}
|
|
61
|
+
if (!isRecord(parsed))
|
|
62
|
+
continue;
|
|
63
|
+
const contribution = interpretEvent(parsed);
|
|
64
|
+
if (contribution.sessionId)
|
|
65
|
+
sessionId = contribution.sessionId;
|
|
66
|
+
if (contribution.agentMessage)
|
|
67
|
+
lastAgentMessage = contribution.agentMessage;
|
|
68
|
+
if (contribution.finalMessage)
|
|
69
|
+
finalMessage = contribution.finalMessage;
|
|
70
|
+
}
|
|
71
|
+
const text = finalMessage ?? lastAgentMessage ?? result.stdout.trim();
|
|
72
|
+
return sessionId === undefined ? { text } : { text, sessionId };
|
|
73
|
+
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
/**
|
|
5
|
+
* GitHub Copilot CLI agent command builder (P2, plan §"The adapter contract"
|
|
6
|
+
* step 2 / §"Capability matrix").
|
|
7
|
+
*
|
|
8
|
+
* Translates a platform-agnostic {@link AgentDispatchRequest} into the exact
|
|
9
|
+
* headless argv the `copilot` CLI expects. Per the capability matrix the
|
|
10
|
+
* headless invocation is:
|
|
11
|
+
*
|
|
12
|
+
* copilot -p "<prompt>" --allow-all-tools
|
|
13
|
+
*
|
|
14
|
+
* with `--output-format json` for structured output, `--model <m>` for model
|
|
15
|
+
* selection, and `--resume <id>` for resume (not built here because
|
|
16
|
+
* `AgentDispatchRequest` carries no session id).
|
|
17
|
+
*
|
|
18
|
+
* Platform-specific mapping decisions (all localized here, per the adapter
|
|
19
|
+
* contract):
|
|
20
|
+
*
|
|
21
|
+
* - **systemPrompt** — Copilot CLI has no system-prompt flag (it reads
|
|
22
|
+
* repo/user custom-instructions files instead), so the system prompt is
|
|
23
|
+
* folded into the `-p` payload ahead of the task prompt, separated by a
|
|
24
|
+
* blank line. `assertNotFlag` still guards it so a `--`-prefixed system
|
|
25
|
+
* prompt cannot turn the front of the `-p` value into a flag.
|
|
26
|
+
* - **schema** — the matrix places Copilot in the "via prompt+validate" tier
|
|
27
|
+
* (no native `--output-schema` equivalent, unlike Codex), so the JSON
|
|
28
|
+
* Schema is passed through the prompt: a directive matching the engine's
|
|
29
|
+
* wording (`step-work.ts` `buildUnitPrompt`) is appended to the `-p`
|
|
30
|
+
* payload, and `--output-format json` is emitted so stdout is the
|
|
31
|
+
* documented JSON envelope the copilot result extractor normalizes. The
|
|
32
|
+
* engine's shared retry-until-valid loop performs the actual validation.
|
|
33
|
+
* - **tools** — a string/array tool policy maps to repeated
|
|
34
|
+
* `--allow-tool <t>` flags (Copilot's per-tool approval flag). With no
|
|
35
|
+
* policy at all, headless runs need autonomy, so `--allow-all-tools` is
|
|
36
|
+
* emitted per the matrix. A *structured* policy object is NOT expressible
|
|
37
|
+
* as Copilot flags; it is deliberately dropped without falling back to
|
|
38
|
+
* `--allow-all-tools` (never silently widen a restriction) — in
|
|
39
|
+
* programmatic mode Copilot then denies unapproved tool calls, which is the
|
|
40
|
+
* conservative failure mode.
|
|
41
|
+
*
|
|
42
|
+
* Registered: `copilotBuilder` is `CopilotHarness.agentBuilder`
|
|
43
|
+
* (`./index.ts`), one of the ten harnesses `HARNESS_REGISTRY` constructs
|
|
44
|
+
* (`harnesses/index.ts`); `agent/builders.ts` derives `BUILTIN_BUILDERS` from
|
|
45
|
+
* that registry, so this builder is reachable under the `"copilot"` platform
|
|
46
|
+
* name without any further wiring.
|
|
47
|
+
*/
|
|
48
|
+
import { assertNotFlag, resolveDispatchModel, } from "../../agent/builder-shared.js";
|
|
49
|
+
/** Canonical harness/platform id used for model-alias resolution. */
|
|
50
|
+
export const COPILOT_PLATFORM = "copilot";
|
|
51
|
+
/**
|
|
52
|
+
* Split a tool policy into individual tool names for `--allow-tool`.
|
|
53
|
+
* Strings are comma-separated lists; arrays are taken as-is. Structured
|
|
54
|
+
* policy objects return `undefined` (not expressible as Copilot flags — see
|
|
55
|
+
* module doc).
|
|
56
|
+
*/
|
|
57
|
+
function toolPolicyEntries(tools) {
|
|
58
|
+
if (typeof tools === "string") {
|
|
59
|
+
return tools
|
|
60
|
+
.split(",")
|
|
61
|
+
.map((t) => t.trim())
|
|
62
|
+
.filter(Boolean);
|
|
63
|
+
}
|
|
64
|
+
if (Array.isArray(tools)) {
|
|
65
|
+
return tools.map((t) => t.trim()).filter(Boolean);
|
|
66
|
+
}
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Assemble the `-p` payload: optional system prompt, the task prompt, and —
|
|
71
|
+
* when a schema is requested — the same schema directive the workflow
|
|
72
|
+
* engine's prompt assembly uses, so both dispatch paths speak one dialect.
|
|
73
|
+
*/
|
|
74
|
+
function buildPromptPayload(req) {
|
|
75
|
+
const sections = [];
|
|
76
|
+
if (req.systemPrompt)
|
|
77
|
+
sections.push(req.systemPrompt);
|
|
78
|
+
sections.push(req.prompt);
|
|
79
|
+
if (req.schema) {
|
|
80
|
+
sections.push(`Respond with ONLY a JSON value matching this JSON Schema (no prose, no code fences):\n${JSON.stringify(req.schema)}`);
|
|
81
|
+
}
|
|
82
|
+
return sections.join("\n\n");
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* GitHub Copilot CLI builder.
|
|
86
|
+
* Command shape:
|
|
87
|
+
* copilot [--model <m>] (--allow-all-tools | --allow-tool <t> ...)
|
|
88
|
+
* [--output-format json] -p "<systemPrompt?\n\nprompt\n\nschema?>"
|
|
89
|
+
*/
|
|
90
|
+
export const copilotBuilder = {
|
|
91
|
+
platform: COPILOT_PLATFORM,
|
|
92
|
+
build(profile, req) {
|
|
93
|
+
assertNotFlag(req.systemPrompt, "systemPrompt");
|
|
94
|
+
assertNotFlag(req.model, "model");
|
|
95
|
+
const args = [...profile.args];
|
|
96
|
+
if (req.model) {
|
|
97
|
+
const resolved = resolveDispatchModel(req, profile, COPILOT_PLATFORM);
|
|
98
|
+
args.push("--model", resolved);
|
|
99
|
+
}
|
|
100
|
+
if (req.tools) {
|
|
101
|
+
const entries = toolPolicyEntries(req.tools);
|
|
102
|
+
// Structured policy objects (entries === undefined) emit NO allow flags:
|
|
103
|
+
// dropping a restriction must never widen to --allow-all-tools.
|
|
104
|
+
for (const tool of entries ?? []) {
|
|
105
|
+
assertNotFlag(tool, "tools entry");
|
|
106
|
+
args.push("--allow-tool", tool);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
// Headless default per the capability matrix: units must run without
|
|
111
|
+
// interactive tool-approval prompts.
|
|
112
|
+
args.push("--allow-all-tools");
|
|
113
|
+
}
|
|
114
|
+
if (req.schema) {
|
|
115
|
+
// Structured unit: ask for the documented JSON envelope so the result
|
|
116
|
+
// extractor can pull the final message + session id deterministically.
|
|
117
|
+
args.push("--output-format", "json");
|
|
118
|
+
}
|
|
119
|
+
args.push("-p", buildPromptPayload(req));
|
|
120
|
+
return { argv: [profile.bin, ...args] };
|
|
121
|
+
},
|
|
122
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
/**
|
|
5
|
+
* GitHub Copilot CLI harness (P2 integration, plan §"The adapter contract").
|
|
6
|
+
*
|
|
7
|
+
* Per-harness barrel gathering the Copilot CLI integration surfaces:
|
|
8
|
+
* - agent command builder → ./agent-builder.ts (copilotBuilder)
|
|
9
|
+
* - result extractor → ./result-extractor.ts (copilotResultExtractor)
|
|
10
|
+
*
|
|
11
|
+
* It also defines {@link CopilotHarness}, the {@link AkmHarness} descriptor
|
|
12
|
+
* that `HARNESS_REGISTRY` registers. This is the LOCAL Copilot CLI
|
|
13
|
+
* (`copilot -p …`); the cloud "Copilot coding agent" is the plan's
|
|
14
|
+
* cloud-delegate pattern and is a separate, future descriptor.
|
|
15
|
+
*/
|
|
16
|
+
import { caps } from "../shared.js";
|
|
17
|
+
import { BaseHarness } from "../types.js";
|
|
18
|
+
import { copilotBuilder } from "./agent-builder.js";
|
|
19
|
+
import { copilotResultExtractor } from "./result-extractor.js";
|
|
20
|
+
export { COPILOT_PLATFORM, copilotBuilder } from "./agent-builder.js";
|
|
21
|
+
export { copilotResultExtractor } from "./result-extractor.js";
|
|
22
|
+
/**
|
|
23
|
+
* GitHub Copilot CLI (local headless CLI, not the cloud coding agent).
|
|
24
|
+
*
|
|
25
|
+
* Canonical id is `'copilot'`; no alias or distinct runtime identity.
|
|
26
|
+
*/
|
|
27
|
+
export class CopilotHarness extends BaseHarness {
|
|
28
|
+
id = "copilot";
|
|
29
|
+
displayName = "GitHub Copilot CLI";
|
|
30
|
+
aliases = [];
|
|
31
|
+
agentBuilder = copilotBuilder;
|
|
32
|
+
resultExtractor = copilotResultExtractor;
|
|
33
|
+
// ── Workflow-engine descriptor (plan §"Capability matrix", P2) ────────────
|
|
34
|
+
// akm spawns the `copilot` CLI locally per unit ⇒ local-runner.
|
|
35
|
+
pattern = "local-runner";
|
|
36
|
+
// `--output-format json` emits a documented JSON envelope akm parses, then
|
|
37
|
+
// validates against the node schema ⇒ native-json tier.
|
|
38
|
+
structuredOutput = "native-json";
|
|
39
|
+
// Session-id env marker only. The matrix's other candidates (GH_TOKEN,
|
|
40
|
+
// bare COPILOT_* presence vars) are credential/presence flags that would
|
|
41
|
+
// stamp identity onto manual runs, so they are deliberately NOT registered
|
|
42
|
+
// (see `AkmHarness.identityEnv`).
|
|
43
|
+
identityEnv = ["COPILOT_SESSION_ID"];
|
|
44
|
+
capabilities = caps({
|
|
45
|
+
agentDispatch: true,
|
|
46
|
+
detection: true,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
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
|
+
function isRecord(value) {
|
|
5
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
/** Keys that may carry the final answer, in precedence order. */
|
|
8
|
+
const TEXT_KEYS = ["result", "response", "text", "output", "content", "message"];
|
|
9
|
+
/** Keys that may carry the harness-native session id, in precedence order. */
|
|
10
|
+
const SESSION_KEYS = ["session_id", "sessionId", "conversation_id", "conversationId", "thread_id", "threadId"];
|
|
11
|
+
/**
|
|
12
|
+
* Coerce a candidate value into text. Handles the shapes Copilot's envelope
|
|
13
|
+
* nests answers in: bare strings, `{content|text}` wrappers (assistant
|
|
14
|
+
* message objects), and arrays of `{type:"text",text}` content blocks.
|
|
15
|
+
* Depth-bounded: JSON.parse output is acyclic, but nesting is capped anyway
|
|
16
|
+
* so a pathological envelope cannot recurse unboundedly.
|
|
17
|
+
*/
|
|
18
|
+
function textOf(value, depth = 0) {
|
|
19
|
+
if (depth > 4)
|
|
20
|
+
return undefined;
|
|
21
|
+
if (typeof value === "string")
|
|
22
|
+
return value;
|
|
23
|
+
if (Array.isArray(value)) {
|
|
24
|
+
const parts = [];
|
|
25
|
+
for (const block of value) {
|
|
26
|
+
const t = textOf(block, depth + 1);
|
|
27
|
+
if (t)
|
|
28
|
+
parts.push(t);
|
|
29
|
+
}
|
|
30
|
+
return parts.length > 0 ? parts.join("\n") : undefined;
|
|
31
|
+
}
|
|
32
|
+
if (isRecord(value)) {
|
|
33
|
+
return textOf(value.content ?? value.text, depth + 1);
|
|
34
|
+
}
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
/** Extract the final-answer text from one parsed JSON value, if any. */
|
|
38
|
+
function extractText(value) {
|
|
39
|
+
if (typeof value === "string")
|
|
40
|
+
return value;
|
|
41
|
+
if (!isRecord(value))
|
|
42
|
+
return undefined;
|
|
43
|
+
for (const key of TEXT_KEYS) {
|
|
44
|
+
if (!(key in value))
|
|
45
|
+
continue;
|
|
46
|
+
const text = textOf(value[key]);
|
|
47
|
+
if (text !== undefined)
|
|
48
|
+
return text;
|
|
49
|
+
}
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
/** Extract a harness-native session id from one parsed JSON value, if any. */
|
|
53
|
+
function extractSessionId(value) {
|
|
54
|
+
if (!isRecord(value))
|
|
55
|
+
return undefined;
|
|
56
|
+
for (const key of SESSION_KEYS) {
|
|
57
|
+
const candidate = value[key];
|
|
58
|
+
if (typeof candidate === "string" && candidate.length > 0)
|
|
59
|
+
return candidate;
|
|
60
|
+
}
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* `type` discriminator values Copilot's `--output-format json` envelopes are
|
|
65
|
+
* documented to use (plus the `session.*` event family). Deliberately a
|
|
66
|
+
* CLOSED set: a schema unit's own answer may legitimately be a discriminated
|
|
67
|
+
* union with a `type` field (`{"type":"success","output":"data"}`), and
|
|
68
|
+
* treating ANY string `type` as a transport marker would unwrap — and
|
|
69
|
+
* corrupt — such answers. An unrecognized type degrades to raw pass-through,
|
|
70
|
+
* which the schema validator handles (whole object) and free-text tolerates.
|
|
71
|
+
*/
|
|
72
|
+
const ENVELOPE_TYPES = new Set(["result", "response", "message", "assistant", "error"]);
|
|
73
|
+
/**
|
|
74
|
+
* Does this parsed object look like one of Copilot's transport ENVELOPES (a
|
|
75
|
+
* `result`/event document) rather than a bare JSON answer the model produced?
|
|
76
|
+
*
|
|
77
|
+
* Copilot's `--output-format json` documents always carry a transport marker:
|
|
78
|
+
* a known `type` discriminator (`"result"`, `"session.start"`, `"message"`, …)
|
|
79
|
+
* and, in every documented result envelope, a session-id field. A bare
|
|
80
|
+
* structured answer a schema unit was asked for — e.g. `{"result":"ok"}` or
|
|
81
|
+
* `{"type":"success","output":"data"}` — carries neither a known discriminator
|
|
82
|
+
* nor (normally) a session-id key. Unwrapping such an answer would hand the
|
|
83
|
+
* schema validator only the field value (`"ok"`) and reject the run despite
|
|
84
|
+
* valid JSON (PR #714 review), so we only unwrap objects that are genuinely
|
|
85
|
+
* envelopes and pass everything else through raw.
|
|
86
|
+
*/
|
|
87
|
+
function isTransportEnvelope(value) {
|
|
88
|
+
const type = value.type;
|
|
89
|
+
if (typeof type === "string" && (ENVELOPE_TYPES.has(type) || type.startsWith("session.")))
|
|
90
|
+
return true;
|
|
91
|
+
return extractSessionId(value) !== undefined;
|
|
92
|
+
}
|
|
93
|
+
/** JSON.parse that returns undefined instead of throwing. */
|
|
94
|
+
function tryParseJson(raw) {
|
|
95
|
+
try {
|
|
96
|
+
return JSON.parse(raw);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Normalize a raw copilot run result into `{ text, sessionId? }`.
|
|
104
|
+
* See the module doc for the three stdout shapes handled.
|
|
105
|
+
*/
|
|
106
|
+
export const copilotResultExtractor = (result) => {
|
|
107
|
+
// The raw result's own sessionId (SDK-style paths) is the fallback; an id
|
|
108
|
+
// found in the output stream wins because it is fresher.
|
|
109
|
+
const fallbackSessionId = result.sessionId;
|
|
110
|
+
const raw = result.stdout.trim();
|
|
111
|
+
// Shape 1 — whole stdout is one JSON document (spawn may have pre-parsed
|
|
112
|
+
// it when the profile requested parseOutput: "json").
|
|
113
|
+
const whole = result.parsed !== undefined ? result.parsed : raw.length > 0 ? tryParseJson(raw) : undefined;
|
|
114
|
+
if (whole !== undefined) {
|
|
115
|
+
const sessionId = extractSessionId(whole) ?? fallbackSessionId;
|
|
116
|
+
// A bare JSON OBJECT with no transport marker is a legitimate structured
|
|
117
|
+
// answer (a schema unit's `{"result":"ok"}`), NOT an envelope — pass its
|
|
118
|
+
// raw JSON through so the engine's schema validator receives the whole
|
|
119
|
+
// object instead of an unwrapped field value (PR #714 review). Only
|
|
120
|
+
// genuine Copilot envelopes are unwrapped; non-object JSON (a top-level
|
|
121
|
+
// string/array/primitive) keeps the prior extraction. Either way, an
|
|
122
|
+
// unknown envelope with no recognized text key falls back to raw stdout.
|
|
123
|
+
const text = isRecord(whole) && !isTransportEnvelope(whole) ? raw : (extractText(whole) ?? raw);
|
|
124
|
+
return { text, ...(sessionId ? { sessionId } : {}) };
|
|
125
|
+
}
|
|
126
|
+
// Shape 2 — JSONL event stream: last text-bearing event wins; first
|
|
127
|
+
// session-id-bearing event supplies the id. Non-JSON lines are banner
|
|
128
|
+
// noise and are skipped.
|
|
129
|
+
let lastText;
|
|
130
|
+
let streamSessionId;
|
|
131
|
+
let sawJsonLine = false;
|
|
132
|
+
for (const line of raw.split("\n")) {
|
|
133
|
+
const trimmed = line.trim();
|
|
134
|
+
if (trimmed.length === 0)
|
|
135
|
+
continue;
|
|
136
|
+
const event = tryParseJson(trimmed);
|
|
137
|
+
if (event === undefined)
|
|
138
|
+
continue;
|
|
139
|
+
sawJsonLine = true;
|
|
140
|
+
streamSessionId ??= extractSessionId(event);
|
|
141
|
+
const text = extractText(event);
|
|
142
|
+
if (text !== undefined)
|
|
143
|
+
lastText = text;
|
|
144
|
+
}
|
|
145
|
+
if (sawJsonLine) {
|
|
146
|
+
const sessionId = streamSessionId ?? fallbackSessionId;
|
|
147
|
+
return { text: lastText ?? raw, ...(sessionId ? { sessionId } : {}) };
|
|
148
|
+
}
|
|
149
|
+
// Shape 3 — plain text passthrough.
|
|
150
|
+
return { text: raw, ...(fallbackSessionId ? { sessionId: fallbackSessionId } : {}) };
|
|
151
|
+
};
|