@aperant/framework 0.8.0 → 0.8.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/CHANGELOG.md +311 -1
- package/README.md +12 -0
- package/agents/apt-planner.md +5 -4
- package/dist/cli/commands/adr.mjs +1 -1
- package/dist/cli/commands/audit-branch-current.d.mts +25 -0
- package/dist/cli/commands/audit-branch-current.d.mts.map +1 -0
- package/dist/cli/commands/audit-branch-current.mjs +252 -0
- package/dist/cli/commands/audit-branch-current.mjs.map +1 -0
- package/dist/cli/commands/audit.d.mts.map +1 -1
- package/dist/cli/commands/audit.mjs +13 -2
- package/dist/cli/commands/audit.mjs.map +1 -1
- package/dist/cli/commands/check-version.d.mts.map +1 -1
- package/dist/cli/commands/check-version.mjs +19 -1
- package/dist/cli/commands/check-version.mjs.map +1 -1
- package/dist/cli/commands/context.mjs +3 -3
- package/dist/cli/commands/context.mjs.map +1 -1
- package/dist/cli/commands/detect-runtime.d.mts +6 -0
- package/dist/cli/commands/detect-runtime.d.mts.map +1 -0
- package/dist/cli/commands/detect-runtime.mjs +136 -0
- package/dist/cli/commands/detect-runtime.mjs.map +1 -0
- package/dist/cli/commands/driver-doctor.d.mts +29 -0
- package/dist/cli/commands/driver-doctor.d.mts.map +1 -0
- package/dist/cli/commands/driver-doctor.mjs +291 -0
- package/dist/cli/commands/driver-doctor.mjs.map +1 -0
- package/dist/cli/commands/gate.mjs +14 -0
- package/dist/cli/commands/gate.mjs.map +1 -1
- package/dist/cli/commands/init.d.mts.map +1 -1
- package/dist/cli/commands/init.mjs +76 -33
- package/dist/cli/commands/init.mjs.map +1 -1
- package/dist/cli/commands/install-from-source.d.mts +2 -0
- package/dist/cli/commands/install-from-source.d.mts.map +1 -0
- package/dist/cli/commands/install-from-source.mjs +2 -0
- package/dist/cli/commands/install-from-source.mjs.map +1 -0
- package/dist/cli/commands/modes.mjs +1 -1
- package/dist/cli/commands/route.d.mts.map +1 -1
- package/dist/cli/commands/route.mjs +38 -1
- package/dist/cli/commands/route.mjs.map +1 -1
- package/dist/cli/commands/triage.mjs +1 -1
- package/dist/cli/config/load.d.mts.map +1 -1
- package/dist/cli/config/load.mjs +9 -3
- package/dist/cli/config/load.mjs.map +1 -1
- package/dist/cli/coordination/auto-emit-artifact-ready.mjs +1 -1
- package/dist/cli/coordination/event-schema.d.mts.map +1 -1
- package/dist/cli/coordination/event-schema.mjs +18 -0
- package/dist/cli/coordination/event-schema.mjs.map +1 -1
- package/dist/cli/design/frontmatter-schema.d.mts +4 -4
- package/dist/cli/dispatch.d.mts.map +1 -1
- package/dist/cli/dispatch.mjs +18 -1
- package/dist/cli/dispatch.mjs.map +1 -1
- package/dist/cli/gate/context.d.mts +1 -0
- package/dist/cli/gate/context.d.mts.map +1 -1
- package/dist/cli/gate/context.mjs +14 -1
- package/dist/cli/gate/context.mjs.map +1 -1
- package/dist/cli/gate/gates/consistency-check.d.mts +1 -0
- package/dist/cli/gate/gates/consistency-check.d.mts.map +1 -1
- package/dist/cli/gate/gates/consistency-check.mjs +1 -0
- package/dist/cli/gate/gates/consistency-check.mjs.map +1 -1
- package/dist/cli/gate/gates/review-clean.d.mts +1 -0
- package/dist/cli/gate/gates/review-clean.d.mts.map +1 -1
- package/dist/cli/gate/gates/review-clean.mjs +1 -0
- package/dist/cli/gate/gates/review-clean.mjs.map +1 -1
- package/dist/cli/gate/gates/verify-approved.d.mts +1 -0
- package/dist/cli/gate/gates/verify-approved.d.mts.map +1 -1
- package/dist/cli/gate/gates/verify-approved.mjs +1 -0
- package/dist/cli/gate/gates/verify-approved.mjs.map +1 -1
- package/dist/cli/gate/registry.d.mts.map +1 -1
- package/dist/cli/gate/registry.mjs +9 -1
- package/dist/cli/gate/registry.mjs.map +1 -1
- package/dist/cli/install/cli-to-install-root.d.mts.map +1 -1
- package/dist/cli/install/cli-to-install-root.mjs +0 -2
- package/dist/cli/install/cli-to-install-root.mjs.map +1 -1
- package/dist/cli/install/find-workspace-framework-version.d.mts +16 -0
- package/dist/cli/install/find-workspace-framework-version.d.mts.map +1 -0
- package/dist/cli/install/find-workspace-framework-version.mjs +85 -0
- package/dist/cli/install/find-workspace-framework-version.mjs.map +1 -0
- package/dist/cli/install/install-from-source.d.mts +10 -0
- package/dist/cli/install/install-from-source.d.mts.map +1 -0
- package/dist/cli/install/install-from-source.mjs +271 -0
- package/dist/cli/install/install-from-source.mjs.map +1 -0
- package/dist/cli/install/install-kernel.d.mts.map +1 -1
- package/dist/cli/install/install-kernel.mjs +24 -0
- package/dist/cli/install/install-kernel.mjs.map +1 -1
- package/dist/cli/install/legacy-paths.d.mts +33 -11
- package/dist/cli/install/legacy-paths.d.mts.map +1 -1
- package/dist/cli/install/legacy-paths.mjs +161 -39
- package/dist/cli/install/legacy-paths.mjs.map +1 -1
- package/dist/cli/install/runtime-detect.d.mts +2 -6
- package/dist/cli/install/runtime-detect.d.mts.map +1 -1
- package/dist/cli/install/runtime-detect.mjs +9 -4
- package/dist/cli/install/runtime-detect.mjs.map +1 -1
- package/dist/cli/install/runtime-migrate.d.mts +34 -14
- package/dist/cli/install/runtime-migrate.d.mts.map +1 -1
- package/dist/cli/install/runtime-migrate.mjs +63 -30
- package/dist/cli/install/runtime-migrate.mjs.map +1 -1
- package/dist/cli/install/transforms/codex.d.mts.map +1 -1
- package/dist/cli/install/transforms/codex.mjs +28 -17
- package/dist/cli/install/transforms/codex.mjs.map +1 -1
- package/dist/cli/install/transforms/pi.d.mts +6 -0
- package/dist/cli/install/transforms/pi.d.mts.map +1 -0
- package/dist/cli/install/transforms/pi.mjs +37 -0
- package/dist/cli/install/transforms/pi.mjs.map +1 -0
- package/dist/cli/personas/sidecar.d.mts +1 -1
- package/dist/cli/roadmap/lifecycle.d.mts +1 -1
- package/dist/cli/roadmap/rollup.d.mts +2 -2
- package/dist/cli/skill-author/contract.mjs +2 -2
- package/dist/cli/skill-author/contract.mjs.map +1 -1
- package/dist/cli/verify-proof/audit.d.mts +34 -0
- package/dist/cli/verify-proof/audit.d.mts.map +1 -0
- package/dist/cli/verify-proof/audit.mjs +53 -0
- package/dist/cli/verify-proof/audit.mjs.map +1 -0
- package/dist/cli/verify-proof/exec.d.mts +20 -0
- package/dist/cli/verify-proof/exec.d.mts.map +1 -0
- package/dist/cli/verify-proof/exec.mjs +74 -0
- package/dist/cli/verify-proof/exec.mjs.map +1 -0
- package/dist/cli/verify-proof/idl/index.d.mts +2 -0
- package/dist/cli/verify-proof/idl/index.d.mts.map +1 -0
- package/dist/cli/verify-proof/idl/index.mjs +14 -0
- package/dist/cli/verify-proof/idl/index.mjs.map +1 -0
- package/dist/cli/verify-proof/idl/types.d.ts +9 -0
- package/dist/cli/verify-proof/idl/types.d.ts.map +1 -0
- package/dist/cli/verify-proof/idl/types.js +9 -0
- package/dist/cli/verify-proof/idl/types.js.map +1 -0
- package/dist/cli/verify-proof/manifest-validator.d.mts +19 -0
- package/dist/cli/verify-proof/manifest-validator.d.mts.map +1 -0
- package/dist/cli/verify-proof/manifest-validator.mjs +182 -0
- package/dist/cli/verify-proof/manifest-validator.mjs.map +1 -0
- package/dist/cli/verify-proof/resolver.d.mts +43 -0
- package/dist/cli/verify-proof/resolver.d.mts.map +1 -0
- package/dist/cli/verify-proof/resolver.mjs +160 -0
- package/dist/cli/verify-proof/resolver.mjs.map +1 -0
- package/dist/cli/verify-proof/runtime-detect.d.mts +27 -0
- package/dist/cli/verify-proof/runtime-detect.d.mts.map +1 -0
- package/dist/cli/verify-proof/runtime-detect.mjs +116 -0
- package/dist/cli/verify-proof/runtime-detect.mjs.map +1 -0
- package/dist/cli/verify-proof/trust.d.mts +70 -0
- package/dist/cli/verify-proof/trust.d.mts.map +1 -0
- package/dist/cli/verify-proof/trust.mjs +174 -0
- package/dist/cli/verify-proof/trust.mjs.map +1 -0
- package/dist/plugin/.claude-plugin/plugin.json +4 -1
- package/dist/plugin/agents/apt-executor.md +12 -0
- package/dist/plugin/agents/apt-planner.md +5 -4
- package/dist/plugin/agents/apt-team-docs-narrator.md +11 -0
- package/dist/plugin/skills/apt/SKILL.md +78 -8
- package/dist/plugin/skills/apt-caveman/SKILL.md +64 -0
- package/dist/plugin/skills/apt-debug/SKILL.md +36 -4
- package/dist/plugin/skills/apt-debug/appendices/diagnose-discipline.md +2 -11
- package/dist/plugin/skills/apt-discuss/SKILL.md +4 -4
- package/dist/plugin/skills/apt-discuss/appendices/grill-discipline.md +2 -11
- package/dist/plugin/skills/apt-discuss/appendices/zoom-out-helper.md +0 -8
- package/dist/plugin/skills/apt-execute/SKILL.md +40 -4
- package/dist/plugin/skills/apt-execute/appendices/tdd-mode.md +2 -10
- package/dist/plugin/skills/apt-fan-out/SKILL.md +159 -0
- package/dist/plugin/skills/apt-handoff/SKILL.md +228 -0
- package/dist/plugin/skills/apt-improve/DEEPENING.md +0 -8
- package/dist/plugin/skills/apt-improve/INTERFACE-DESIGN.md +0 -8
- package/dist/plugin/skills/apt-improve/LANGUAGE.md +0 -8
- package/dist/plugin/skills/apt-improve/SKILL.md +4 -4
- package/dist/plugin/skills/apt-plan/SKILL.md +23 -5
- package/dist/plugin/skills/apt-plan/adapters/conductor.md +1 -1
- package/dist/plugin/skills/apt-pr-review/SKILL.md +8 -1
- package/dist/plugin/skills/apt-prototype/LOGIC.md +0 -8
- package/dist/plugin/skills/apt-prototype/SKILL.md +4 -4
- package/dist/plugin/skills/apt-prototype/UI.md +0 -8
- package/dist/plugin/skills/apt-quick/SKILL.md +31 -1
- package/dist/plugin/skills/apt-resume/SKILL.md +54 -31
- package/dist/plugin/skills/apt-review/SKILL.md +4 -0
- package/dist/plugin/skills/apt-run/SKILL.md +134 -21
- package/dist/plugin/skills/apt-setup/SKILL.md +97 -8
- package/dist/plugin/skills/apt-ship/SKILL.md +165 -9
- package/dist/plugin/skills/apt-spar/SKILL.md +77 -25
- package/dist/plugin/skills/apt-triage/AGENT-BRIEF.md +0 -8
- package/dist/plugin/skills/apt-triage/OUT-OF-SCOPE.md +0 -7
- package/dist/plugin/skills/apt-triage/SKILL.md +2 -2
- package/dist/plugin/skills/apt-update/SKILL.md +74 -17
- package/dist/plugin/skills/apt-verify/SKILL.md +11 -0
- package/dist/plugin/skills/apt-verify-proof/SKILL.md +48 -1
- package/dist/plugin/skills/apt-watch-ci/SKILL.md +2 -2
- package/dist/plugin/skills/apt-zoom-out/SKILL.md +3 -3
- package/dist/schemas/quick-task.d.ts +17 -17
- package/dist/schemas/quick-task.d.ts.map +1 -1
- package/dist/schemas/quick-task.js +2 -2
- package/dist/schemas/quick-task.js.map +1 -1
- package/dist/types/config.d.ts +33 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/state.d.ts +1 -1
- package/dist/types/state.d.ts.map +1 -1
- package/dist/types/task-record.d.ts +1 -1
- package/dist/types/task-record.d.ts.map +1 -1
- package/package.json +134 -133
- package/prompts/planner.md +1 -1
- package/prompts/spec_writer.md +1 -1
- package/skills/apt/SKILL.md +78 -8
- package/skills/apt-caveman/SKILL.md +64 -0
- package/skills/apt-debug/SKILL.md +36 -4
- package/skills/apt-debug/appendices/diagnose-discipline.md +2 -11
- package/skills/apt-discuss/SKILL.md +4 -4
- package/skills/apt-discuss/appendices/grill-discipline.md +2 -11
- package/skills/apt-discuss/appendices/zoom-out-helper.md +0 -8
- package/skills/apt-execute/SKILL.md +27 -4
- package/skills/apt-execute/appendices/tdd-mode.md +2 -10
- package/skills/apt-fan-out/SKILL.md +36 -1
- package/skills/apt-handoff/SKILL.md +228 -0
- package/skills/apt-improve/DEEPENING.md +0 -8
- package/skills/apt-improve/INTERFACE-DESIGN.md +0 -8
- package/skills/apt-improve/LANGUAGE.md +0 -8
- package/skills/apt-improve/SKILL.md +4 -4
- package/skills/apt-plan/SKILL.md +23 -5
- package/skills/apt-plan/adapters/conductor.md +1 -1
- package/skills/apt-planner.md +1 -1
- package/skills/apt-prototype/LOGIC.md +0 -8
- package/skills/apt-prototype/SKILL.md +4 -4
- package/skills/apt-prototype/UI.md +0 -8
- package/skills/apt-quick/SKILL.md +31 -1
- package/skills/apt-resume/SKILL.md +54 -31
- package/skills/apt-run/SKILL.md +114 -16
- package/skills/apt-setup/SKILL.md +97 -8
- package/skills/apt-ship/SKILL.md +165 -9
- package/skills/apt-spar/SKILL.md +65 -16
- package/skills/apt-triage/AGENT-BRIEF.md +0 -8
- package/skills/apt-triage/OUT-OF-SCOPE.md +0 -7
- package/skills/apt-triage/SKILL.md +2 -2
- package/skills/apt-update/SKILL.md +74 -17
- package/skills/apt-verify-proof/SKILL.md +48 -1
- package/skills/apt-zoom-out/SKILL.md +3 -3
- package/src/cli/commands/adr.mjs +1 -1
- package/src/cli/commands/audit-branch-current.mjs +250 -0
- package/src/cli/commands/audit.mjs +13 -2
- package/src/cli/commands/check-version.mjs +20 -1
- package/src/cli/commands/context.mjs +3 -3
- package/src/cli/commands/detect-runtime.mjs +134 -0
- package/src/cli/commands/driver-doctor.mjs +294 -0
- package/src/cli/commands/gate.mjs +15 -0
- package/src/cli/commands/init.mjs +75 -33
- package/src/cli/commands/install-from-source.mjs +1 -0
- package/src/cli/commands/modes.mjs +1 -1
- package/src/cli/commands/route.mjs +42 -1
- package/src/cli/commands/triage.mjs +1 -1
- package/src/cli/config/load.mjs +9 -3
- package/src/cli/coordination/auto-emit-artifact-ready.mjs +1 -1
- package/src/cli/coordination/event-schema.mjs +19 -0
- package/src/cli/dispatch.mjs +17 -1
- package/src/cli/gate/context.mjs +20 -1
- package/src/cli/gate/gates/consistency-check.mjs +1 -0
- package/src/cli/gate/gates/review-clean.mjs +1 -0
- package/src/cli/gate/gates/verify-approved.mjs +1 -0
- package/src/cli/gate/registry.mjs +11 -1
- package/src/cli/install/cli-to-install-root.mjs +0 -2
- package/src/cli/install/find-workspace-framework-version.mjs +88 -0
- package/src/cli/install/install-from-source.mjs +276 -0
- package/src/cli/install/install-kernel.mjs +24 -0
- package/src/cli/install/legacy-paths.mjs +162 -39
- package/src/cli/install/runtime-detect.mjs +9 -4
- package/src/cli/install/runtime-migrate.mjs +63 -30
- package/src/cli/install/transforms/codex.mjs +26 -17
- package/src/cli/install/transforms/pi.mjs +37 -0
- package/src/cli/skill-author/contract.mjs +2 -2
- package/src/cli/verify-proof/.gitkeep +0 -0
- package/src/cli/verify-proof/audit.mjs +55 -0
- package/src/cli/verify-proof/exec.mjs +74 -0
- package/src/cli/verify-proof/idl/index.mjs +24 -0
- package/src/cli/verify-proof/idl/types.ts +41 -0
- package/src/cli/verify-proof/manifest-schema.json +211 -0
- package/src/cli/verify-proof/manifest-validator.mjs +184 -0
- package/src/cli/verify-proof/resolver.mjs +163 -0
- package/src/cli/verify-proof/runtime-detect.mjs +122 -0
- package/src/cli/verify-proof/trust.mjs +187 -0
- package/templates/adr-format.md +0 -8
- package/templates/aperant-claude-md-appendix.md +1 -1
- package/templates/context-format.md +1 -9
- package/templates/proof-verification.md +19 -5
- package/workflows/verify-proof.md +56 -14
|
@@ -26,8 +26,8 @@ Tiny skill. High signal. The user named an area; you produce a one-page
|
|
|
26
26
|
orientation so they (or a future agent) can plan or edit without
|
|
27
27
|
re-learning the codebase from scratch.
|
|
28
28
|
|
|
29
|
-
**
|
|
30
|
-
discipline. Aperant's router is dynamic and LLM-driven, so unlike
|
|
29
|
+
**Aperant adoption note.** This skill descends from 's `zoom-out`
|
|
30
|
+
discipline. Aperant's router is dynamic and LLM-driven, so unlike 's
|
|
31
31
|
upstream this skill is **router-invocable** (no `disable-model-invocation:
|
|
32
32
|
true` flag). The work-intent — "give me a broader picture of X" — is
|
|
33
33
|
genuine and the router resolves natural-language triggers without forcing
|
|
@@ -37,7 +37,7 @@ the user to remember the verb name.
|
|
|
37
37
|
|
|
38
38
|
- Dropped into a new module / package / area of the monorepo
|
|
39
39
|
- About to plan a feature that crosses an unfamiliar boundary
|
|
40
|
-
- The codebase has CONTEXT.md (
|
|
40
|
+
- The codebase has CONTEXT.md (Aperant glossary) and you want to load it
|
|
41
41
|
alongside the structural map
|
|
42
42
|
|
|
43
43
|
## When Not to Use
|
package/src/cli/commands/adr.mjs
CHANGED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* commands/audit-branch-current.mjs — pre-PR rebase gate envelope for apt:ship §0.7.
|
|
3
|
+
*
|
|
4
|
+
* Pure read-only branch-drift audit. Given a base ref (default `main`), reports
|
|
5
|
+
* how many commits HEAD is ahead/behind `origin/<base>`, captures the current
|
|
6
|
+
* `origin/<base>` tip SHA (the lease target for any subsequent
|
|
7
|
+
* `--force-with-lease=refs/heads/<branch>:<sha>` push), and probes whether a
|
|
8
|
+
* trial merge against the remote tip would conflict.
|
|
9
|
+
*
|
|
10
|
+
* Single network call: `git fetch origin <base>`. Fetch failure is recovered
|
|
11
|
+
* as `audit_warning: 'fetch-failed'` — the envelope still returns, just with
|
|
12
|
+
* stale counts. No `git rebase`, no `git push`, no `git reset` — the SKILL.md
|
|
13
|
+
* prose owns history rewrites.
|
|
14
|
+
*
|
|
15
|
+
* Envelope:
|
|
16
|
+
*
|
|
17
|
+
* {
|
|
18
|
+
* status: 'ok',
|
|
19
|
+
* command: 'audit-branch-current',
|
|
20
|
+
* projectDir: string,
|
|
21
|
+
* base: string,
|
|
22
|
+
* ahead: number, // commits HEAD has over origin/<base>
|
|
23
|
+
* behind: number, // commits origin/<base> has over HEAD
|
|
24
|
+
* remote_tip_sha: string | null, // origin/<base> after fetch
|
|
25
|
+
* mergeable: boolean | null, // null when probe unavailable
|
|
26
|
+
* conflicts_preview?: string[], // populated only when mergeable=false
|
|
27
|
+
* audit_warning?: string // 'fetch-failed' | 'git-version-too-old' | ...
|
|
28
|
+
* }
|
|
29
|
+
*
|
|
30
|
+
* Spec cross-ref: .aperant/tasks/apt-ship-pre-pr-rebase-gate-audit-branch_21-05-26/spec.md
|
|
31
|
+
*
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
import { execFileSync } from 'node:child_process'
|
|
36
|
+
import { resolve } from 'node:path'
|
|
37
|
+
import { err, ok } from '../util/result.mjs'
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Try-execute a git command, returning {ok, stdout, stderr, code}. Never throws.
|
|
41
|
+
*
|
|
42
|
+
* @param {string} cwd
|
|
43
|
+
* @param {string[]} args
|
|
44
|
+
*/
|
|
45
|
+
function gitTry(cwd, args) {
|
|
46
|
+
try {
|
|
47
|
+
const stdout = execFileSync('git', args, {
|
|
48
|
+
cwd,
|
|
49
|
+
encoding: 'utf-8',
|
|
50
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
51
|
+
})
|
|
52
|
+
return { ok: true, stdout, stderr: '', code: 0 }
|
|
53
|
+
} catch (e) {
|
|
54
|
+
// execFileSync throws an error whose `stdout`, `stderr`, and `status`
|
|
55
|
+
// properties carry the captured output and exit code.
|
|
56
|
+
return {
|
|
57
|
+
ok: false,
|
|
58
|
+
stdout: typeof e?.stdout === 'string' ? e.stdout : (e?.stdout?.toString() ?? ''),
|
|
59
|
+
stderr: typeof e?.stderr === 'string' ? e.stderr : (e?.stderr?.toString() ?? ''),
|
|
60
|
+
code: typeof e?.status === 'number' ? e.status : 1,
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Parse `--base <ref>` (or `--base=<ref>`) from extraArgs. Defaults to 'main'.
|
|
67
|
+
*
|
|
68
|
+
* @param {string[]} extraArgs
|
|
69
|
+
* @returns {string}
|
|
70
|
+
*/
|
|
71
|
+
function parseBaseFlag(extraArgs) {
|
|
72
|
+
for (let i = 0; i < extraArgs.length; i++) {
|
|
73
|
+
const a = extraArgs[i]
|
|
74
|
+
if (a === '--base' && i + 1 < extraArgs.length) return extraArgs[i + 1]
|
|
75
|
+
if (a.startsWith('--base=')) return a.slice('--base='.length)
|
|
76
|
+
}
|
|
77
|
+
return 'main'
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Parse `git merge-tree --write-tree --no-messages HEAD origin/<base>` output
|
|
82
|
+
* for conflict file paths. Modern (git ≥ 2.38) merge-tree emits, on conflict:
|
|
83
|
+
*
|
|
84
|
+
* <tree-OID>
|
|
85
|
+
* <conflict report lines, each "<mode> <stage> <oid>\t<path>" for stage > 0>
|
|
86
|
+
* (NUL separator)
|
|
87
|
+
* <textual conflict messages>
|
|
88
|
+
*
|
|
89
|
+
* Older variants emit a `+<<<<<<< ... +======= ... +>>>>>>>` diff per file.
|
|
90
|
+
* For correctness we use the stable form: extract file paths from the conflict
|
|
91
|
+
* report. The report includes the SAME path multiple times (once per non-zero
|
|
92
|
+
* stage), so we de-dupe.
|
|
93
|
+
*
|
|
94
|
+
* @param {string} stdout
|
|
95
|
+
* @returns {string[]}
|
|
96
|
+
*/
|
|
97
|
+
function parseConflictPaths(stdout) {
|
|
98
|
+
const paths = new Set()
|
|
99
|
+
for (const rawLine of stdout.split('\n')) {
|
|
100
|
+
const line = rawLine.replace(/\0/g, '')
|
|
101
|
+
if (!line.trim()) continue
|
|
102
|
+
// Match "<mode> <oid> <stage>\t<path>" — git merge-tree --write-tree
|
|
103
|
+
// emits conflict report lines as "<mode> <oid> <stage>\t<path>".
|
|
104
|
+
// Stage 0 means no conflict, so we only surface stage ≥ 1.
|
|
105
|
+
const m = line.match(/^(\d{6})\s+([0-9a-f]{4,40})\s+(\d)\t(.+)$/)
|
|
106
|
+
if (m) {
|
|
107
|
+
const stage = Number.parseInt(m[3], 10)
|
|
108
|
+
if (stage >= 1) paths.add(m[4])
|
|
109
|
+
continue
|
|
110
|
+
}
|
|
111
|
+
// Fallback (older git): the textual report block prefixes paths with
|
|
112
|
+
// "CONFLICT (content): Merge conflict in <path>".
|
|
113
|
+
const c = line.match(/Merge conflict in (.+)$/)
|
|
114
|
+
if (c) paths.add(c[1].trim())
|
|
115
|
+
}
|
|
116
|
+
return Array.from(paths).sort()
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Detect "git too old" from merge-tree stderr. Pre-2.38 git rejects
|
|
121
|
+
* `--write-tree` outright; older still rejects merge-tree's modern arg
|
|
122
|
+
* shape entirely. We treat any non-zero-with-no-output as "version too old"
|
|
123
|
+
* — callers are expected to fall back gracefully.
|
|
124
|
+
*
|
|
125
|
+
* @param {string} stderr
|
|
126
|
+
* @returns {boolean}
|
|
127
|
+
*/
|
|
128
|
+
function isGitVersionTooOld(stderr) {
|
|
129
|
+
return /unknown option|did you mean|usage: git merge-tree/i.test(stderr)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @param {string} projectDir
|
|
134
|
+
* @param {string[]} extraArgs
|
|
135
|
+
*/
|
|
136
|
+
export function auditBranchCurrent(projectDir, extraArgs = []) {
|
|
137
|
+
if (!projectDir) {
|
|
138
|
+
return err('Usage: apt-tools audit branch-current <project-dir> [--base <ref>]')
|
|
139
|
+
}
|
|
140
|
+
const targetDir = resolve(projectDir)
|
|
141
|
+
const base = parseBaseFlag(extraArgs)
|
|
142
|
+
|
|
143
|
+
/** @type {string | undefined} */
|
|
144
|
+
let auditWarning
|
|
145
|
+
/** @type {string[]} */
|
|
146
|
+
const warnings = []
|
|
147
|
+
|
|
148
|
+
// 1. Fetch origin <base>. Tolerate failure (offline, no remote, etc.).
|
|
149
|
+
const fetch = gitTry(targetDir, ['fetch', 'origin', base])
|
|
150
|
+
if (!fetch.ok) {
|
|
151
|
+
auditWarning = 'fetch-failed'
|
|
152
|
+
warnings.push(fetch.stderr.trim().split('\n').slice(0, 3).join(' | '))
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// 2. Resolve origin/<base> tip.
|
|
156
|
+
let remoteTipSha = null
|
|
157
|
+
const tip = gitTry(targetDir, ['rev-parse', `origin/${base}`])
|
|
158
|
+
if (tip.ok) {
|
|
159
|
+
remoteTipSha = tip.stdout.trim()
|
|
160
|
+
} else {
|
|
161
|
+
// No origin/<base> ref at all — emit an envelope with null counts so the
|
|
162
|
+
// caller can recognise the gap. The SKILL.md prose treats null counts as
|
|
163
|
+
// "audit unavailable, STOP with a clear message" rather than proceeding.
|
|
164
|
+
return ok({
|
|
165
|
+
status: 'ok',
|
|
166
|
+
command: 'audit-branch-current',
|
|
167
|
+
projectDir: targetDir,
|
|
168
|
+
base,
|
|
169
|
+
ahead: null,
|
|
170
|
+
behind: null,
|
|
171
|
+
remote_tip_sha: null,
|
|
172
|
+
mergeable: null,
|
|
173
|
+
audit_warning: auditWarning ?? 'no-remote-base-ref',
|
|
174
|
+
warnings,
|
|
175
|
+
})
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// 3. Counts.
|
|
179
|
+
let ahead = 0
|
|
180
|
+
let behind = 0
|
|
181
|
+
const aheadOut = gitTry(targetDir, ['rev-list', '--count', `origin/${base}..HEAD`])
|
|
182
|
+
const behindOut = gitTry(targetDir, ['rev-list', '--count', `HEAD..origin/${base}`])
|
|
183
|
+
if (aheadOut.ok) ahead = Number.parseInt(aheadOut.stdout.trim(), 10) || 0
|
|
184
|
+
if (behindOut.ok) behind = Number.parseInt(behindOut.stdout.trim(), 10) || 0
|
|
185
|
+
|
|
186
|
+
// 4. Mergeability.
|
|
187
|
+
// - When behind === 0, the branch is current or strictly ahead — no
|
|
188
|
+
// remote changes to integrate, mergeable = true by definition.
|
|
189
|
+
// - When behind > 0 AND ahead === 0, the branch is strictly fast-forward
|
|
190
|
+
// behind — a clean fast-forward rebase is always mergeable.
|
|
191
|
+
// - When diverged (behind > 0 AND ahead > 0), probe via git merge-tree.
|
|
192
|
+
let mergeable
|
|
193
|
+
/** @type {string[] | undefined} */
|
|
194
|
+
let conflictsPreview
|
|
195
|
+
if (behind === 0) {
|
|
196
|
+
mergeable = true
|
|
197
|
+
} else if (behind > 0 && ahead === 0) {
|
|
198
|
+
mergeable = true
|
|
199
|
+
} else {
|
|
200
|
+
// Diverged. Run modern merge-tree trial.
|
|
201
|
+
const probe = gitTry(targetDir, [
|
|
202
|
+
'merge-tree',
|
|
203
|
+
'--write-tree',
|
|
204
|
+
'--no-messages',
|
|
205
|
+
'HEAD',
|
|
206
|
+
`origin/${base}`,
|
|
207
|
+
])
|
|
208
|
+
if (probe.ok) {
|
|
209
|
+
mergeable = true
|
|
210
|
+
} else if (probe.code === 1) {
|
|
211
|
+
// Documented merge-tree exit-code semantics: 0 clean, 1 conflict,
|
|
212
|
+
// other = invocation error.
|
|
213
|
+
mergeable = false
|
|
214
|
+
conflictsPreview = parseConflictPaths(probe.stdout)
|
|
215
|
+
} else if (isGitVersionTooOld(probe.stderr)) {
|
|
216
|
+
mergeable = null
|
|
217
|
+
auditWarning = auditWarning ?? 'git-version-too-old'
|
|
218
|
+
warnings.push(`git merge-tree --write-tree unsupported: ${probe.stderr.trim().slice(0, 200)}`)
|
|
219
|
+
} else {
|
|
220
|
+
// Unknown probe failure — treat as unknown rather than asserting
|
|
221
|
+
// clean.
|
|
222
|
+
mergeable = null
|
|
223
|
+
auditWarning = auditWarning ?? 'merge-tree-probe-failed'
|
|
224
|
+
warnings.push(
|
|
225
|
+
`git merge-tree probe failed (code ${probe.code}): ${probe.stderr.trim().slice(0, 200)}`,
|
|
226
|
+
)
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const envelope = {
|
|
231
|
+
status: 'ok',
|
|
232
|
+
command: 'audit-branch-current',
|
|
233
|
+
projectDir: targetDir,
|
|
234
|
+
base,
|
|
235
|
+
ahead,
|
|
236
|
+
behind,
|
|
237
|
+
remote_tip_sha: remoteTipSha,
|
|
238
|
+
mergeable,
|
|
239
|
+
}
|
|
240
|
+
if (conflictsPreview && conflictsPreview.length > 0) {
|
|
241
|
+
envelope.conflicts_preview = conflictsPreview
|
|
242
|
+
}
|
|
243
|
+
if (auditWarning) envelope.audit_warning = auditWarning
|
|
244
|
+
if (warnings.length > 0) envelope.warnings = warnings
|
|
245
|
+
return ok(envelope)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Test-only export for unit-level parser coverage (not part of the public CLI
|
|
249
|
+
// contract).
|
|
250
|
+
export { parseConflictPaths as __parseConflictPathsForTests }
|
|
@@ -28,6 +28,14 @@
|
|
|
28
28
|
* committable bucket is non-empty after staging (CI-friendly gate).
|
|
29
29
|
* Default: report-only, exits 0 regardless.
|
|
30
30
|
*
|
|
31
|
+
* apt-tools audit branch-current <project-dir> [--base <ref>]
|
|
32
|
+
* Pre-PR rebase gate envelope for apt:ship §0.7. Pure read-only:
|
|
33
|
+
* `git fetch origin <base>`, captures origin/<base> tip SHA, counts
|
|
34
|
+
* ahead/behind, and (when diverged) probes mergeability with
|
|
35
|
+
* `git merge-tree --write-tree`. Returns {ahead, behind,
|
|
36
|
+
* remote_tip_sha, mergeable, conflicts_preview?}. Never mutates
|
|
37
|
+
* HEAD, the index, the worktree, or any remote ref.
|
|
38
|
+
*
|
|
31
39
|
* Single source of truth: buildPolicyIgnoreMatcher in share-policy.mjs is
|
|
32
40
|
* the ONLY matcher anywhere in the CLI. If you add a new taxonomy class or
|
|
33
41
|
* toggle, update share-policy and this command follows automatically.
|
|
@@ -46,6 +54,7 @@ import { selfStageCommittableWrites } from '../artifacts/self-stage.mjs'
|
|
|
46
54
|
import { buildPolicyIgnoreMatcher, resolveSharePolicy } from '../config/share-policy.mjs'
|
|
47
55
|
import { detectPublicRemote } from '../git/remote.mjs'
|
|
48
56
|
import { err, exitWith, ok } from '../util/result.mjs'
|
|
57
|
+
import { auditBranchCurrent } from './audit-branch-current.mjs'
|
|
49
58
|
|
|
50
59
|
/**
|
|
51
60
|
* Dispatch an `audit <subcommand>` call.
|
|
@@ -59,7 +68,7 @@ import { err, exitWith, ok } from '../util/result.mjs'
|
|
|
59
68
|
export function cmdAudit(subcommand, projectDir, extraArgs = []) {
|
|
60
69
|
if (!subcommand) {
|
|
61
70
|
return err(
|
|
62
|
-
'Usage: apt-tools audit <privacy|visibility-signals|pending-artifacts> <project-dir> [flags]',
|
|
71
|
+
'Usage: apt-tools audit <privacy|visibility-signals|pending-artifacts|branch-current> <project-dir> [flags]',
|
|
63
72
|
)
|
|
64
73
|
}
|
|
65
74
|
if (!projectDir) {
|
|
@@ -73,9 +82,11 @@ export function cmdAudit(subcommand, projectDir, extraArgs = []) {
|
|
|
73
82
|
return auditVisibilitySignals(targetDir)
|
|
74
83
|
case 'pending-artifacts':
|
|
75
84
|
return auditPendingArtifacts(targetDir, extraArgs)
|
|
85
|
+
case 'branch-current':
|
|
86
|
+
return auditBranchCurrent(targetDir, extraArgs)
|
|
76
87
|
default:
|
|
77
88
|
return err(
|
|
78
|
-
`Unknown audit subcommand: ${subcommand}. Expected 'privacy', 'visibility-signals',
|
|
89
|
+
`Unknown audit subcommand: ${subcommand}. Expected 'privacy', 'visibility-signals', 'pending-artifacts', or 'branch-current'.`,
|
|
79
90
|
)
|
|
80
91
|
}
|
|
81
92
|
}
|
|
@@ -29,7 +29,13 @@
|
|
|
29
29
|
* // `framework_version` field (read from package.json, never from
|
|
30
30
|
* // the cache).
|
|
31
31
|
* framework: {
|
|
32
|
-
* latest_version: '0.6.7' | null
|
|
32
|
+
* latest_version: '0.6.7' | null,
|
|
33
|
+
* // Bundle A (0.8.3) — additive nullable field. Set when a workspace
|
|
34
|
+
* // `packages/framework/package.json` is found above the project root
|
|
35
|
+
* // and its `name === '@aperant/framework'`. When workspace_version
|
|
36
|
+
* // is ahead of the running kernel, `update_available` flips true
|
|
37
|
+
* // regardless of cache state (workspace wins on self-host).
|
|
38
|
+
* workspace_version: '0.8.3' | null
|
|
33
39
|
* },
|
|
34
40
|
* update_available: false,
|
|
35
41
|
* dev_install_ahead: false,
|
|
@@ -48,11 +54,13 @@
|
|
|
48
54
|
import { existsSync, readFileSync } from 'node:fs'
|
|
49
55
|
import { dirname, join, resolve } from 'node:path'
|
|
50
56
|
import { fileURLToPath } from 'node:url'
|
|
57
|
+
import { findWorkspaceFrameworkVersion } from '../install/find-workspace-framework-version.mjs'
|
|
51
58
|
import { readManifest } from '../install/manifest.mjs'
|
|
52
59
|
import { detectInstalledRuntimes } from '../install/runtime-detect.mjs'
|
|
53
60
|
import { readFreshUpdateCache } from '../install/update-chips.mjs'
|
|
54
61
|
import { inspectManifestFiles } from '../install/version-header.mjs'
|
|
55
62
|
import { err, ok } from '../util/result.mjs'
|
|
63
|
+
import { compareVersions } from '../util/semver.mjs'
|
|
56
64
|
|
|
57
65
|
const __filename = fileURLToPath(import.meta.url)
|
|
58
66
|
const __dirname = dirname(__filename)
|
|
@@ -167,6 +175,16 @@ export function cmdCheckVersion(projectDir) {
|
|
|
167
175
|
if (typeof c.lookup_error === 'string') lookupError = c.lookup_error
|
|
168
176
|
}
|
|
169
177
|
|
|
178
|
+
// Bundle A — additive `framework.workspace_version` field. When the
|
|
179
|
+
// workspace package.json is ahead of the running kernel, flip
|
|
180
|
+
// `update_available` true regardless of cache state (the workspace is
|
|
181
|
+
// the source of truth on self-host). schema_version stays at 1 (D-01).
|
|
182
|
+
const workspace = findWorkspaceFrameworkVersion(targetDir)
|
|
183
|
+
const workspaceVersion = workspace?.source_version ?? null
|
|
184
|
+
if (workspaceVersion && compareVersions(workspaceVersion, frameworkVersion) > 0) {
|
|
185
|
+
updateAvailable = true
|
|
186
|
+
}
|
|
187
|
+
|
|
170
188
|
return ok({
|
|
171
189
|
status,
|
|
172
190
|
command: 'check-version',
|
|
@@ -178,6 +196,7 @@ export function cmdCheckVersion(projectDir) {
|
|
|
178
196
|
// file-header schema comment.
|
|
179
197
|
framework: {
|
|
180
198
|
latest_version: latestVersion,
|
|
199
|
+
workspace_version: workspaceVersion,
|
|
181
200
|
},
|
|
182
201
|
update_available: updateAvailable,
|
|
183
202
|
dev_install_ahead: devInstallAhead,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* commands/context.mjs — `apt-tools context write
|
|
2
|
+
* commands/context.mjs — `apt-tools context write`.
|
|
3
3
|
*
|
|
4
4
|
* Upserts a term-block into the project's CONTEXT.md (the persistent
|
|
5
|
-
* project glossary). Format ported from
|
|
5
|
+
* project glossary). Format ported from the Aperant CONTEXT-FORMAT.md
|
|
6
6
|
* (see packages/framework/templates/context-format.md for the MIT
|
|
7
7
|
* attribution + field semantics).
|
|
8
8
|
*
|
|
@@ -192,7 +192,7 @@ export function cmdContext(subcommand, projectDir, extraArgs) {
|
|
|
192
192
|
} else {
|
|
193
193
|
source = `${HEADER}\n\n${HEADER_NOTE}\n\n`
|
|
194
194
|
}
|
|
195
|
-
// Ensure the file starts with the header even if it existed pre-
|
|
195
|
+
// Ensure the file starts with the header even if it existed pre-vertical-slice.
|
|
196
196
|
if (!source.startsWith(HEADER)) {
|
|
197
197
|
source = `${HEADER}\n\n${HEADER_NOTE}\n\n${source}`
|
|
198
198
|
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* commands/detect-runtime.mjs — `apt-tools detect-runtime <projectDir>`.
|
|
3
|
+
*
|
|
4
|
+
* Exposes runtime-detect.mjs at the CLI surface so adopters can preview
|
|
5
|
+
* which driver Aperant will pick for /apt:verify-proof.
|
|
6
|
+
*
|
|
7
|
+
* Returns:
|
|
8
|
+
* { status: 'ok', command: 'detect-runtime', projectDir,
|
|
9
|
+
* runtime: { is_electron, is_tauri, is_nextjs, is_web_frontend, ... },
|
|
10
|
+
* selected_driver_id: string | null,
|
|
11
|
+
* fallback_attempts: [{ driver_id, reason }] }
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs'
|
|
15
|
+
import { join, resolve } from 'node:path'
|
|
16
|
+
import { fileURLToPath } from 'node:url'
|
|
17
|
+
import { err, ok } from '../util/result.mjs'
|
|
18
|
+
import { resolveDriver } from '../verify-proof/resolver.mjs'
|
|
19
|
+
import { loadRuntimeCapabilities } from '../verify-proof/runtime-detect.mjs'
|
|
20
|
+
|
|
21
|
+
/** Default required capabilities — the smallest set that proves a driver is usable. */
|
|
22
|
+
const DEFAULT_REQUIRED_CAPABILITIES = ['screenshot']
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Discover every driver manifest bundled with @aperant/framework.
|
|
26
|
+
* @param {string} frameworkRoot — absolute path to packages/framework or .aperant/deps/.../@aperant/framework
|
|
27
|
+
* @returns {Array<object>}
|
|
28
|
+
*/
|
|
29
|
+
function discoverBundledDrivers(frameworkRoot) {
|
|
30
|
+
const dir = join(frameworkRoot, 'drivers')
|
|
31
|
+
if (!existsSync(dir)) return []
|
|
32
|
+
const manifests = []
|
|
33
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
34
|
+
if (!entry.isDirectory()) continue
|
|
35
|
+
const manifestPath = join(dir, entry.name, 'manifest.json')
|
|
36
|
+
if (!existsSync(manifestPath)) continue
|
|
37
|
+
try {
|
|
38
|
+
const parsed = JSON.parse(readFileSync(manifestPath, 'utf-8'))
|
|
39
|
+
manifests.push({ ...parsed, locality: 'bundled' })
|
|
40
|
+
} catch {
|
|
41
|
+
/* skip malformed manifests */
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return manifests
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Discover every user-installed driver manifest at .aperant/drivers/.
|
|
49
|
+
* @param {string} projectDir
|
|
50
|
+
* @returns {Array<object>}
|
|
51
|
+
*/
|
|
52
|
+
function discoverUserDrivers(projectDir) {
|
|
53
|
+
const dir = join(projectDir, '.aperant/drivers')
|
|
54
|
+
if (!existsSync(dir)) return []
|
|
55
|
+
const manifests = []
|
|
56
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
57
|
+
if (!entry.isDirectory()) continue
|
|
58
|
+
const manifestPath = join(dir, entry.name, 'manifest.json')
|
|
59
|
+
if (!existsSync(manifestPath)) continue
|
|
60
|
+
try {
|
|
61
|
+
const parsed = JSON.parse(readFileSync(manifestPath, 'utf-8'))
|
|
62
|
+
manifests.push({ ...parsed, locality: 'user' })
|
|
63
|
+
} catch {
|
|
64
|
+
/* skip malformed manifests */
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return manifests
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @param {string} projectDir
|
|
72
|
+
* @param {string[]} [_extra]
|
|
73
|
+
*/
|
|
74
|
+
export function cmdDetectRuntime(projectDir, _extra = []) {
|
|
75
|
+
if (!projectDir) return err('Usage: apt-tools detect-runtime <project-dir>')
|
|
76
|
+
const target = resolve(projectDir)
|
|
77
|
+
|
|
78
|
+
// Detect runtime capabilities from project's package.json.
|
|
79
|
+
const runtime = loadRuntimeCapabilities(target)
|
|
80
|
+
|
|
81
|
+
// Discover bundled + user drivers.
|
|
82
|
+
// __dirname-equivalent under ESM: walk up from this file to the framework
|
|
83
|
+
// package root. fileURLToPath is portable across POSIX + Windows;
|
|
84
|
+
// new URL(...).pathname returns '/C:/...' on Windows which resolve()
|
|
85
|
+
// does not handle correctly.
|
|
86
|
+
const frameworkRoot = fileURLToPath(new URL('../../..', import.meta.url))
|
|
87
|
+
const bundled = discoverBundledDrivers(frameworkRoot)
|
|
88
|
+
const user = discoverUserDrivers(target)
|
|
89
|
+
const drivers = [...bundled, ...user]
|
|
90
|
+
|
|
91
|
+
// Read user override from .aperant/config.json:verification.runtimes[].
|
|
92
|
+
let override = []
|
|
93
|
+
const configPath = join(target, '.aperant/config.json')
|
|
94
|
+
if (existsSync(configPath)) {
|
|
95
|
+
try {
|
|
96
|
+
const cfg = JSON.parse(readFileSync(configPath, 'utf-8'))
|
|
97
|
+
if (Array.isArray(cfg?.verification?.runtimes)) {
|
|
98
|
+
override = cfg.verification.runtimes.filter((x) => typeof x === 'string')
|
|
99
|
+
}
|
|
100
|
+
} catch {
|
|
101
|
+
/* malformed config — ignore */
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Try resolving with the default minimum required capability.
|
|
106
|
+
let selected = null
|
|
107
|
+
let fallback_attempts = []
|
|
108
|
+
try {
|
|
109
|
+
const result = resolveDriver({
|
|
110
|
+
drivers,
|
|
111
|
+
runtime,
|
|
112
|
+
required_capabilities: DEFAULT_REQUIRED_CAPABILITIES,
|
|
113
|
+
override,
|
|
114
|
+
})
|
|
115
|
+
selected = result.selected.driverId
|
|
116
|
+
fallback_attempts = result.fallback_attempts
|
|
117
|
+
} catch (resolveErr) {
|
|
118
|
+
fallback_attempts = resolveErr && Array.isArray(resolveErr.attempts) ? resolveErr.attempts : []
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return ok({
|
|
122
|
+
status: 'ok',
|
|
123
|
+
command: 'detect-runtime',
|
|
124
|
+
projectDir: target,
|
|
125
|
+
runtime,
|
|
126
|
+
discovered_drivers: drivers.map((d) => ({
|
|
127
|
+
driverId: d.driverId,
|
|
128
|
+
version: d.version,
|
|
129
|
+
locality: d.locality,
|
|
130
|
+
})),
|
|
131
|
+
selected_driver_id: selected,
|
|
132
|
+
fallback_attempts,
|
|
133
|
+
})
|
|
134
|
+
}
|