@aiwg/cli 2026.10.1 → 2026.10.4
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/README.md +2 -2
- package/agentic/code/providers/capability-matrix.yaml +270 -0
- package/agentic/code/providers/model-capabilities.v1.json +3183 -24
- package/bin/aiwg.mjs +135 -47
- package/dist/src/a2a/codecs.js +9 -0
- package/dist/src/agents/grounding/knowledge-base.js +54 -6
- package/dist/src/artifacts/browser-export.js +6 -0
- package/dist/src/artifacts/checksum-manifest.js +1 -0
- package/dist/src/artifacts/citation-parser.js +173 -92
- package/dist/src/artifacts/citation-table-schema.js +59 -0
- package/dist/src/artifacts/cli.js +57 -18
- package/dist/src/artifacts/corpus-tools/snapshot.js +1 -1
- package/dist/src/artifacts/corpus-tools/vision-extract.js +107 -15
- package/dist/src/artifacts/corpus-views/ref-parser.js +3 -1
- package/dist/src/artifacts/corpus-views/renderers.js +3 -3
- package/dist/src/artifacts/discovery-eval.js +6 -4
- package/dist/src/artifacts/fortemi-core-query-adapter.js +36 -3
- package/dist/src/artifacts/fortemi-core-sync.js +166 -40
- package/dist/src/artifacts/framework-capabilities.js +171 -0
- package/dist/src/artifacts/framework-index-paths.js +73 -0
- package/dist/src/artifacts/framework-source-digest.js +75 -0
- package/dist/src/artifacts/index-builder.js +285 -131
- package/dist/src/artifacts/index-files.js +132 -18
- package/dist/src/artifacts/index-preparation.js +65 -0
- package/dist/src/artifacts/index-refresh.js +576 -0
- package/dist/src/artifacts/index-worker.mjs +9 -0
- package/dist/src/artifacts/prebuilt-build-lock.js +47 -4
- package/dist/src/artifacts/prebuilt-deployment.js +46 -0
- package/dist/src/artifacts/prebuilt-relations.js +80 -0
- package/dist/src/artifacts/query-engine.js +410 -88
- package/dist/src/artifacts/relations-builder.js +168 -0
- package/dist/src/artifacts/relations.js +148 -0
- package/dist/src/artifacts/repair.js +9 -4
- package/dist/src/artifacts/stats.js +5 -2
- package/dist/src/artifacts/types.js +30 -10
- package/dist/src/artifacts/watcher.js +1 -1
- package/dist/src/auth/credential-store.js +2 -1
- package/dist/src/catalog/cli.d.mts +5 -0
- package/dist/src/channel/manager.d.mts +20 -0
- package/dist/src/channel/manager.mjs +78 -12
- package/dist/src/cli/child-process-result.js +40 -0
- package/dist/src/cli/command-log.js +2 -3
- package/dist/src/cli/env.js +38 -16
- package/dist/src/cli/flag-parsing.js +236 -0
- package/dist/src/cli/handlers/artifacts.js +3 -0
- package/dist/src/cli/handlers/auth.js +3 -0
- package/dist/src/cli/handlers/decision.js +218 -5
- package/dist/src/cli/handlers/diagnose.js +13 -5
- package/dist/src/cli/handlers/effect.js +4 -2
- package/dist/src/cli/handlers/evidence.js +3 -0
- package/dist/src/cli/handlers/feedback.js +14 -5
- package/dist/src/cli/handlers/help.js +1 -0
- package/dist/src/cli/handlers/index.js +3 -1
- package/dist/src/cli/handlers/init.js +248 -30
- package/dist/src/cli/handlers/lint.js +5 -0
- package/dist/src/cli/handlers/mc.js +23 -0
- package/dist/src/cli/handlers/models.js +169 -10
- package/dist/src/cli/handlers/ralph-launcher.js +2 -0
- package/dist/src/cli/handlers/ralph.js +3 -0
- package/dist/src/cli/handlers/refresh.js +28 -0
- package/dist/src/cli/handlers/regenerate.js +14 -0
- package/dist/src/cli/handlers/resource-versions.js +3 -0
- package/dist/src/cli/handlers/rules.js +195 -0
- package/dist/src/cli/handlers/run.js +4 -0
- package/dist/src/cli/handlers/runtime-info.js +25 -11
- package/dist/src/cli/handlers/script-runner.js +19 -8
- package/dist/src/cli/handlers/session.js +406 -62
- package/dist/src/cli/handlers/sessions.js +243 -76
- package/dist/src/cli/handlers/setup-manifest.js +474 -79
- package/dist/src/cli/handlers/setup.js +180 -39
- package/dist/src/cli/handlers/steward.js +11 -0
- package/dist/src/cli/handlers/subcommands.js +60 -3
- package/dist/src/cli/handlers/team.js +18 -8
- package/dist/src/cli/handlers/uhp.js +3 -0
- package/dist/src/cli/handlers/use.js +307 -55
- package/dist/src/cli/handlers/utilities.js +125 -26
- package/dist/src/cli/handlers/version.js +8 -0
- package/dist/src/cli/prompt-utils.js +72 -0
- package/dist/src/cli/provider-resolution.js +11 -0
- package/dist/src/cli/router.js +15 -1
- package/dist/src/cli/services/deployment-verification.js +19 -9
- package/dist/src/cli/services/provider-prepare-coordinator.js +24 -0
- package/dist/src/cli/skill-usage.js +2 -3
- package/dist/src/config/aiwg-config.js +349 -35
- package/dist/src/config/cli.js +256 -23
- package/dist/src/config/decision-config.js +106 -0
- package/dist/src/config/dispatch-thresholds-runtime.d.mts +8 -0
- package/dist/src/config/dispatch-thresholds-runtime.mjs +38 -0
- package/dist/src/config/gitignore.js +50 -0
- package/dist/src/config/index-graph-overrides.js +36 -0
- package/dist/src/config/project-artifacts-health.d.mts +37 -0
- package/dist/src/config/project-artifacts-health.mjs +14 -3
- package/dist/src/config/project-artifacts-runtime.d.mts +16 -0
- package/dist/src/config/user-config-dir.d.mts +9 -0
- package/dist/src/config/user-config.js +38 -11
- package/dist/src/config/user-registry.js +23 -15
- package/dist/src/config/user-state.js +7 -0
- package/dist/src/decision/adapters/jev.js +75 -27
- package/dist/src/decision/ask.js +203 -43
- package/dist/src/decision/context-live-qualification.js +2 -2
- package/dist/src/decision/driver.js +14 -7
- package/dist/src/decision/ensemble/aggregate.js +23 -10
- package/dist/src/decision/ensemble-study/multifact-study.js +6 -2
- package/dist/src/decision/entry.js +25 -6
- package/dist/src/decision/graph-live-qualification.js +1 -1
- package/dist/src/decision/graph-run.js +9 -0
- package/dist/src/decision/heldout/collector.js +15 -14
- package/dist/src/decision/heldout/contract.js +30 -7
- package/dist/src/decision/index.js +1 -0
- package/dist/src/decision/interop.js +60 -8
- package/dist/src/decision/jev-credentials.js +15 -1
- package/dist/src/decision/ledger.js +942 -0
- package/dist/src/decision/offload-activation.js +137 -0
- package/dist/src/decision/offload.js +550 -0
- package/dist/src/decision/qualification/load.js +4 -6
- package/dist/src/decision/savings.js +28 -0
- package/dist/src/decision/validate.js +6 -3
- package/dist/src/effects/dispatch-verifier.js +252 -0
- package/dist/src/effects/index.js +1 -0
- package/dist/src/effects/types.js +5 -1
- package/dist/src/effects/verifiers/git.js +2 -1
- package/dist/src/effects/verifiers/tracker.js +26 -14
- package/dist/src/extensions/commands/definitions.js +19 -0
- package/dist/src/extensions/project-local-remove.js +36 -1
- package/dist/src/features/installer.js +2 -2
- package/dist/src/flow/graph-metadata.js +5 -0
- package/dist/src/gates/providers/loader.js +64 -18
- package/dist/src/installation/manager-command.d.mts +18 -0
- package/dist/src/installation/manager-command.mjs +15 -3
- package/dist/src/installation/manager.d.mts +49 -0
- package/dist/src/installation/manager.mjs +95 -5
- package/dist/src/issues/cli.js +4 -4
- package/dist/src/issues/local.js +24 -5
- package/dist/src/jobs/runner.js +1 -1
- package/dist/src/lint/cli.js +27 -1
- package/dist/src/lint/loader.js +2 -1
- package/dist/src/lint/reporters.js +25 -1
- package/dist/src/lint/rule-activation.js +43 -0
- package/dist/src/lint/runner.js +137 -62
- package/dist/src/mcp/adapters/codex-runtime.js +366 -56
- package/dist/src/mcp/claude-install.d.mts +4 -0
- package/dist/src/mcp/claude-install.mjs +41 -0
- package/dist/src/mcp/cli.d.mts +1 -0
- package/dist/src/mcp/cli.mjs +620 -85
- package/dist/src/mcp/config-file.d.mts +28 -0
- package/dist/src/mcp/config-file.mjs +279 -0
- package/dist/src/mcp/config-layers.d.mts +36 -0
- package/dist/src/mcp/config-layers.mjs +348 -0
- package/dist/src/mcp/credentials.d.mts +51 -0
- package/dist/src/mcp/credentials.mjs +484 -0
- package/dist/src/mcp/grok-build-config.d.mts +6 -0
- package/dist/src/mcp/grok-build-config.mjs +17 -27
- package/dist/src/mcp/helpers.mjs +109 -4
- package/dist/src/mcp/muse-native-config.d.mts +13 -0
- package/dist/src/mcp/muse-native-config.mjs +1 -0
- package/dist/src/mcp/omp-config.d.mts +4 -0
- package/dist/src/mcp/omp-config.mjs +50 -29
- package/dist/src/mcp/profiles.js +97 -23
- package/dist/src/mcp/profiles.mjs +99 -27
- package/dist/src/mcp/registry.js +248 -131
- package/dist/src/mcp/registry.mjs +169 -100
- package/dist/src/mcp/server-config.d.mts +3 -0
- package/dist/src/mcp/server-config.mjs +89 -0
- package/dist/src/mcp/server.mjs +127 -82
- package/dist/src/mcp/test-simple.mjs +2 -1
- package/dist/src/mcp/toml-editor.d.mts +4 -0
- package/dist/src/mcp/toml-string.d.mts +1 -0
- package/dist/src/mcp/toml-string.mjs +9 -0
- package/dist/src/mcp/toml-strip-mcp.d.mts +1 -0
- package/dist/src/mcp/toml-strip-mcp.mjs +135 -0
- package/dist/src/mcp/tool-filters.d.mts +46 -0
- package/dist/src/mcp/tool-filters.mjs +357 -0
- package/dist/src/mcp/tools/agentic-sandbox.mjs +3 -1
- package/dist/src/mcp/tools/decision.mjs +22 -3
- package/dist/src/mcp/tools/discovery.mjs +62 -55
- package/dist/src/mcp/tools/orchestration.mjs +50 -2
- package/dist/src/mcp/tools/subsystems.mjs +39 -8
- package/dist/src/mcp/tools/worker-invoke.mjs +2856 -0
- package/dist/src/mcp/tools/worker-shell-control.mjs +289 -0
- package/dist/src/mcp/tools/worker-stdin-runtime.mjs +79 -0
- package/dist/src/memory/project-registry.js +2 -2
- package/dist/src/mission-protocol/codecs.js +647 -1
- package/dist/src/mission-protocol/types.js +110 -0
- package/dist/src/mission-protocol/worker-status.js +2 -0
- package/dist/src/models/config-loader.js +76 -14
- package/dist/src/models/grok-build-models.js +93 -41
- package/dist/src/models/model-capabilities.v1.json +3183 -24
- package/dist/src/models/model-discovery.js +931 -67
- package/dist/src/models/provider-policy.js +719 -11
- package/dist/src/models/qualification-digest.d.mts +2 -0
- package/dist/src/models/qualification-digest.mjs +17 -0
- package/dist/src/models/resolver.js +261 -0
- package/dist/src/models/worker-direct-readiness.js +550 -0
- package/dist/src/models/worker-dispatch-offer.js +169 -0
- package/dist/src/models/worker-health-readiness.js +144 -0
- package/dist/src/models/worker-installation.d.mts +39 -0
- package/dist/src/models/worker-installation.mjs +986 -0
- package/dist/src/models/wrapper-route.js +18 -0
- package/dist/src/ops/registry.js +9 -14
- package/dist/src/plugins/standalone-packager.js +4 -3
- package/dist/src/process/bounded-child-process.d.mts +84 -0
- package/dist/src/process/bounded-child-process.mjs +430 -0
- package/dist/src/process/cli-command.d.mts +16 -0
- package/dist/src/process/cli-command.mjs +75 -0
- package/dist/src/process/signal-child.d.mts +6 -0
- package/dist/src/process/signal-child.mjs +7 -0
- package/dist/src/providers/capability-matrix.js +8 -0
- package/dist/src/providers/capability-matrix.yaml +270 -0
- package/dist/src/providers/deployed-skill-roots.js +20 -0
- package/dist/src/providers/grok-build-acp.js +3 -2
- package/dist/src/providers/grok-build-headless.js +53 -23
- package/dist/src/providers/grok-build-inspect.js +1 -0
- package/dist/src/providers/omp-agent.d.mts +8 -0
- package/dist/src/providers/omp-diagnostics.d.mts +1 -0
- package/dist/src/providers/omp-paths.d.mts +13 -0
- package/dist/src/providers/provider-definitions.js +9 -1
- package/dist/src/providers/provider-definitions.mjs +9 -2
- package/dist/src/providers/skill-ownership.d.mts +9 -0
- package/dist/src/providers/skill-ownership.mjs +88 -0
- package/dist/src/rules/activation.d.mts +21 -0
- package/dist/src/rules/activation.mjs +62 -0
- package/dist/src/rules/inline-budget.d.mts +26 -0
- package/dist/src/rules/inline-budget.mjs +66 -0
- package/dist/src/rules/inventory.js +129 -0
- package/dist/src/rules/pin-state.js +73 -0
- package/dist/src/rules/pins.d.mts +14 -0
- package/dist/src/rules/pins.mjs +112 -0
- package/dist/src/rules/rule-frontmatter.schema.json +197 -0
- package/dist/src/serve/executor-registry.js +16 -24
- package/dist/src/serve/fleet-mission-conductor.js +9 -0
- package/dist/src/serve/mission-conductor.js +47 -12
- package/dist/src/serve/shared-host-scheduler.js +2 -0
- package/dist/src/serve/worker-invocation.js +558 -0
- package/dist/src/serve/worker-stdin-frame.d.mts +10 -0
- package/dist/src/serve/worker-stdin-frame.mjs +107 -0
- package/dist/src/sessions/adapter-registry.js +49 -0
- package/dist/src/sessions/adapters/claude.js +39 -54
- package/dist/src/sessions/adapters/codex.js +82 -67
- package/dist/src/sessions/adapters/copilot.js +4 -4
- package/dist/src/sessions/adapters/cursor.js +40 -57
- package/dist/src/sessions/adapters/deepseek-harness.js +15 -12
- package/dist/src/sessions/adapters/factory.js +31 -27
- package/dist/src/sessions/adapters/generic.js +43 -9
- package/dist/src/sessions/adapters/grok-build.js +11 -11
- package/dist/src/sessions/adapters/grokbot-locator.js +111 -0
- package/dist/src/sessions/adapters/grokbot.js +434 -24
- package/dist/src/sessions/adapters/hermes.js +27 -29
- package/dist/src/sessions/adapters/muse-workspace-scan.js +128 -0
- package/dist/src/sessions/adapters/muse.js +200 -104
- package/dist/src/sessions/adapters/omp.js +28 -14
- package/dist/src/sessions/adapters/openclaw.js +89 -79
- package/dist/src/sessions/adapters/opencode.js +27 -24
- package/dist/src/sessions/adapters/openhuman.js +18 -60
- package/dist/src/sessions/adapters/pi.js +30 -14
- package/dist/src/sessions/adapters/warp.js +3 -3
- package/dist/src/sessions/adapters/windsurf.js +19 -48
- package/dist/src/sessions/batch-contracts.js +25 -5
- package/dist/src/sessions/batch-import.js +72 -51
- package/dist/src/sessions/candidates.js +47 -11
- package/dist/src/sessions/contracts.js +75 -2
- package/dist/src/sessions/coverage-preflight.js +134 -0
- package/dist/src/sessions/discovery.js +3 -0
- package/dist/src/sessions/export-plan.js +4 -3
- package/dist/src/sessions/grok-build-cli.js +67 -5
- package/dist/src/sessions/import-exclusions.js +72 -0
- package/dist/src/sessions/import-lease.js +34 -18
- package/dist/src/sessions/import-limits.js +37 -0
- package/dist/src/sessions/importer.js +84 -46
- package/dist/src/sessions/index.js +2 -0
- package/dist/src/sessions/lifecycle.js +45 -0
- package/dist/src/sessions/policy.js +133 -25
- package/dist/src/sessions/readers.js +106 -53
- package/dist/src/sessions/refresh.js +106 -0
- package/dist/src/sessions/repository.js +199 -63
- package/dist/src/sessions/workspace-discovery.js +315 -88
- package/dist/src/sessions/workspace-matching.js +107 -0
- package/dist/src/skills/adapters/clawhub.js +10 -8
- package/dist/src/skills/adapters/openclaw.js +10 -7
- package/dist/src/skills/importer.js +1 -0
- package/dist/src/smiths/context-pipeline/aiwg-md.js +11 -0
- package/dist/src/smiths/context-pipeline/claude-hook.js +3 -26
- package/dist/src/smiths/context-pipeline/finalization.js +6 -5
- package/dist/src/smiths/context-pipeline/generator.js +21 -4
- package/dist/src/smiths/context-pipeline/parallelism-section.js +195 -14
- package/dist/src/smiths/context-pipeline/workspace-context.js +116 -9
- package/dist/src/smiths/hook-bridge/codex-translator.js +6 -5
- package/dist/src/smiths/mcpsmith/example.js +1 -1
- package/dist/src/smiths/mcpsmith/generator.js +1 -1
- package/dist/src/smiths/toolsmith/runtime-discovery.d.mts +10 -0
- package/dist/src/smiths/toolsmith/runtime-discovery.mjs +85 -31
- package/dist/src/storage/backends/fs.js +18 -76
- package/dist/src/storage/backends/logseq.js +68 -7
- package/dist/src/storage/backends/obsidian.js +1 -0
- package/dist/src/storage/fortemi-qualification-receipt.js +2 -2
- package/dist/src/testing/generators/test-code-generator.js +57 -30
- package/dist/src/tracker/forge-http.js +2 -1
- package/dist/src/uhp/client.js +11 -1
- package/dist/src/uhp/mission.js +5 -0
- package/dist/src/update/checker.d.mts +2 -0
- package/dist/src/update/checker.mjs +5 -5
- package/dist/src/update/notifier.mjs +54 -2
- package/dist/src/update/service.d.mts +22 -0
- package/dist/src/utils/contained-filesystem.d.mts +37 -0
- package/dist/src/utils/contained-filesystem.mjs +683 -0
- package/dist/src/utils/temporary-directory.js +36 -0
- package/dist/src/writing/example-generator.js +1 -1
- package/dist/src/writing/fidelity.js +18 -1
- package/package.json +32 -2
- package/schemas/mission-v1.schema.json +2429 -0
- package/schemas/models/model-catalog.v1.schema.json +301 -0
- package/schemas/models/model-config-compatibility.v1.schema.json +281 -0
- package/schemas/models/model-policy.v1.schema.json +14 -0
- package/schemas/models/provider-model-capabilities.v1.schema.json +1072 -0
- package/tools/_resolve-impl.mjs +39 -2
- package/tools/agents/deploy-agents.mjs +64 -23
- package/tools/agents/providers/base.mjs +153 -166
- package/tools/agents/providers/claude.mjs +8 -24
- package/tools/agents/providers/codex.mjs +18 -11
- package/tools/agents/providers/cursor.mjs +19 -18
- package/tools/agents/providers/grok-build.mjs +3 -1
- package/tools/agents/providers/grokbot.mjs +11 -12
- package/tools/agents/providers/hermes.mjs +62 -49
- package/tools/agents/providers/omp.mjs +5 -2
- package/tools/agents/providers/openclaw-translator.mjs +19 -5
- package/tools/agents/providers/openclaw.mjs +9 -4
- package/tools/agents/providers/pi.mjs +5 -0
- package/tools/agents/providers/provider-prepare-channel.mjs +5 -0
- package/tools/agents/providers/provider-prepare-coordinator.mjs +247 -0
- package/tools/agents/providers/provider-prepare-worker.mjs +84 -0
- package/tools/agents/providers/rule-delivery.mjs +1270 -0
- package/tools/agents/providers/warp.mjs +20 -26
- package/tools/cli/decision-offload-report.mjs +40 -0
- package/tools/cli/workspace-status.mjs +862 -0
- package/tools/plugin/package-plugins.mjs +186 -8
- package/tools/plugin/plugin-links.mjs +114 -0
- package/tools/providers/antigravity-transport.mjs +3 -1
- package/tools/providers/deepseek-harness-transport.mjs +360 -0
- package/tools/providers/omp-transport.mjs +194 -0
- package/tools/ralph-external/lib/claude-adapter.mjs +389 -0
- package/tools/ralph-external/lib/codex-adapter.mjs +432 -0
- package/tools/ralph-external/lib/consecutive-failure-circuit-breaker.mjs +1748 -0
- package/tools/ralph-external/lib/deepseek-harness-adapter.mjs +397 -0
- package/tools/ralph-external/lib/factory-adapter.mjs +503 -0
- package/tools/ralph-external/lib/launcher-recovery-evidence.mjs +55 -0
- package/tools/ralph-external/lib/muse-adapter.mjs +364 -0
- package/tools/ralph-external/lib/omp-adapter.mjs +315 -0
- package/tools/ralph-external/lib/opencode-adapter.mjs +575 -0
- package/tools/ralph-external/lib/openhuman-adapter.mjs +75 -0
- package/tools/ralph-external/lib/pi-adapter.mjs +329 -0
- package/tools/ralph-external/lib/provider-adapter.mjs +748 -0
- package/tools/ralph-external/lib/recovery-probe.mjs +72 -0
- package/tools/ralph-external/lib/session-environment.mjs +28 -0
- package/tools/ralph-external/lib/systemd-client.mjs +49 -0
- package/tools/ralph-external/lib/worker-health.mjs +439 -0
- package/tools/ralph-external/lib/worker-isolation.mjs +717 -0
- package/tools/ralph-external/lib/worker-overflow.mjs +50 -0
- package/tools/ralph-external/process-monitor.mjs +1017 -0
- package/tools/ralph-external/session-launcher.mjs +5057 -0
- package/tools/scripts/resource-preflight.mjs +541 -0
- package/tools/skills/deploy-skills-codex.mjs +2 -1
- package/vscode-extension/schemas/aiwg.config.v1.json +2916 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { lstat, readFile, realpath, stat } from 'node:fs/promises';
|
|
2
|
+
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
3
|
+
export const WORKSPACE_MATCH_KINDS = ['exact', 'subfolder', 'worktree'];
|
|
4
|
+
/** A nested catalog owns its subtree, even when discovery runs one workspace at a time. */
|
|
5
|
+
export async function matchSessionWorkspace(cwd, workspace) {
|
|
6
|
+
try {
|
|
7
|
+
const { path: candidate, missing } = await resolveCandidate(resolve(cwd));
|
|
8
|
+
const workspacePath = await realpath(resolve(workspace));
|
|
9
|
+
const direct = encloses(workspacePath, candidate);
|
|
10
|
+
if (missing && !direct)
|
|
11
|
+
return null;
|
|
12
|
+
const physicalCatalog = await nearestCatalogBetween(candidate, direct ? workspacePath : undefined);
|
|
13
|
+
if (physicalCatalog && !encloses(physicalCatalog, workspacePath))
|
|
14
|
+
return null;
|
|
15
|
+
const mainRepository = await worktreeMainRepository(candidate).catch(() => null);
|
|
16
|
+
// A worktree also belongs to a deeper catalog around its main repository,
|
|
17
|
+
// including when both paths sit beneath the workspace being discovered.
|
|
18
|
+
if (mainRepository && encloses(workspacePath, mainRepository)
|
|
19
|
+
&& await nearestCatalogBetween(mainRepository, workspacePath))
|
|
20
|
+
return null;
|
|
21
|
+
if (direct)
|
|
22
|
+
return candidate === workspacePath ? 'exact' : 'subfolder';
|
|
23
|
+
if (!mainRepository || !encloses(workspacePath, mainRepository))
|
|
24
|
+
return null;
|
|
25
|
+
return 'worktree';
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// Unresolved paths or Git metadata cannot establish workspace ownership.
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function resolveCandidate(path) {
|
|
33
|
+
let ancestor = path;
|
|
34
|
+
const suffix = [];
|
|
35
|
+
for (;;) {
|
|
36
|
+
try {
|
|
37
|
+
// Stop at symlinks too, so realpath rejects dangling links below.
|
|
38
|
+
await lstat(ancestor);
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
if (error.code !== 'ENOENT')
|
|
43
|
+
throw error;
|
|
44
|
+
const parent = dirname(ancestor);
|
|
45
|
+
if (parent === ancestor)
|
|
46
|
+
throw error;
|
|
47
|
+
suffix.unshift(basename(ancestor));
|
|
48
|
+
ancestor = parent;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return { path: join(await realpath(ancestor), ...suffix), missing: suffix.length > 0 };
|
|
52
|
+
}
|
|
53
|
+
function encloses(parent, child) {
|
|
54
|
+
const suffix = relative(parent, child);
|
|
55
|
+
return suffix === '' || (!isAbsolute(suffix) && suffix !== '..' && !suffix.startsWith(`..${sep}`));
|
|
56
|
+
}
|
|
57
|
+
async function nearestCatalogBetween(candidate, stop) {
|
|
58
|
+
for (let directory = candidate; directory !== stop; directory = dirname(directory)) {
|
|
59
|
+
const catalog = await statIfPresent(join(directory, '.aiwg', 'sessions'));
|
|
60
|
+
if (catalog?.isDirectory())
|
|
61
|
+
return directory;
|
|
62
|
+
if (directory === dirname(directory))
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
async function worktreeMainRepository(candidate) {
|
|
68
|
+
for (let directory = candidate;; directory = dirname(directory)) {
|
|
69
|
+
const marker = join(directory, '.git');
|
|
70
|
+
const details = await statIfPresent(marker);
|
|
71
|
+
if (details) {
|
|
72
|
+
// Stop at the nearest repository; a normal repository or submodule
|
|
73
|
+
// must not inherit an outer worktree's ownership.
|
|
74
|
+
if (!details.isFile())
|
|
75
|
+
return null;
|
|
76
|
+
const gitfile = /^gitdir: (.+)\s*$/.exec((await readFile(marker, 'utf8')).trim());
|
|
77
|
+
if (!gitfile)
|
|
78
|
+
return null;
|
|
79
|
+
const gitdir = await realpath(resolve(directory, gitfile[1].trim()));
|
|
80
|
+
const common = (await readFile(join(gitdir, 'commondir'), 'utf8')).trim();
|
|
81
|
+
if (!common)
|
|
82
|
+
return null;
|
|
83
|
+
const commonDir = await realpath(resolve(gitdir, common));
|
|
84
|
+
const backlink = (await readFile(join(gitdir, 'gitdir'), 'utf8')).trim();
|
|
85
|
+
if (!backlink || await realpath(resolve(gitdir, backlink)) !== await realpath(marker))
|
|
86
|
+
return null;
|
|
87
|
+
// Standard linked worktrees share the main repository's .git directory.
|
|
88
|
+
if (basename(commonDir) !== '.git' || commonDir === gitdir)
|
|
89
|
+
return null;
|
|
90
|
+
const mainRepository = dirname(commonDir);
|
|
91
|
+
return await realpath(join(mainRepository, '.git')) === commonDir ? mainRepository : null;
|
|
92
|
+
}
|
|
93
|
+
if (directory === dirname(directory))
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async function statIfPresent(path) {
|
|
98
|
+
try {
|
|
99
|
+
return await stat(path);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
if (['ENOENT', 'ENOTDIR'].includes(error.code ?? ''))
|
|
103
|
+
return null;
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=workspace-matching.js.map
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
* @see https://clawhub.ai
|
|
12
12
|
* @see https://docs.openclaw.ai/tools/clawhub
|
|
13
13
|
*/
|
|
14
|
-
import {
|
|
14
|
+
import { boundedExecFileSync } from '../../process/bounded-child-process.mjs';
|
|
15
|
+
import { cliCommand } from '../../process/cli-command.mjs';
|
|
15
16
|
import fs from 'fs';
|
|
16
17
|
import path from 'path';
|
|
17
18
|
import { getProviderDefinition, resolveProviderPathValue, } from '../../providers/provider-definitions.js';
|
|
@@ -47,7 +48,8 @@ async function clawHubFetch(endpoint) {
|
|
|
47
48
|
*/
|
|
48
49
|
function runClawHub(args) {
|
|
49
50
|
try {
|
|
50
|
-
|
|
51
|
+
const [file, argv] = cliCommand('clawhub', args);
|
|
52
|
+
return boundedExecFileSync(file, argv, 'quick', {
|
|
51
53
|
encoding: 'utf-8',
|
|
52
54
|
timeout: 30000,
|
|
53
55
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
@@ -65,7 +67,7 @@ export class ClawHubAdapter {
|
|
|
65
67
|
if (this.available !== null)
|
|
66
68
|
return this.available;
|
|
67
69
|
// Check CLI
|
|
68
|
-
const cliAvailable = runClawHub('--version
|
|
70
|
+
const cliAvailable = runClawHub(['--version']) !== null;
|
|
69
71
|
if (cliAvailable) {
|
|
70
72
|
this.available = true;
|
|
71
73
|
return true;
|
|
@@ -89,7 +91,7 @@ export class ClawHubAdapter {
|
|
|
89
91
|
}));
|
|
90
92
|
}
|
|
91
93
|
// Try CLI
|
|
92
|
-
const cliOutput = runClawHub(
|
|
94
|
+
const cliOutput = runClawHub(['search', query, '--json']);
|
|
93
95
|
if (cliOutput) {
|
|
94
96
|
try {
|
|
95
97
|
const parsed = JSON.parse(cliOutput);
|
|
@@ -127,7 +129,7 @@ export class ClawHubAdapter {
|
|
|
127
129
|
};
|
|
128
130
|
}
|
|
129
131
|
// Try CLI
|
|
130
|
-
const cliOutput = runClawHub(
|
|
132
|
+
const cliOutput = runClawHub(['info', name, '--json']);
|
|
131
133
|
if (cliOutput) {
|
|
132
134
|
try {
|
|
133
135
|
const parsed = JSON.parse(cliOutput);
|
|
@@ -162,7 +164,7 @@ export class ClawHubAdapter {
|
|
|
162
164
|
}));
|
|
163
165
|
}
|
|
164
166
|
// Try CLI
|
|
165
|
-
const cliOutput = runClawHub('list --json
|
|
167
|
+
const cliOutput = runClawHub(['list', '--json']);
|
|
166
168
|
if (cliOutput) {
|
|
167
169
|
try {
|
|
168
170
|
const parsed = JSON.parse(cliOutput);
|
|
@@ -195,7 +197,7 @@ export class ClawHubAdapter {
|
|
|
195
197
|
targetDir = resolveSkillFallbackPath(target, options.projectDir, name);
|
|
196
198
|
}
|
|
197
199
|
// Try CLI install (downloads to a temp location, then we copy)
|
|
198
|
-
const cliResult = runClawHub(
|
|
200
|
+
const cliResult = runClawHub(['install', name, '--output', targetDir]);
|
|
199
201
|
if (cliResult !== null)
|
|
200
202
|
return;
|
|
201
203
|
// Try API download
|
|
@@ -240,7 +242,7 @@ export class ClawHubAdapter {
|
|
|
240
242
|
}
|
|
241
243
|
}
|
|
242
244
|
// Try CLI publish
|
|
243
|
-
const cliResult = runClawHub(
|
|
245
|
+
const cliResult = runClawHub(['publish', packageDir]);
|
|
244
246
|
if (cliResult !== null)
|
|
245
247
|
return;
|
|
246
248
|
throw new Error('ClawHub publish requires the clawhub CLI. ' +
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* @implements #539
|
|
9
9
|
* @see https://docs.openclaw.ai
|
|
10
10
|
*/
|
|
11
|
-
import {
|
|
11
|
+
import { boundedExecFileSync } from '../../process/bounded-child-process.mjs';
|
|
12
|
+
import { cliCommand } from '../../process/cli-command.mjs';
|
|
12
13
|
import fs from 'fs';
|
|
13
14
|
import path from 'path';
|
|
14
15
|
import { getProviderDefinition, resolveProviderPathValue, } from '../../providers/provider-definitions.js';
|
|
@@ -26,7 +27,8 @@ function resolveSkillFallbackPath(target, projectDir, name) {
|
|
|
26
27
|
*/
|
|
27
28
|
function runOpenClaw(args) {
|
|
28
29
|
try {
|
|
29
|
-
|
|
30
|
+
const [file, argv] = cliCommand('openclaw', args);
|
|
31
|
+
return boundedExecFileSync(file, argv, 'quick', {
|
|
30
32
|
encoding: 'utf-8',
|
|
31
33
|
timeout: 30000,
|
|
32
34
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
@@ -142,7 +144,8 @@ export class OpenClawAdapter {
|
|
|
142
144
|
if (fs.existsSync(openclawDir))
|
|
143
145
|
return true;
|
|
144
146
|
try {
|
|
145
|
-
|
|
147
|
+
const [file, args] = cliCommand('openclaw', ['--version']);
|
|
148
|
+
boundedExecFileSync(file, args, 'quick', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] });
|
|
146
149
|
return true;
|
|
147
150
|
}
|
|
148
151
|
catch {
|
|
@@ -153,7 +156,7 @@ export class OpenClawAdapter {
|
|
|
153
156
|
if (this.cachedSkills)
|
|
154
157
|
return this.cachedSkills;
|
|
155
158
|
// Try openclaw CLI with JSON output first
|
|
156
|
-
const jsonOutput = runOpenClaw('skills list --json
|
|
159
|
+
const jsonOutput = runOpenClaw(['skills', 'list', '--json']);
|
|
157
160
|
if (jsonOutput) {
|
|
158
161
|
try {
|
|
159
162
|
const parsed = JSON.parse(jsonOutput);
|
|
@@ -178,7 +181,7 @@ export class OpenClawAdapter {
|
|
|
178
181
|
}
|
|
179
182
|
async search(query) {
|
|
180
183
|
// Try CLI delegation first
|
|
181
|
-
const cliOutput = runOpenClaw(
|
|
184
|
+
const cliOutput = runOpenClaw(['skills', 'search', query, '--json']);
|
|
182
185
|
if (cliOutput) {
|
|
183
186
|
try {
|
|
184
187
|
const parsed = JSON.parse(cliOutput);
|
|
@@ -207,7 +210,7 @@ export class OpenClawAdapter {
|
|
|
207
210
|
const skillMdPath = skillDir ? path.join(skillDir, 'SKILL.md') : '';
|
|
208
211
|
if (!skillMdPath || !fs.existsSync(skillMdPath)) {
|
|
209
212
|
// Try CLI
|
|
210
|
-
const cliOutput = runOpenClaw(
|
|
213
|
+
const cliOutput = runOpenClaw(['skills', 'info', name, '--json']);
|
|
211
214
|
if (cliOutput) {
|
|
212
215
|
try {
|
|
213
216
|
const parsed = JSON.parse(cliOutput);
|
|
@@ -268,7 +271,7 @@ export class OpenClawAdapter {
|
|
|
268
271
|
}
|
|
269
272
|
async install(name, options) {
|
|
270
273
|
// Try openclaw CLI install first
|
|
271
|
-
const cliResult = runOpenClaw(
|
|
274
|
+
const cliResult = runOpenClaw(['skills', 'install', name]);
|
|
272
275
|
if (cliResult !== null) {
|
|
273
276
|
// CLI handled it — if target is different from openclaw, copy to target
|
|
274
277
|
if (options.target && options.target !== 'openclaw') {
|
|
@@ -178,6 +178,7 @@ function runGit(args, options = {}) {
|
|
|
178
178
|
maxBuffer: options.maxBuffer ?? 16 * 1024 * 1024,
|
|
179
179
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
180
180
|
timeout: 120_000,
|
|
181
|
+
killSignal: 'SIGKILL',
|
|
181
182
|
});
|
|
182
183
|
if (result.error) {
|
|
183
184
|
if (result.error.code === 'ETIMEDOUT') {
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
import { promises as fs } from 'node:fs';
|
|
18
18
|
import * as path from 'node:path';
|
|
19
19
|
import { projectControlPath } from '../../config/project-artifacts.js';
|
|
20
|
+
import { buildClaudeHookBlock, CLAUDE_HOOK_START, CLAUDE_HOOK_END } from './claude-hook.js';
|
|
21
|
+
import { dominantLineEnding, withLineEnding } from './line-endings.js';
|
|
20
22
|
import { buildParallelismSection, replaceOrAppendParallelismBlock } from './parallelism-section.js';
|
|
21
23
|
import { buildContextFinalizationBlock, replaceOrAppendFinalizationBlock } from './finalization.js';
|
|
22
24
|
import { buildExternalLinksSection, replaceOrAppendExternalLinksBlock, } from './external-links-section.js';
|
|
@@ -55,6 +57,15 @@ export async function buildAiwgMdContent(projectPath, stagedClaudeMdContent) {
|
|
|
55
57
|
if (claudeMdContent) {
|
|
56
58
|
// Insert the AIWG signature comment as the second line.
|
|
57
59
|
// Top line is typically `# AIWG` or `# Project` heading; preserve it.
|
|
60
|
+
// Regenerate may mirror CLAUDE.md before its hook updater runs. Normalize
|
|
61
|
+
// that managed block here too so legacy duplicate policy never reaches
|
|
62
|
+
// AIWG.md, even on the first refresh. Operator content stays untouched.
|
|
63
|
+
const start = claudeMdContent.indexOf(CLAUDE_HOOK_START);
|
|
64
|
+
const end = claudeMdContent.indexOf(CLAUDE_HOOK_END, start);
|
|
65
|
+
if (start >= 0 && end >= start) {
|
|
66
|
+
const hook = withLineEnding(buildClaudeHookBlock(), dominantLineEnding(claudeMdContent));
|
|
67
|
+
claudeMdContent = claudeMdContent.slice(0, start) + hook + claudeMdContent.slice(end + CLAUDE_HOOK_END.length);
|
|
68
|
+
}
|
|
58
69
|
const lines = claudeMdContent.split('\n');
|
|
59
70
|
// #1268: strip `@AIWG.md` self-include directives. CLAUDE.md uses
|
|
60
71
|
// `@AIWG.md` to pull in the framework context; AIWG.md IS that framework
|
|
@@ -26,29 +26,14 @@ import { dominantLineEnding, withLineEnding } from './line-endings.js';
|
|
|
26
26
|
import { assertSafeContextFile } from './context-file-safety.js';
|
|
27
27
|
export const CLAUDE_HOOK_START = '<!-- AIWG:claude-md-hook:start -->';
|
|
28
28
|
export const CLAUDE_HOOK_END = '<!-- AIWG:claude-md-hook:end -->';
|
|
29
|
-
function
|
|
30
|
-
const providerNative = policy.provider_native ?? 'explicit-only';
|
|
31
|
-
const design = policy.destinations?.['claude-code.design'];
|
|
32
|
-
const designEnabled = design?.enabled !== false && design?.use_when !== 'disabled';
|
|
33
|
-
return [
|
|
34
|
-
'## AIWG artifact output policy',
|
|
35
|
-
'',
|
|
36
|
-
`- Canonical durable artifacts: AIWG artifact store (policy: ${policy.canonical ?? 'aiwg'}).`,
|
|
37
|
-
`- Provider-native presentation/export: ${providerNative}.`,
|
|
38
|
-
`- Claude Design: ${designEnabled ? 'available only when explicitly selected by the resolved policy or requested by the user' : 'disabled by project policy'}.`,
|
|
39
|
-
'- Never substitute, relocate, or omit the canonical AIWG plan/review artifact because Claude adds or changes a provider default.',
|
|
40
|
-
'- When both canonical and presentation outputs are selected, write the canonical artifact first; treat Design as a derived export and record provenance linking it to the canonical source of truth.',
|
|
41
|
-
'- Unknown provider-native destinations fail safe with a diagnostic. Higher-authority project policy overrides user preferences; explicit task selection overrides provider defaults only within the project policy ceiling.',
|
|
42
|
-
];
|
|
43
|
-
}
|
|
44
|
-
export function buildClaudeHookBlock(policy = {}) {
|
|
29
|
+
export function buildClaudeHookBlock(_policy = {}) {
|
|
45
30
|
return [
|
|
46
31
|
CLAUDE_HOOK_START,
|
|
47
32
|
'',
|
|
48
33
|
buildProviderBootstrapBlock('claude'),
|
|
49
34
|
'@.aiwg/aiwg.config',
|
|
50
35
|
'',
|
|
51
|
-
|
|
36
|
+
'Artifact destination authority: `aiwg show rule artifact-output-policy` (kernel).',
|
|
52
37
|
'',
|
|
53
38
|
'<!--',
|
|
54
39
|
' This block is managed by `aiwg regenerate` and `aiwg use`.',
|
|
@@ -72,15 +57,7 @@ export async function ensureClaudeMdHook(projectPath, opts = {}) {
|
|
|
72
57
|
action: 'skipped',
|
|
73
58
|
warnings: [],
|
|
74
59
|
};
|
|
75
|
-
let
|
|
76
|
-
try {
|
|
77
|
-
const config = JSON.parse(await fs.readFile(path.join(projectPath, '.aiwg', 'aiwg.config'), 'utf8'));
|
|
78
|
-
policy = config.artifact_outputs ?? {};
|
|
79
|
-
}
|
|
80
|
-
catch {
|
|
81
|
-
// Missing/legacy/temporarily malformed config receives the safe default.
|
|
82
|
-
}
|
|
83
|
-
let block = buildClaudeHookBlock(policy);
|
|
60
|
+
let block = buildClaudeHookBlock();
|
|
84
61
|
// Case 1: CLAUDE.md does not exist — create a minimal one with just the block.
|
|
85
62
|
let existing;
|
|
86
63
|
try {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Context-finalization pass for generated provider context files.
|
|
3
3
|
*
|
|
4
4
|
* Templates provide the stable structure; this pass stitches in current
|
|
5
|
-
* workspace facts from `.aiwg/aiwg.config` and
|
|
5
|
+
* workspace facts from `.aiwg/aiwg.config` and rule authority pointers so
|
|
6
6
|
* provider context files do not remain template-only (#1365).
|
|
7
7
|
*/
|
|
8
8
|
import { promises as fs } from 'node:fs';
|
|
@@ -10,6 +10,7 @@ import * as path from 'node:path';
|
|
|
10
10
|
import { projectAiwgPath, projectControlPath, resolveProjectAiwgDir, } from '../../config/project-artifacts.js';
|
|
11
11
|
import { renderTrackerProtocol, resolveTrackerAuthority } from '../../tracker/capability-protocol.js';
|
|
12
12
|
import { readConfig, readGitRemoteUrls } from '../../tracker/project-inputs.js';
|
|
13
|
+
import { DECISION_COMPACT_ANCHOR, inspectDecisionOffloadActivation } from '../../decision/offload-activation.js';
|
|
13
14
|
import { buildExternalLinksSection, replaceOrAppendExternalLinksBlock, } from './external-links-section.js';
|
|
14
15
|
export const FINALIZATION_START = '<!-- aiwg-context-finalization:START -->';
|
|
15
16
|
export const FINALIZATION_END = '<!-- aiwg-context-finalization:END -->';
|
|
@@ -52,6 +53,7 @@ export async function buildContextFinalizationBlock(projectPath, documentPath =
|
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
const trackerAuthority = resolveTrackerAuthority(config, remoteUrls);
|
|
56
|
+
const decision = await inspectDecisionOffloadActivation({ cwd: projectPath });
|
|
55
57
|
const lines = [
|
|
56
58
|
FINALIZATION_START,
|
|
57
59
|
'## Context Finalization',
|
|
@@ -65,11 +67,9 @@ export async function buildContextFinalizationBlock(projectPath, documentPath =
|
|
|
65
67
|
`- Recorded deployments: ${formatList([...providerDeployments].sort())}`,
|
|
66
68
|
`- Normalized project context: \`${normalizedAiwgMdPath}\``,
|
|
67
69
|
'',
|
|
68
|
-
'###
|
|
70
|
+
'### Capability Routing',
|
|
69
71
|
'',
|
|
70
|
-
'
|
|
71
|
-
'',
|
|
72
|
-
'Also run `aiwg discover` before declining an AIWG request as out of scope or inventing a workflow from memory. The CLI ranks AIWG capabilities across the installed corpus and rebuilds the index from `$AIWG_ROOT` automatically, so a "no matches" for a command you know is deployed is a bug — not a signal it is absent. Commands AIWG deploys to your provider command directory (`.opencode/command/`, `.claude/commands/`, `~/.codex/prompts/`, …) ARE discoverable this way; fetch them with `aiwg show command <name>`. This prevents decline-without-search failures, ask-instead-of-act on new directives, and hallucinated skill or agent names. Full rule: `agentic/code/addons/aiwg-utils/rules/skill-discovery.md`.',
|
|
72
|
+
'Routing authority: `aiwg show rule skill-discovery` (kernel); capability phrases: `aiwg show skill aiwg-utils-quickref`.',
|
|
73
73
|
'',
|
|
74
74
|
'### Engagement Verification',
|
|
75
75
|
'',
|
|
@@ -84,6 +84,7 @@ export async function buildContextFinalizationBlock(projectPath, documentPath =
|
|
|
84
84
|
`- ${normalizedAiwgMdLabel} is the normalized project-local context entry point.`,
|
|
85
85
|
'- Root `AIWG.md` is the generated cross-provider companion loaded through `AGENTS.md` and provider twins.',
|
|
86
86
|
`- \`AGENTS.md\`, \`WARP.md\`, \`.hermes.md\`, and \`.github/copilot-instructions.md\` are provider-facing bridges, not replacements for ${normalizedAiwgMdLabel}.`,
|
|
87
|
+
...(decision.shouldAnchor ? ['', '## Compact Instructions', '', DECISION_COMPACT_ANCHOR] : []),
|
|
87
88
|
FINALIZATION_END,
|
|
88
89
|
'',
|
|
89
90
|
];
|
|
@@ -199,7 +199,24 @@ export async function isOverwriteSafe(filePath) {
|
|
|
199
199
|
*
|
|
200
200
|
* Per ADR-4 §4 atomic write requirement; on failure no partial state is persisted.
|
|
201
201
|
*/
|
|
202
|
-
async function atomicWrite(filePath, content) {
|
|
202
|
+
async function atomicWrite(filePath, content, provider) {
|
|
203
|
+
// Rule delivery owns this block. Context regeneration runs after deployment
|
|
204
|
+
// and must retain the selected kernel even when rebuilding the adapter.
|
|
205
|
+
const existing = await fs.readFile(filePath, 'utf8').catch(() => '');
|
|
206
|
+
for (const owner of ['rule-startup', 'hermes-context', 'hermes-routing', 'warp-context']) {
|
|
207
|
+
if (content.includes(`<!-- AIWG:${owner}:start -->`))
|
|
208
|
+
continue;
|
|
209
|
+
const managed = existing.match(new RegExp(`<!-- AIWG:${owner}:start -->[\\s\\S]*?<!-- AIWG:${owner}:end -->`));
|
|
210
|
+
if (managed)
|
|
211
|
+
content = `${content.trimEnd()}\n\n${managed[0]}\n`;
|
|
212
|
+
}
|
|
213
|
+
const bytes = Buffer.byteLength(content, 'utf8');
|
|
214
|
+
if (provider === 'codex' && path.basename(filePath) === 'AGENTS.md' && bytes >= 32768) {
|
|
215
|
+
throw new Error('Codex AGENTS.md exceeds its 32 KB hard cap');
|
|
216
|
+
}
|
|
217
|
+
if (provider === 'hermes' && ['AGENTS.md', '.hermes.md'].includes(path.basename(filePath)) && content.length > 19000) {
|
|
218
|
+
throw new Error(`Hermes ${path.basename(filePath)} exceeds hard cap of 19000 characters`);
|
|
219
|
+
}
|
|
203
220
|
const dir = path.dirname(filePath);
|
|
204
221
|
const tmp = path.join(dir, `.${path.basename(filePath)}.tmp.${process.pid}`);
|
|
205
222
|
await fs.mkdir(dir, { recursive: true });
|
|
@@ -212,6 +229,7 @@ async function atomicWrite(filePath, content) {
|
|
|
212
229
|
await fs.unlink(tmp).catch(() => undefined);
|
|
213
230
|
throw err;
|
|
214
231
|
}
|
|
232
|
+
return bytes;
|
|
215
233
|
}
|
|
216
234
|
/**
|
|
217
235
|
* Per-provider twin-file names for AGENTS.md emission per ADR-1 §4.
|
|
@@ -303,7 +321,7 @@ async function writeTwinFiles(provider, projectPath, agentsMdContent, opts, resu
|
|
|
303
321
|
throw err;
|
|
304
322
|
}
|
|
305
323
|
}
|
|
306
|
-
await atomicWrite(twinPath, twinContent);
|
|
324
|
+
await atomicWrite(twinPath, twinContent, provider);
|
|
307
325
|
result.twinPaths.push(twinPath);
|
|
308
326
|
}
|
|
309
327
|
}
|
|
@@ -408,9 +426,8 @@ export async function generate(opts) {
|
|
|
408
426
|
// write, and as the twin content downstream.
|
|
409
427
|
const built = await buildAgentsMd(opts);
|
|
410
428
|
if (canWrite) {
|
|
411
|
-
await atomicWrite(agentsMdPath, built.content);
|
|
429
|
+
result.agentsMdBytes = await atomicWrite(agentsMdPath, built.content, opts.provider);
|
|
412
430
|
result.agentsMdPath = agentsMdPath;
|
|
413
|
-
result.agentsMdBytes = Buffer.byteLength(built.content, 'utf8');
|
|
414
431
|
result.warnings.push(...built.warnings);
|
|
415
432
|
if (built.splitOccurred) {
|
|
416
433
|
await writeSpilloverBlock(opts.projectPath, built.spilloverContent, result);
|