@1aboveio/skills 1.0.7 → 1.0.9
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/.codex-plugin/plugin.json +13 -0
- package/.codex-plugin/resources.json +1827 -0
- package/README.md +22 -0
- package/package.json +9 -2
- package/skills/app-dev/airflow/SKILL.md +1 -1
- package/skills/app-dev/airflow/release-check.mjs +3 -1
- package/skills/app-dev/android-foundation/SKILL.md +92 -34
- package/skills/app-dev/android-foundation/assets/android-ci-job.yml +13 -7
- package/skills/app-dev/android-foundation/references/ci.md +23 -13
- package/skills/app-dev/android-foundation/references/delivery-focus.md +29 -0
- package/skills/app-dev/android-foundation/references/diagnosis.md +136 -0
- package/skills/app-dev/android-foundation/references/gotchas.md +20 -11
- package/skills/app-dev/android-foundation/references/setup.md +15 -6
- package/skills/app-dev/android-foundation/release-check.mjs +3 -1
- package/skills/app-dev/android-foundation/scripts/device-run.sh +148 -42
- package/skills/app-dev/app-debug/SKILL.md +1 -1
- package/skills/app-dev/app-debug/release-check.mjs +3 -1
- package/skills/app-dev/better-auth/SKILL.md +1 -1
- package/skills/app-dev/better-auth/release-check.mjs +3 -1
- package/skills/app-dev/data-catalog/SKILL.md +1 -1
- package/skills/app-dev/data-catalog/release-check.mjs +3 -1
- package/skills/app-dev/data-quality/SKILL.md +1 -1
- package/skills/app-dev/data-quality/release-check.mjs +3 -1
- package/skills/app-dev/ios-foundation/SKILL.md +1 -1
- package/skills/app-dev/ios-foundation/release-check.mjs +3 -1
- package/skills/app-dev/monorepo/SKILL.md +1 -1
- package/skills/app-dev/monorepo/release-check.mjs +3 -1
- package/skills/app-dev/nextjs-fullstack/SKILL.md +1 -1
- package/skills/app-dev/nextjs-fullstack/release-check.mjs +3 -1
- package/skills/app-dev/prisma-setup/SKILL.md +1 -1
- package/skills/app-dev/prisma-setup/release-check.mjs +3 -1
- package/skills/app-dev/pyspark/SKILL.md +1 -1
- package/skills/app-dev/pyspark/release-check.mjs +3 -1
- package/skills/app-dev/python-backend/SKILL.md +1 -1
- package/skills/app-dev/python-backend/release-check.mjs +3 -1
- package/skills/app-dev/shadcn/SKILL.md +1 -1
- package/skills/app-dev/shadcn/release-check.mjs +3 -1
- package/skills/app-dev/zod-v4/SKILL.md +1 -1
- package/skills/app-dev/zod-v4/release-check.mjs +3 -1
- package/skills/cicd/cloud-build/SKILL.md +1 -1
- package/skills/cicd/cloud-build/release-check.mjs +3 -1
- package/skills/cicd/cloud-debug/SKILL.md +1 -1
- package/skills/cicd/cloud-debug/release-check.mjs +3 -1
- package/skills/cicd/cloud-deploy/SKILL.md +1 -1
- package/skills/cicd/cloud-deploy/release-check.mjs +3 -1
- package/skills/cicd/docker/SKILL.md +1 -1
- package/skills/cicd/docker/release-check.mjs +3 -1
- package/skills/cicd/github-actions/SKILL.md +1 -1
- package/skills/cicd/github-actions/release-check.mjs +3 -1
- package/skills/cicd/github-flow/SKILL.md +1 -1
- package/skills/cicd/github-flow/release-check.mjs +3 -1
- package/skills/cicd/google-cloud/SKILL.md +1 -1
- package/skills/cicd/google-cloud/release-check.mjs +3 -1
- package/skills/cicd/mergify/SKILL.md +1 -1
- package/skills/cicd/mergify/release-check.mjs +3 -1
- package/skills/cicd/podman/SKILL.md +1 -1
- package/skills/cicd/podman/release-check.mjs +3 -1
- package/skills/content/article-review/SKILL.md +1 -1
- package/skills/content/article-review/release-check.mjs +3 -1
- package/skills/content/article-to-image/SKILL.md +1 -1
- package/skills/content/article-to-image/release-check.mjs +3 -1
- package/skills/content/flowchart-svg/SKILL.md +1 -1
- package/skills/content/flowchart-svg/release-check.mjs +3 -1
- package/skills/content/image-gen/SKILL.md +1 -1
- package/skills/content/image-gen/release-check.mjs +3 -1
- package/skills/content/mermaid/SKILL.md +1 -1
- package/skills/content/mermaid/release-check.mjs +3 -1
- package/skills/content/wechat-article-writer/SKILL.md +1 -1
- package/skills/content/wechat-article-writer/release-check.mjs +3 -1
- package/skills/content/wechat-publisher/SKILL.md +1 -1
- package/skills/content/wechat-publisher/release-check.mjs +3 -1
- package/skills/content/wechat-search/SKILL.md +1 -1
- package/skills/content/wechat-search/release-check.mjs +3 -1
- package/skills/content/xai-search/SKILL.md +88 -13
- package/skills/content/xai-search/release-check.mjs +3 -1
- package/skills/content/xai-search/scripts/xai_search.sh +125 -149
- package/skills/core/distill-writing/SKILL.md +1 -1
- package/skills/core/distill-writing/release-check.mjs +3 -1
- package/skills/core/doc-to-md/SKILL.md +1 -1
- package/skills/core/doc-to-md/release-check.mjs +3 -1
- package/skills/core/editorial-review/SKILL.md +1 -1
- package/skills/core/editorial-review/release-check.mjs +3 -1
- package/skills/core/house-style/SKILL.md +1 -1
- package/skills/core/house-style/release-check.mjs +3 -1
- package/skills/core/plain-language/SKILL.md +1 -1
- package/skills/core/plain-language/release-check.mjs +3 -1
- package/skills/core/polish-cn/SKILL.md +1 -1
- package/skills/core/polish-cn/release-check.mjs +3 -1
- package/skills/core/reg-parser/SKILL.md +1 -1
- package/skills/core/reg-parser/release-check.mjs +3 -1
- package/skills/core/terminology/SKILL.md +1 -1
- package/skills/core/terminology/release-check.mjs +3 -1
- package/skills/core/write-doc/SKILL.md +1 -1
- package/skills/core/write-doc/release-check.mjs +3 -1
- package/skills/engineering/better-review/SKILL.md +1 -1
- package/skills/engineering/better-review/release-check.mjs +3 -1
- package/skills/engineering/contributing/SKILL.md +1 -1
- package/skills/engineering/contributing/release-check.mjs +3 -1
- package/skills/engineering/e2e-test/SKILL.md +1 -1
- package/skills/engineering/e2e-test/release-check.mjs +3 -1
- package/skills/engineering/engineering-runtime/SKILL.md +1 -1
- package/skills/engineering/engineering-runtime/coherence/workflow.json +13 -13
- package/skills/engineering/engineering-runtime/release-check.mjs +3 -1
- package/skills/engineering/engineering-runtime/scripts/installation-resolver.mjs +191 -0
- package/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +51 -10
- package/skills/engineering/ensure-coverage/SKILL.md +1 -1
- package/skills/engineering/ensure-coverage/release-check.mjs +3 -1
- package/skills/engineering/golden-path/SKILL.md +1 -1
- package/skills/engineering/golden-path/release-check.mjs +3 -1
- package/skills/engineering/harness-runtime/SKILL.md +1 -1
- package/skills/engineering/harness-runtime/release-check.mjs +3 -1
- package/skills/engineering/resolve-issues/SKILL.md +11 -20
- package/skills/engineering/resolve-issues/references/delivery-progress.md +63 -0
- package/skills/engineering/resolve-issues/references/expire.md +24 -11
- package/skills/engineering/resolve-issues/references/implementation.md +9 -1
- package/skills/engineering/resolve-issues/references/preflight.md +7 -0
- package/skills/engineering/resolve-issues/references/shared-modules.md +27 -0
- package/skills/engineering/resolve-issues/references/task-plan.md +12 -5
- package/skills/engineering/resolve-issues/release-check.mjs +3 -1
- package/skills/engineering/resolve-issues/scripts/active-installation.mjs +32 -0
- package/skills/engineering/resolve-issues/scripts/install-hooks.mjs +3 -0
- package/skills/engineering/resolve-issues/scripts/rehydrate.mjs +17 -1
- package/skills/engineering/resolve-release/SKILL.md +1 -1
- package/skills/engineering/resolve-release/release-check.mjs +3 -1
- package/skills/engineering/rush-issues/SKILL.md +5 -2
- package/skills/engineering/rush-issues/release-check.mjs +3 -1
- package/skills/engineering/rush-release/SKILL.md +1 -1
- package/skills/engineering/rush-release/release-check.mjs +3 -1
- package/skills/engineering/test-quality/SKILL.md +1 -1
- package/skills/engineering/test-quality/release-check.mjs +3 -1
- package/skills/risk-compliance/compliance-audit/SKILL.md +1 -1
- package/skills/risk-compliance/compliance-audit/release-check.mjs +3 -1
- package/skills/risk-compliance/contract-compare/SKILL.md +1 -1
- package/skills/risk-compliance/contract-compare/release-check.mjs +3 -1
- package/skills/risk-compliance/contract-review/SKILL.md +1 -1
- package/skills/risk-compliance/contract-review/release-check.mjs +3 -1
- package/skills/risk-compliance/doc-authenticity/SKILL.md +1 -1
- package/skills/risk-compliance/doc-authenticity/release-check.mjs +3 -1
- package/skills/risk-compliance/fraud-analysis/SKILL.md +1 -1
- package/skills/risk-compliance/fraud-analysis/release-check.mjs +3 -1
- package/skills/risk-compliance/payment-analysis/SKILL.md +1 -1
- package/skills/risk-compliance/payment-analysis/release-check.mjs +3 -1
- package/skills/risk-compliance/similar-domain/SKILL.md +1 -1
- package/skills/risk-compliance/similar-domain/release-check.mjs +3 -1
- package/skills/risk-compliance/tld-detection/SKILL.md +1 -1
- package/skills/risk-compliance/tld-detection/release-check.mjs +3 -1
- package/skills/app-dev/android-foundation/scripts/device-run.test.mjs +0 -172
- package/skills/app-dev/data-catalog/scripts/data-catalog.test.mjs +0 -36
- package/skills/app-dev/data-quality/scripts/data-quality.test.mjs +0 -12
- package/skills/cicd/github-actions/scripts/ci-run-audit.test.mjs +0 -637
- package/skills/cicd/github-flow/scripts/flow.test.mjs +0 -114
- package/skills/cicd/github-flow/scripts/persist-conventions.test.mjs +0 -108
- package/skills/cicd/mergify/scripts/audit.test.mjs +0 -201
- package/skills/cicd/mergify/scripts/entrypoints.test.mjs +0 -106
- package/skills/cicd/mergify/scripts/pr-620-mergify-comments.fixture.json +0 -30
- package/skills/cicd/mergify/scripts/stack-push.test.mjs +0 -233
- package/skills/cicd/mergify/scripts/watch-pr-delivery.test.mjs +0 -1826
- package/skills/content/image-gen/scripts/credentials.test.mjs +0 -212
- package/skills/content/image-gen/scripts/options.test.mjs +0 -245
- package/skills/content/xai-search/tests/smoke_test.sh +0 -36
- package/skills/core/polish-cn/scripts/polish-cn.test.mjs +0 -244
- package/skills/core/reg-parser/scripts/reg-parser.test.mjs +0 -165
- package/skills/engineering/better-review/scripts/pr-context.test.mjs +0 -168
- package/skills/engineering/better-review/scripts/rereview-scope.test.mjs +0 -587
- package/skills/engineering/better-review/scripts/scan-diff.test.mjs +0 -414
- package/skills/engineering/better-review/scripts/vendor-sync.test.mjs +0 -96
- package/skills/engineering/contributing/scripts/persist-conventions.test.mjs +0 -118
- package/skills/engineering/e2e-test/scripts/presentation-checks.test.mjs +0 -106
- package/skills/engineering/e2e-test/scripts/presentation-perceivability.test.mjs +0 -117
- package/skills/engineering/e2e-test/scripts/presentation-reachability.test.mjs +0 -69
- package/skills/engineering/e2e-test/scripts/presentation-render-health.test.mjs +0 -98
- package/skills/engineering/e2e-test/scripts/presentation-sweep.test.mjs +0 -71
- package/skills/engineering/e2e-test/scripts/presentation-temporal.test.mjs +0 -59
- package/skills/engineering/e2e-test/scripts/project-route-manifest.test.mjs +0 -76
- package/skills/engineering/engineering-runtime/engineering-runtime.test.mjs +0 -68
- package/skills/engineering/engineering-runtime/scripts/invocation-policy.test.mjs +0 -95
- package/skills/engineering/engineering-runtime/scripts/main-module.test.mjs +0 -288
- package/skills/engineering/engineering-runtime/scripts/required-check-plan.test.mjs +0 -96
- package/skills/engineering/ensure-coverage/scripts/adapters/nextjs-inventory.test.mjs +0 -96
- package/skills/engineering/ensure-coverage/scripts/check-quarantine-expiry.test.mjs +0 -47
- package/skills/engineering/ensure-coverage/scripts/ci-audit.test.mjs +0 -86
- package/skills/engineering/ensure-coverage/scripts/coverage-ledger.test.mjs +0 -447
- package/skills/engineering/ensure-coverage/scripts/design-parity.test.mjs +0 -552
- package/skills/engineering/ensure-coverage/scripts/lint-tests.test.mjs +0 -289
- package/skills/engineering/ensure-coverage/scripts/mock-policy-config.test.mjs +0 -119
- package/skills/engineering/golden-path/scripts/golden-path.test.mjs +0 -1457
- package/skills/engineering/harness-runtime/discover-models.test.mjs +0 -363
- package/skills/engineering/harness-runtime/harness-runtime.test.mjs +0 -967
- package/skills/engineering/harness-runtime/model-catalog-seed.test.mjs +0 -829
- package/skills/engineering/harness-runtime/model-catalog.test.mjs +0 -366
- package/skills/engineering/resolve-issues/scripts/cleanup-runs.test.mjs +0 -280
- package/skills/engineering/resolve-issues/scripts/dropbox.test.mjs +0 -346
- package/skills/engineering/resolve-issues/scripts/findings-reuse.test.mjs +0 -88
- package/skills/engineering/resolve-issues/scripts/github-reviews.test.mjs +0 -264
- package/skills/engineering/resolve-issues/scripts/install-hooks.test.mjs +0 -79
- package/skills/engineering/resolve-issues/scripts/issue-tree.test.mjs +0 -107
- package/skills/engineering/resolve-issues/scripts/manual-invocation.test.mjs +0 -14
- package/skills/engineering/resolve-issues/scripts/next-actions-capacity.test.mjs +0 -149
- package/skills/engineering/resolve-issues/scripts/next-actions.test.mjs +0 -915
- package/skills/engineering/resolve-issues/scripts/plan-sync.test.mjs +0 -156
- package/skills/engineering/resolve-issues/scripts/preflight-models.test.mjs +0 -448
- package/skills/engineering/resolve-issues/scripts/ready-check.test.mjs +0 -217
- package/skills/engineering/resolve-issues/scripts/rehydrate.test.mjs +0 -91
- package/skills/engineering/resolve-issues/scripts/review-verdict.test.mjs +0 -1060
- package/skills/engineering/resolve-issues/scripts/size-check.test.mjs +0 -458
- package/skills/engineering/resolve-release/scripts/apply.test.mjs +0 -99
- package/skills/engineering/resolve-release/scripts/dark-flags.test.mjs +0 -100
- package/skills/engineering/resolve-release/scripts/flow.test.mjs +0 -340
- package/skills/engineering/resolve-release/scripts/green-head.test.mjs +0 -101
- package/skills/engineering/resolve-release/scripts/npm-version-absence.test.mjs +0 -426
- package/skills/engineering/resolve-release/scripts/plan-npm.test.mjs +0 -659
- package/skills/engineering/resolve-release/scripts/plan-toml-boundary.test.mjs +0 -317
- package/skills/engineering/resolve-release/scripts/plan-uv.test.mjs +0 -291
- package/skills/engineering/resolve-release/scripts/plan.test.mjs +0 -428
- package/skills/engineering/test-quality/scripts/lint-tests.test.mjs +0 -591
- package/skills/engineering/test-quality/scripts/mock-policy-config.test.mjs +0 -119
- package/skills/engineering/test-quality/scripts/persist-conventions.test.mjs +0 -104
- package/skills/risk-compliance/compliance-audit/scripts/compliance-audit.test.mjs +0 -14
- package/skills/risk-compliance/doc-authenticity/manual-invocation.test.mjs +0 -12
- package/skills/risk-compliance/doc-authenticity/scripts/validate_verdict.test.mjs +0 -212
- package/skills/risk-compliance/tld-detection/scripts/detect_ladders.test.mjs +0 -14
- package/skills/risk-compliance/tld-detection/scripts/detect_streams.test.mjs +0 -14
- package/skills/risk-compliance/tld-detection/tests/test_detect_ladders.py +0 -134
- package/skills/risk-compliance/tld-detection/tests/test_detect_streams.py +0 -520
|
@@ -1,363 +0,0 @@
|
|
|
1
|
-
// discover-models tests — real fixture config files under a temp HOME, NEVER the
|
|
2
|
-
// user's real ~/.pi / ~/.codex / ~/.claude. Every case writes its own config tree
|
|
3
|
-
// into a scratch dir and runs the script with `HOME=<tmp>` and an INJECTED env for
|
|
4
|
-
// the apiKey `$VAR` resolution, so no test reads or depends on the real machine's
|
|
5
|
-
// config or environment. A test that touched the real config would be a defect —
|
|
6
|
-
// the whole point of this unit is a trustworthy, isolated discovery read.
|
|
7
|
-
|
|
8
|
-
import { test } from 'node:test'
|
|
9
|
-
import assert from 'node:assert/strict'
|
|
10
|
-
import fs from 'node:fs'
|
|
11
|
-
import os from 'node:os'
|
|
12
|
-
import path from 'node:path'
|
|
13
|
-
import { fileURLToPath } from 'node:url'
|
|
14
|
-
import { execFileSync } from 'node:child_process'
|
|
15
|
-
|
|
16
|
-
import { discoverPi, discoverCodex, discoverClaudeCode, apiKeyResolves } from './discover-models.mjs'
|
|
17
|
-
|
|
18
|
-
const scriptPath = path.join(path.dirname(fileURLToPath(import.meta.url)), 'bin', 'discover-models.mjs')
|
|
19
|
-
|
|
20
|
-
// ---- temp-HOME fixture scaffolding ----
|
|
21
|
-
|
|
22
|
-
function mkHome() {
|
|
23
|
-
return fs.mkdtempSync(path.join(os.tmpdir(), 'discover-models-'))
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function writeJson(file, obj) {
|
|
27
|
-
fs.mkdirSync(path.dirname(file), { recursive: true })
|
|
28
|
-
fs.writeFileSync(file, JSON.stringify(obj, null, 2))
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function writeText(file, text) {
|
|
32
|
-
fs.mkdirSync(path.dirname(file), { recursive: true })
|
|
33
|
-
fs.writeFileSync(file, text)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Run the script with a fully-controlled env: an explicit HOME (the fixture tree)
|
|
37
|
-
// and only the env vars a case injects — so `$VAR` resolution is tested against
|
|
38
|
-
// injected values, never the real environment. Returns { code, stdout, json }.
|
|
39
|
-
function run(args, { home, extraEnv = {} } = {}) {
|
|
40
|
-
const env = { PATH: process.env.PATH, HOME: home, ...extraEnv }
|
|
41
|
-
let stdout = ''
|
|
42
|
-
let code = 0
|
|
43
|
-
try {
|
|
44
|
-
stdout = execFileSync('node', [scriptPath, ...args], { encoding: 'utf8', env })
|
|
45
|
-
} catch (err) {
|
|
46
|
-
code = err.status ?? 1
|
|
47
|
-
stdout = err.stdout ?? ''
|
|
48
|
-
}
|
|
49
|
-
let json = null
|
|
50
|
-
try {
|
|
51
|
-
json = JSON.parse(stdout)
|
|
52
|
-
} catch {
|
|
53
|
-
/* non-JSON (help/usage) — leave json null */
|
|
54
|
-
}
|
|
55
|
-
return { code, stdout, json }
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const ids = (json) => json.discovered.map((d) => d.id)
|
|
59
|
-
|
|
60
|
-
// ---- Pi: the full credentialed-remainder fixture ----
|
|
61
|
-
|
|
62
|
-
// Builds the Pi fixture the task spec asks for, under a fresh temp HOME:
|
|
63
|
-
// - enabledModels: the curated picker set
|
|
64
|
-
// - a default provider/model
|
|
65
|
-
// - a models.json custom entry whose provider apiKey is a LITERAL (resolves)
|
|
66
|
-
// - a models.json custom entry whose provider apiKey is $SET_VAR (resolves)
|
|
67
|
-
// - a models.json custom entry whose provider apiKey is $UNSET_VAR (does NOT resolve)
|
|
68
|
-
// - an auth.json-credentialed provider with NO enabledModels entry (provider-level)
|
|
69
|
-
function buildPiHome() {
|
|
70
|
-
const home = mkHome()
|
|
71
|
-
writeJson(path.join(home, '.pi', 'agent', 'settings.json'), {
|
|
72
|
-
defaultProvider: 'openai',
|
|
73
|
-
defaultModel: 'gpt-x-terra',
|
|
74
|
-
enabledModels: ['openai/gpt-x-terra', 'openai/gpt-x-sol', 'acme/curated-1'],
|
|
75
|
-
})
|
|
76
|
-
writeJson(path.join(home, '.pi', 'agent', 'models.json'), {
|
|
77
|
-
providers: {
|
|
78
|
-
// openai is curated (has enabledModels entries) — a proxy provider, no models[]
|
|
79
|
-
openai: { baseUrl: 'https://example/v1', apiKey: '$OPENAI_KEY' },
|
|
80
|
-
// literal apiKey → resolves; custom models emitted at model level
|
|
81
|
-
litprov: { apiKey: 'sk-literal-abc', models: [{ id: 'lit-model-1' }, { id: 'lit-model-2' }] },
|
|
82
|
-
// $SET_VAR apiKey → resolves (env injected)
|
|
83
|
-
setprov: { apiKey: '$SET_VAR', models: [{ id: 'set-model-1' }] },
|
|
84
|
-
// $UNSET_VAR apiKey → does NOT resolve; its custom model is a KNOWN definition
|
|
85
|
-
// the user cannot run — the never-a-source / credential-gate case.
|
|
86
|
-
unsetprov: { apiKey: '$UNSET_VAR', models: [{ id: 'unset-model-1' }] },
|
|
87
|
-
},
|
|
88
|
-
})
|
|
89
|
-
// A provider credentialed via auth.json with no enabledModels entry and no
|
|
90
|
-
// models[] detail — listed at PROVIDER level only.
|
|
91
|
-
writeJson(path.join(home, '.pi', 'agent', 'auth.json'), {
|
|
92
|
-
google: { type: 'apiKey', key: 'stored-google-key' },
|
|
93
|
-
})
|
|
94
|
-
return home
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// @covers package:harness-runtime
|
|
98
|
-
// @level integration
|
|
99
|
-
test('pi: discovers enabledModels, the default, and credentialed custom models', () => {
|
|
100
|
-
const home = buildPiHome()
|
|
101
|
-
const { code, json } = run(['--harness', 'pi'], { home, extraEnv: { OPENAI_KEY: 'x', SET_VAR: 'yes' } })
|
|
102
|
-
assert.equal(code, 0)
|
|
103
|
-
assert.equal(json.harness, 'pi')
|
|
104
|
-
assert.equal(json.completeness, 'full')
|
|
105
|
-
const discovered = ids(json)
|
|
106
|
-
// curated picker set
|
|
107
|
-
assert.ok(discovered.includes('openai/gpt-x-terra'))
|
|
108
|
-
assert.ok(discovered.includes('openai/gpt-x-sol'))
|
|
109
|
-
assert.ok(discovered.includes('acme/curated-1'))
|
|
110
|
-
// literal-apiKey custom models
|
|
111
|
-
assert.ok(discovered.includes('litprov/lit-model-1'))
|
|
112
|
-
assert.ok(discovered.includes('litprov/lit-model-2'))
|
|
113
|
-
// $SET_VAR-apiKey custom model
|
|
114
|
-
assert.ok(discovered.includes('setprov/set-model-1'))
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
test('pi: the default provider/model is present and sourced as the default', () => {
|
|
118
|
-
const home = buildPiHome()
|
|
119
|
-
const { json } = run(['--harness', 'pi'], { home, extraEnv: { OPENAI_KEY: 'x', SET_VAR: 'yes' } })
|
|
120
|
-
const entry = json.discovered.find((d) => d.id === 'openai/gpt-x-terra')
|
|
121
|
-
assert.ok(entry, 'default model must be discovered')
|
|
122
|
-
// It is already in enabledModels, so first-source-wins keeps the enabledModels source.
|
|
123
|
-
assert.equal(entry.source, 'settings.json:enabledModels')
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
test('pi: an auth.json-credentialed provider with no enabledModels entry is listed at PROVIDER level only', () => {
|
|
127
|
-
const home = buildPiHome()
|
|
128
|
-
const { json } = run(['--harness', 'pi'], { home, extraEnv: { OPENAI_KEY: 'x', SET_VAR: 'yes' } })
|
|
129
|
-
const discovered = ids(json)
|
|
130
|
-
assert.ok(discovered.includes('google/*'), 'expected provider-level google/*')
|
|
131
|
-
// NEVER an expanded per-model registry for the credentialed-but-uncurated provider.
|
|
132
|
-
assert.ok(!discovered.some((id) => id.startsWith('google/') && id !== 'google/*'),
|
|
133
|
-
'google must appear only at provider level, never expanded into concrete model ids')
|
|
134
|
-
const entry = json.discovered.find((d) => d.id === 'google/*')
|
|
135
|
-
assert.match(entry.source, /auth\.json entry/)
|
|
136
|
-
})
|
|
137
|
-
|
|
138
|
-
test('pi: NEVER-A-SOURCE — a config-known model whose provider key does not resolve is NOT emitted', () => {
|
|
139
|
-
const home = buildPiHome()
|
|
140
|
-
// $UNSET_VAR is deliberately absent from the injected env.
|
|
141
|
-
const { json } = run(['--harness', 'pi'], { home, extraEnv: { OPENAI_KEY: 'x', SET_VAR: 'yes' } })
|
|
142
|
-
const discovered = ids(json)
|
|
143
|
-
assert.ok(
|
|
144
|
-
!discovered.includes('unsetprov/unset-model-1'),
|
|
145
|
-
'a custom model whose provider apiKey ($UNSET_VAR) does not resolve must NOT be discovered — ' +
|
|
146
|
-
'it is a definition the config knows but the user cannot run',
|
|
147
|
-
)
|
|
148
|
-
// And the provider itself is not credentialed, so no provider-level entry either.
|
|
149
|
-
assert.ok(!discovered.includes('unsetprov/*'))
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
test('pi: records the never-a-source rule as a note', () => {
|
|
153
|
-
const home = buildPiHome()
|
|
154
|
-
const { json } = run(['--harness', 'pi'], { home, extraEnv: { OPENAI_KEY: 'x', SET_VAR: 'yes' } })
|
|
155
|
-
assert.ok(json.notes.some((n) => /never a discovery source/.test(n) && /pi --models/.test(n)))
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
test('pi: missing config is graceful — empty set + note, exit 0, no crash', () => {
|
|
159
|
-
const home = mkHome() // no .pi tree at all
|
|
160
|
-
const { code, json } = run(['--harness', 'pi'], { home })
|
|
161
|
-
assert.equal(code, 0)
|
|
162
|
-
assert.equal(json.completeness, 'full')
|
|
163
|
-
assert.deepEqual(json.discovered, [])
|
|
164
|
-
assert.ok(json.notes.some((n) => /not found/.test(n)))
|
|
165
|
-
})
|
|
166
|
-
|
|
167
|
-
// ---- Codex ----
|
|
168
|
-
|
|
169
|
-
// @covers package:harness-runtime
|
|
170
|
-
// @level integration
|
|
171
|
-
test('codex: discovers configured defaults without claiming a complete runnable inventory', () => {
|
|
172
|
-
const home = mkHome()
|
|
173
|
-
writeText(path.join(home, '.codex', 'config.toml'),
|
|
174
|
-
'model = "gpt-x-sol"\n' +
|
|
175
|
-
'model_reasoning_effort = "high"\n' + // must NOT be read as a model
|
|
176
|
-
'model_context_window = 1000000\n' +
|
|
177
|
-
'\n' +
|
|
178
|
-
'[profiles.deep]\n' +
|
|
179
|
-
'model = "gpt-x-max"\n')
|
|
180
|
-
const { code, json } = run(['--harness', 'codex'], { home })
|
|
181
|
-
assert.equal(code, 0)
|
|
182
|
-
assert.equal(json.harness, 'codex')
|
|
183
|
-
assert.equal(json.completeness, 'partial')
|
|
184
|
-
const discovered = ids(json)
|
|
185
|
-
assert.deepEqual(discovered.sort(), ['gpt-x-max', 'gpt-x-sol'].sort())
|
|
186
|
-
// The `model_*` keys must not leak in as models.
|
|
187
|
-
assert.ok(!discovered.includes('high'))
|
|
188
|
-
assert.ok(!discovered.some((id) => /^\d+$/.test(id)))
|
|
189
|
-
// The top-level model is sourced as config.toml:model; the profile one carries its table.
|
|
190
|
-
assert.equal(json.discovered.find((d) => d.id === 'gpt-x-sol').source, 'config.toml:model')
|
|
191
|
-
assert.match(json.discovered.find((d) => d.id === 'gpt-x-max').source, /\[profiles\.deep\]/)
|
|
192
|
-
assert.ok(json.notes.some((note) => /partial/.test(note)))
|
|
193
|
-
})
|
|
194
|
-
|
|
195
|
-
test('codex: current-turn advertised ids are preserved, unioned, and make discovery full', () => {
|
|
196
|
-
const home = mkHome()
|
|
197
|
-
writeText(path.join(home, '.codex', 'config.toml'), 'model = "configured-default"\n')
|
|
198
|
-
const { code, json } = run([
|
|
199
|
-
'--harness', 'codex',
|
|
200
|
-
'--available', 'advertised/model-a,configured-default,advertised:model-b',
|
|
201
|
-
], { home })
|
|
202
|
-
|
|
203
|
-
assert.equal(code, 0)
|
|
204
|
-
assert.equal(json.completeness, 'full')
|
|
205
|
-
assert.deepEqual(ids(json), ['advertised/model-a', 'configured-default', 'advertised:model-b'])
|
|
206
|
-
assert.equal(json.discovered[0].source, 'current-turn')
|
|
207
|
-
assert.equal(json.discovered[2].source, 'current-turn')
|
|
208
|
-
})
|
|
209
|
-
|
|
210
|
-
test('codex: a human-named runnable id is evidence but does not turn partial discovery into full', () => {
|
|
211
|
-
const home = mkHome()
|
|
212
|
-
const { code, json } = run([
|
|
213
|
-
'--harness', 'codex',
|
|
214
|
-
'--human-named', 'operator/model-exact',
|
|
215
|
-
], { home })
|
|
216
|
-
|
|
217
|
-
assert.equal(code, 0)
|
|
218
|
-
assert.equal(json.completeness, 'partial')
|
|
219
|
-
assert.deepEqual(json.discovered, [{ id: 'operator/model-exact', source: 'human-named' }])
|
|
220
|
-
})
|
|
221
|
-
|
|
222
|
-
test('codex: missing config is graceful — empty set + note, exit 0', () => {
|
|
223
|
-
const home = mkHome()
|
|
224
|
-
const { code, json } = run(['--harness', 'codex'], { home })
|
|
225
|
-
assert.equal(code, 0)
|
|
226
|
-
assert.equal(json.completeness, 'partial')
|
|
227
|
-
assert.deepEqual(json.discovered, [])
|
|
228
|
-
assert.ok(json.notes.some((n) => /not found/.test(n)))
|
|
229
|
-
})
|
|
230
|
-
|
|
231
|
-
// ---- Claude Code (honest-partial) ----
|
|
232
|
-
|
|
233
|
-
// @covers package:harness-runtime
|
|
234
|
-
// @level integration
|
|
235
|
-
test('claude-code: is honest-partial — records that discovery stays manual and does NOT read the banked catalog', () => {
|
|
236
|
-
const home = mkHome()
|
|
237
|
-
writeJson(path.join(home, '.claude', 'settings.json'), { effortLevel: 'high', permissions: {} })
|
|
238
|
-
// A banked catalog is present — it must NOT be treated as an availability source.
|
|
239
|
-
writeJson(path.join(home, '.claude', 'model-catalog.json'), {
|
|
240
|
-
harness: 'claude-code',
|
|
241
|
-
models: [{ id: 'should-not-appear', tiers: { high: 'frontier' } }],
|
|
242
|
-
})
|
|
243
|
-
const { code, json } = run(['--harness', 'claude-code'], { home })
|
|
244
|
-
assert.equal(code, 0)
|
|
245
|
-
assert.equal(json.harness, 'claude-code')
|
|
246
|
-
assert.equal(json.completeness, 'partial')
|
|
247
|
-
assert.ok(!ids(json).includes('should-not-appear'),
|
|
248
|
-
'the banked model-catalog.json is a cache of confirmations, never an availability source')
|
|
249
|
-
assert.ok(json.notes.some((n) => /Agent-tool model enum/.test(n) && /stays manual/.test(n)))
|
|
250
|
-
})
|
|
251
|
-
|
|
252
|
-
test('claude-code: current-turn advertised ids complete discovery and union with settings', () => {
|
|
253
|
-
const home = mkHome()
|
|
254
|
-
writeJson(path.join(home, '.claude', 'settings.json'), { model: 'configured-model' })
|
|
255
|
-
const { code, json } = run([
|
|
256
|
-
'--harness', 'claude-code',
|
|
257
|
-
'--available', 'advertised-model,configured-model',
|
|
258
|
-
], { home })
|
|
259
|
-
|
|
260
|
-
assert.equal(code, 0)
|
|
261
|
-
assert.equal(json.completeness, 'full')
|
|
262
|
-
assert.deepEqual(ids(json), ['advertised-model', 'configured-model'])
|
|
263
|
-
assert.ok(json.discovered.every((model) => model.source === 'current-turn'))
|
|
264
|
-
})
|
|
265
|
-
|
|
266
|
-
// ---- CLI contract: help, unknown flags, auto-detect ----
|
|
267
|
-
|
|
268
|
-
test('--help exits 0 with non-empty usage naming the flags and exit codes', () => {
|
|
269
|
-
const { code, stdout } = run(['--help'], { home: mkHome() })
|
|
270
|
-
assert.equal(code, 0)
|
|
271
|
-
assert.ok(stdout.includes('--harness'))
|
|
272
|
-
assert.ok(stdout.includes('--available'))
|
|
273
|
-
assert.ok(stdout.includes('--human-named'))
|
|
274
|
-
assert.ok(stdout.includes('Exit codes'))
|
|
275
|
-
assert.ok(/pi\|codex\|claude-code/.test(stdout))
|
|
276
|
-
})
|
|
277
|
-
|
|
278
|
-
test('-h is an alias for --help (exit 0)', () => {
|
|
279
|
-
const { code, stdout } = run(['-h'], { home: mkHome() })
|
|
280
|
-
assert.equal(code, 0)
|
|
281
|
-
assert.ok(stdout.length > 0)
|
|
282
|
-
})
|
|
283
|
-
|
|
284
|
-
test('an unknown flag exits 2 with usage', () => {
|
|
285
|
-
const { code } = run(['--bogus'], { home: mkHome() })
|
|
286
|
-
assert.equal(code, 2)
|
|
287
|
-
})
|
|
288
|
-
|
|
289
|
-
test('an unknown --harness value exits 2', () => {
|
|
290
|
-
const { code } = run(['--harness', 'nope'], { home: mkHome() })
|
|
291
|
-
assert.equal(code, 2)
|
|
292
|
-
})
|
|
293
|
-
|
|
294
|
-
test('no --harness with an ambiguous/empty HOME exits 2 (never guesses)', () => {
|
|
295
|
-
const { code } = run([], { home: mkHome() }) // empty HOME: no harness present
|
|
296
|
-
assert.equal(code, 2)
|
|
297
|
-
})
|
|
298
|
-
|
|
299
|
-
test('no --harness auto-detects the sole present harness', () => {
|
|
300
|
-
const home = mkHome()
|
|
301
|
-
writeText(path.join(home, '.codex', 'config.toml'), 'model = "solo-model"\n')
|
|
302
|
-
const { code, json } = run([], { home })
|
|
303
|
-
assert.equal(code, 0)
|
|
304
|
-
assert.equal(json.harness, 'codex')
|
|
305
|
-
assert.ok(ids(json).includes('solo-model'))
|
|
306
|
-
})
|
|
307
|
-
|
|
308
|
-
// ---- pure-core unit checks (fast, no spawn) ----
|
|
309
|
-
|
|
310
|
-
test('apiKeyResolves: literal resolves; $SET resolves; $UNSET does not; empty does not', () => {
|
|
311
|
-
assert.equal(apiKeyResolves('sk-abc', {}).resolved, true)
|
|
312
|
-
assert.equal(apiKeyResolves('$K', { K: 'v' }).resolved, true)
|
|
313
|
-
assert.equal(apiKeyResolves('$K', {}).resolved, false)
|
|
314
|
-
assert.equal(apiKeyResolves('', {}).resolved, false)
|
|
315
|
-
assert.equal(apiKeyResolves(undefined, {}).resolved, false)
|
|
316
|
-
})
|
|
317
|
-
|
|
318
|
-
test('discoverPi (pure): credential gate excludes the unresolved custom model', () => {
|
|
319
|
-
const { discovered } = discoverPi({
|
|
320
|
-
settings: { enabledModels: ['a/one'] },
|
|
321
|
-
models: {
|
|
322
|
-
providers: {
|
|
323
|
-
ok: { apiKey: 'lit', models: [{ id: 'runnable' }] },
|
|
324
|
-
no: { apiKey: '$MISSING', models: [{ id: 'notrunnable' }] },
|
|
325
|
-
},
|
|
326
|
-
},
|
|
327
|
-
auth: {},
|
|
328
|
-
env: {},
|
|
329
|
-
})
|
|
330
|
-
const set = discovered.map((d) => d.id)
|
|
331
|
-
assert.ok(set.includes('a/one'))
|
|
332
|
-
assert.ok(set.includes('ok/runnable'))
|
|
333
|
-
assert.ok(!set.includes('no/notrunnable'))
|
|
334
|
-
})
|
|
335
|
-
|
|
336
|
-
// @covers package:harness-runtime
|
|
337
|
-
// @level unit
|
|
338
|
-
test('discoverCodex (pure): explicit current-turn ids pass unchanged and take source precedence', () => {
|
|
339
|
-
const advertised = ['provider/model-a', 'model:b']
|
|
340
|
-
const { discovered, completeness } = discoverCodex({
|
|
341
|
-
configText: 'model = "provider/model-a"\nmodel = "config-only"\n',
|
|
342
|
-
spawnModelIds: advertised,
|
|
343
|
-
})
|
|
344
|
-
assert.equal(completeness, 'full')
|
|
345
|
-
assert.deepEqual(discovered, [
|
|
346
|
-
{ id: 'provider/model-a', source: 'current-turn' },
|
|
347
|
-
{ id: 'model:b', source: 'current-turn' },
|
|
348
|
-
{ id: 'config-only', source: 'config.toml:model' },
|
|
349
|
-
])
|
|
350
|
-
assert.deepEqual(advertised, ['provider/model-a', 'model:b'])
|
|
351
|
-
})
|
|
352
|
-
|
|
353
|
-
test('discoverCodex (pure): empty text yields empty + note, not a throw', () => {
|
|
354
|
-
const { discovered, notes, completeness } = discoverCodex({ configText: null })
|
|
355
|
-
assert.deepEqual(discovered, [])
|
|
356
|
-
assert.equal(completeness, 'partial')
|
|
357
|
-
assert.ok(notes.length > 0)
|
|
358
|
-
})
|
|
359
|
-
|
|
360
|
-
test('discoverClaudeCode (pure): always carries the honest-manual note', () => {
|
|
361
|
-
const { notes } = discoverClaudeCode({ settings: {} })
|
|
362
|
-
assert.ok(notes.some((n) => /stays manual/.test(n)))
|
|
363
|
-
})
|