pstack-dsh 0.2.3
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/HARNESS.md +109 -0
- package/LICENSE +25 -0
- package/README.md +168 -0
- package/TEST-PLAN.md +70 -0
- package/agents/comment-sicko.md +32 -0
- package/agents/poteto-agent.md +9 -0
- package/cordis.patch.yml +4 -0
- package/cordis.yml +4 -0
- package/docs/guide/01-setup.md +41 -0
- package/docs/guide/02-poteto-mode.md +98 -0
- package/docs/guide/03-understand.md +53 -0
- package/docs/guide/04-design.md +81 -0
- package/docs/guide/05-build-and-clean.md +75 -0
- package/docs/guide/06-verify-and-ship.md +87 -0
- package/docs/guide/07-overnight.md +81 -0
- package/docs/guide/08-principles.md +71 -0
- package/docs/guide/09-make-it-yours.md +67 -0
- package/docs/guide/10-recipes-and-pitfalls.md +96 -0
- package/docs/guide/README.md +30 -0
- package/dshx.yml +9 -0
- package/lib/client.js +981 -0
- package/lib/client.js.map +1 -0
- package/lib/index.d.ts +34 -0
- package/lib/index.js +1120 -0
- package/package.json +140 -0
- package/skills/architect/SKILL.md +83 -0
- package/skills/architect/references/design-red-flags.md +33 -0
- package/skills/architect/references/rationale-template.md +35 -0
- package/skills/architect/references/runner-prompt.md +20 -0
- package/skills/arena/SKILL.md +73 -0
- package/skills/automate-me/SKILL.md +103 -0
- package/skills/blast-radius/SKILL.md +50 -0
- package/skills/bro/SKILL.md +7 -0
- package/skills/create-verification-skill/SKILL.md +44 -0
- package/skills/create-verification-skill/references/feature-map-example/README.md +47 -0
- package/skills/create-verification-skill/references/feature-map-example/create-note.md +39 -0
- package/skills/create-verification-skill/references/feature-map-example/search.md +45 -0
- package/skills/figure-it-out/SKILL.md +53 -0
- package/skills/how/SKILL.md +45 -0
- package/skills/how/references/explainer-prompt.md +55 -0
- package/skills/how/references/explorer-prompt.md +52 -0
- package/skills/interrogate/SKILL.md +99 -0
- package/skills/interrogate/references/code-quality-review.md +47 -0
- package/skills/interrogate/references/lead-judgment.md +58 -0
- package/skills/interrogate/references/reviewer-prompt.md +72 -0
- package/skills/interrogate/references/rubric.md +77 -0
- package/skills/maintain-verification-skill/SKILL.md +39 -0
- package/skills/no-comments/SKILL.md +24 -0
- package/skills/poteto-mode/SKILL.md +149 -0
- package/skills/poteto-mode/playbooks/authoring-a-skill.md +12 -0
- package/skills/poteto-mode/playbooks/autonomous-run.md +13 -0
- package/skills/poteto-mode/playbooks/autopilot-full.md +13 -0
- package/skills/poteto-mode/playbooks/autopilot-stack.md +16 -0
- package/skills/poteto-mode/playbooks/babysit.md +27 -0
- package/skills/poteto-mode/playbooks/bug-fix.md +17 -0
- package/skills/poteto-mode/playbooks/eval.md +25 -0
- package/skills/poteto-mode/playbooks/feature.md +21 -0
- package/skills/poteto-mode/playbooks/hillclimb.md +21 -0
- package/skills/poteto-mode/playbooks/investigation.md +14 -0
- package/skills/poteto-mode/playbooks/multi-phase-plan.md +156 -0
- package/skills/poteto-mode/playbooks/opening-a-pr.md +33 -0
- package/skills/poteto-mode/playbooks/orchestrate.md +113 -0
- package/skills/poteto-mode/playbooks/pause-safely.md +10 -0
- package/skills/poteto-mode/playbooks/perf-issue.md +24 -0
- package/skills/poteto-mode/playbooks/prototype.md +14 -0
- package/skills/poteto-mode/playbooks/refactoring.md +16 -0
- package/skills/poteto-mode/playbooks/runtime-forensics.md +11 -0
- package/skills/poteto-mode/playbooks/session-pickup.md +11 -0
- package/skills/poteto-mode/playbooks/shipping.md +17 -0
- package/skills/poteto-mode/playbooks/trace-forensics.md +14 -0
- package/skills/poteto-mode/playbooks/visual-parity.md +11 -0
- package/skills/poteto-mode/playbooks/worktree-cleanup.md +14 -0
- package/skills/poteto-mode/references/bugbot-triage.md +142 -0
- package/skills/poteto-mode/scripts/bootstrap.ts +62 -0
- package/skills/poteto-mode/scripts/bun.lock +67 -0
- package/skills/poteto-mode/scripts/check-plan.mjs +186 -0
- package/skills/poteto-mode/scripts/orch/orch.test.ts +634 -0
- package/skills/poteto-mode/scripts/orch/orch.ts +578 -0
- package/skills/poteto-mode/scripts/orch/store.ts +1607 -0
- package/skills/poteto-mode/scripts/package.json +16 -0
- package/skills/poteto-mode/scripts/watch-pr/cli.test.ts +224 -0
- package/skills/poteto-mode/scripts/watch-pr/cli.ts +223 -0
- package/skills/poteto-mode/scripts/watch-pr/fakes.test-helper.ts +118 -0
- package/skills/poteto-mode/scripts/watch-pr/github.test.ts +306 -0
- package/skills/poteto-mode/scripts/watch-pr/github.ts +699 -0
- package/skills/poteto-mode/scripts/watch-pr/policy.test.ts +420 -0
- package/skills/poteto-mode/scripts/watch-pr/policy.ts +832 -0
- package/skills/poteto-mode/scripts/watch-pr/render.ts +169 -0
- package/skills/poteto-mode/scripts/watch-pr/tsconfig.json +13 -0
- package/skills/poteto-mode/scripts/watch-pr/types.compile.ts +93 -0
- package/skills/poteto-mode/scripts/watch-pr/types.ts +401 -0
- package/skills/poteto-mode/scripts/watch-pr/watch-pr +6 -0
- package/skills/poteto-mode/scripts/worktree-audit.sh +86 -0
- package/skills/principle-attack-the-premise/SKILL.md +22 -0
- package/skills/principle-boundary-discipline/SKILL.md +33 -0
- package/skills/principle-build-the-lever/SKILL.md +22 -0
- package/skills/principle-encode-lessons-in-structure/SKILL.md +30 -0
- package/skills/principle-exhaust-the-design-space/SKILL.md +20 -0
- package/skills/principle-experience-first/SKILL.md +18 -0
- package/skills/principle-fix-root-causes/SKILL.md +22 -0
- package/skills/principle-foundational-thinking/SKILL.md +20 -0
- package/skills/principle-guard-the-context-window/SKILL.md +16 -0
- package/skills/principle-laziness-protocol/SKILL.md +17 -0
- package/skills/principle-make-operations-idempotent/SKILL.md +23 -0
- package/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +21 -0
- package/skills/principle-minimize-reader-load/SKILL.md +22 -0
- package/skills/principle-model-the-domain/SKILL.md +25 -0
- package/skills/principle-never-block-on-the-human/SKILL.md +21 -0
- package/skills/principle-outcome-oriented-execution/SKILL.md +21 -0
- package/skills/principle-prove-it-works/SKILL.md +32 -0
- package/skills/principle-redesign-from-first-principles/SKILL.md +15 -0
- package/skills/principle-separate-before-serializing-shared-state/SKILL.md +15 -0
- package/skills/principle-sequence-verifiable-units/SKILL.md +21 -0
- package/skills/principle-subtract-before-you-add/SKILL.md +20 -0
- package/skills/principle-test-behavior-not-implementation/SKILL.md +24 -0
- package/skills/principle-type-system-discipline/SKILL.md +30 -0
- package/skills/recall/SKILL.md +35 -0
- package/skills/reflect/SKILL.md +65 -0
- package/skills/reflect/references/divergent-reviewer.md +43 -0
- package/skills/reflect/references/judgment-reviewer.md +42 -0
- package/skills/reflect/references/synthesizer.md +56 -0
- package/skills/reflect/references/tooling-reviewer.md +55 -0
- package/skills/setup-pstack/SKILL.md +32 -0
- package/skills/setup-pstack/references/catalog.md +28 -0
- package/skills/setup-pstack/references/spawn.md +61 -0
- package/skills/show-me-your-work/SKILL.md +82 -0
- package/skills/show-me-your-work/references/decision-log-template.tsv +1 -0
- package/skills/show-me-your-work/scripts/log.sh +40 -0
- package/skills/swarm/SKILL.md +44 -0
- package/skills/tdd/SKILL.md +44 -0
- package/skills/teach/SKILL.md +21 -0
- package/skills/technical-writing/SKILL.md +127 -0
- package/skills/typescript-best-practices/SKILL.md +30 -0
- package/skills/typescript-best-practices/references/patterns.md +313 -0
- package/skills/unslop/SKILL.md +67 -0
- package/skills/why/SKILL.md +146 -0
- package/skills/why/references/epistemics.md +144 -0
- package/skills/why/references/investigator-prompt.md +103 -0
- package/skills/why/references/source-playbook.md +17 -0
- package/skills/why/references/sources/code-archaeology.md +88 -0
- package/skills/why/references/sources/databricks.md +70 -0
- package/skills/why/references/sources/datadog.md +99 -0
- package/skills/why/references/sources/incident-postmortem.md +15 -0
- package/skills/why/references/sources/linear.md +48 -0
- package/skills/why/references/sources/notion.md +55 -0
- package/skills/why/references/sources/sentry.md +100 -0
- package/skills/why/references/sources/slack.md +54 -0
- package/skills/why/references/synthesizer-prompt.md +135 -0
- package/src/catalog-types.ts +54 -0
- package/src/catalog.ts +308 -0
- package/src/client/PstackSettings.tsx +519 -0
- package/src/client/api.ts +56 -0
- package/src/client/index.tsx +38 -0
- package/src/client/locales.ts +65 -0
- package/src/client/poteto-defaults.ts +37 -0
- package/src/frontmatter.ts +73 -0
- package/src/home.ts +13 -0
- package/src/http-trust.ts +38 -0
- package/src/ids.ts +39 -0
- package/src/index.ts +85 -0
- package/src/overlay-model.ts +139 -0
- package/src/overlay.ts +40 -0
- package/src/persona.ts +38 -0
- package/src/plugin-config.ts +29 -0
- package/src/request-overlay.ts +40 -0
- package/src/roles.ts +55 -0
- package/src/settings-api.ts +48 -0
- package/src/settings-draft.ts +144 -0
- package/src/settings-routes.ts +77 -0
- package/src/skills-provider.ts +96 -0
- package/src/spawn.ts +52 -0
- package/src/tools.ts +226 -0
package/src/catalog.ts
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises'
|
|
2
|
+
import { join } from 'node:path'
|
|
3
|
+
import {
|
|
4
|
+
ANTIGRAVITY_AUTH_FILENAME,
|
|
5
|
+
ANTIGRAVITY_PROVIDER,
|
|
6
|
+
DEEPSEEK_API_KEY_ENV,
|
|
7
|
+
DEEPSEEK_PROVIDER,
|
|
8
|
+
OAUTH_AUTH_FILENAME,
|
|
9
|
+
OAUTH_AUTH_LEGACY_FILENAME,
|
|
10
|
+
} from './ids.ts'
|
|
11
|
+
import { resolveDshHome } from './home.ts'
|
|
12
|
+
import {
|
|
13
|
+
OAUTH_ROUTE_BY_STORE_ID,
|
|
14
|
+
storeIdForRoute,
|
|
15
|
+
type CatalogResult,
|
|
16
|
+
type LiveEffort,
|
|
17
|
+
type LiveRoute,
|
|
18
|
+
} from './catalog-types.ts'
|
|
19
|
+
import { readOverlay } from './overlay.ts'
|
|
20
|
+
|
|
21
|
+
export type { CatalogResult, LiveEffort, LiveRoute } from './catalog-types.ts'
|
|
22
|
+
|
|
23
|
+
const API_KEY_REF = /^[A-Za-z_][A-Za-z0-9_]*$/
|
|
24
|
+
|
|
25
|
+
interface LlmLike {
|
|
26
|
+
listProviders(): { id: string; name: string }[]
|
|
27
|
+
listConfigurableProviders?(): { provider: string; displayName: string; settingsNs: string; settingsPath: readonly string[] }[]
|
|
28
|
+
listModels(provider: string): Promise<{ id: string; name: string }[]>
|
|
29
|
+
resolveModelInfo(provider: string, model: string, signal?: AbortSignal): Promise<{
|
|
30
|
+
id: string
|
|
31
|
+
name: string
|
|
32
|
+
reasoning?: { efforts: LiveEffort[]; defaultEffort?: string }
|
|
33
|
+
}>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface CredentialsLike {
|
|
37
|
+
describe(ref: string): Promise<{ configured: boolean; source?: string }>
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface SettingsLike {
|
|
41
|
+
describe(options?: { redactSecrets?: boolean }): unknown[]
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface CatalogHost {
|
|
45
|
+
llm?: LlmLike
|
|
46
|
+
credentials?: CredentialsLike
|
|
47
|
+
settings?: SettingsLike
|
|
48
|
+
dshHome?: string
|
|
49
|
+
env?: NodeJS.ProcessEnv
|
|
50
|
+
nowProviders?: () => string[]
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
54
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function collectApiKeyEnvRefs(value: unknown, out: Set<string>): void {
|
|
58
|
+
if (Array.isArray(value)) {
|
|
59
|
+
for (const item of value) collectApiKeyEnvRefs(item, out)
|
|
60
|
+
return
|
|
61
|
+
}
|
|
62
|
+
if (!isRecord(value)) return
|
|
63
|
+
for (const [key, child] of Object.entries(value)) {
|
|
64
|
+
if (key === 'apiKeyEnv' && typeof child === 'string' && API_KEY_REF.test(child)) out.add(child)
|
|
65
|
+
else collectApiKeyEnvRefs(child, out)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function sliceAtPath(value: unknown, path: readonly string[]): unknown {
|
|
70
|
+
let current = value
|
|
71
|
+
for (const segment of path) {
|
|
72
|
+
if (!isRecord(current)) return undefined
|
|
73
|
+
current = current[segment]
|
|
74
|
+
}
|
|
75
|
+
return current
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function settingsValue(entry: unknown): unknown {
|
|
79
|
+
if (!isRecord(entry)) return undefined
|
|
80
|
+
return entry.value ?? entry.base ?? entry.user
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function settingsNs(entry: unknown): string | undefined {
|
|
84
|
+
if (!isRecord(entry)) return undefined
|
|
85
|
+
return typeof entry.ns === 'string' ? entry.ns : undefined
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function refConfigured(credentials: CredentialsLike | undefined, env: NodeJS.ProcessEnv, ref: string): Promise<boolean> {
|
|
89
|
+
if (credentials !== undefined) {
|
|
90
|
+
try {
|
|
91
|
+
const info = await credentials.describe(ref)
|
|
92
|
+
return info.configured === true
|
|
93
|
+
} catch {
|
|
94
|
+
return false
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const ambient = env[ref]
|
|
98
|
+
return typeof ambient === 'string' && ambient.trim().length > 0
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function readOauthStoreIds(dshHome: string): Promise<{ present: boolean; ids: string[] }> {
|
|
102
|
+
const candidates = [join(dshHome, OAUTH_AUTH_FILENAME), join(dshHome, OAUTH_AUTH_LEGACY_FILENAME)]
|
|
103
|
+
let present = false
|
|
104
|
+
const ids = new Set<string>()
|
|
105
|
+
for (const filename of candidates) {
|
|
106
|
+
try {
|
|
107
|
+
const text = await readFile(filename, 'utf8')
|
|
108
|
+
const parsed: unknown = JSON.parse(text)
|
|
109
|
+
if (!isRecord(parsed) || !isRecord(parsed.credentials)) continue
|
|
110
|
+
present = true
|
|
111
|
+
for (const key of Object.keys(parsed.credentials)) ids.add(key)
|
|
112
|
+
break
|
|
113
|
+
} catch (error) {
|
|
114
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') continue
|
|
115
|
+
present = true
|
|
116
|
+
break
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
const text = await readFile(join(dshHome, ANTIGRAVITY_AUTH_FILENAME), 'utf8')
|
|
122
|
+
const parsed: unknown = JSON.parse(text)
|
|
123
|
+
if (isRecord(parsed) && isRecord(parsed.credential)) {
|
|
124
|
+
present = true
|
|
125
|
+
const cred = parsed.credential
|
|
126
|
+
if (
|
|
127
|
+
cred.type === 'oauth'
|
|
128
|
+
&& typeof cred.projectId === 'string'
|
|
129
|
+
&& cred.projectId.trim().length > 0
|
|
130
|
+
&& typeof cred.expires === 'number'
|
|
131
|
+
&& cred.expires > 0
|
|
132
|
+
) {
|
|
133
|
+
ids.add('antigravity')
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
} catch (error) {
|
|
137
|
+
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {
|
|
138
|
+
present = true
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return { present, ids: [...ids] }
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function effortsOf(info: { reasoning?: { efforts: LiveEffort[]; defaultEffort?: string } }): {
|
|
146
|
+
efforts: LiveEffort[]
|
|
147
|
+
defaultEffort?: string
|
|
148
|
+
} {
|
|
149
|
+
const reasoning = info.reasoning
|
|
150
|
+
if (reasoning === undefined || !Array.isArray(reasoning.efforts)) return { efforts: [] }
|
|
151
|
+
return {
|
|
152
|
+
efforts: reasoning.efforts.map(effort => ({
|
|
153
|
+
id: effort.id,
|
|
154
|
+
name: effort.name,
|
|
155
|
+
...effort.description === undefined ? {} : { description: effort.description },
|
|
156
|
+
})),
|
|
157
|
+
...reasoning.defaultEffort === undefined ? {} : { defaultEffort: reasoning.defaultEffort },
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Live logged-in routes only. No vendor catalog. No invented slugs.
|
|
163
|
+
*/
|
|
164
|
+
export async function buildCatalog(host: CatalogHost, signal?: AbortSignal): Promise<CatalogResult> {
|
|
165
|
+
const dshHome = host.dshHome ?? resolveDshHome(host.env)
|
|
166
|
+
const env = host.env ?? process.env
|
|
167
|
+
const overlay = await readOverlay(dshHome)
|
|
168
|
+
const oauth = await readOauthStoreIds(dshHome)
|
|
169
|
+
const llm = host.llm
|
|
170
|
+
const providers = llm?.listProviders() ?? []
|
|
171
|
+
const registered = new Set(providers.map(provider => provider.id))
|
|
172
|
+
const oauthPluginPresent = [...registered].some(id => id.startsWith('pi-') || id === ANTIGRAVITY_PROVIDER || id.startsWith('agy-'))
|
|
173
|
+
const recommendOauthLogin = oauth.ids.length === 0 && !oauthPluginPresent
|
|
174
|
+
|
|
175
|
+
const refsByProvider = new Map<string, Set<string>>()
|
|
176
|
+
const remember = (provider: string, ref: string) => {
|
|
177
|
+
const set = refsByProvider.get(provider) ?? new Set<string>()
|
|
178
|
+
set.add(ref)
|
|
179
|
+
refsByProvider.set(provider, set)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (host.settings !== undefined) {
|
|
183
|
+
let described: unknown[] = []
|
|
184
|
+
try {
|
|
185
|
+
described = host.settings.describe({ redactSecrets: true })
|
|
186
|
+
} catch {
|
|
187
|
+
described = []
|
|
188
|
+
}
|
|
189
|
+
const configurable = llm?.listConfigurableProviders?.() ?? []
|
|
190
|
+
for (const entry of described) {
|
|
191
|
+
const ns = settingsNs(entry)
|
|
192
|
+
const value = settingsValue(entry)
|
|
193
|
+
for (const row of configurable) {
|
|
194
|
+
if (ns !== undefined && row.settingsNs !== ns) continue
|
|
195
|
+
const slice = row.settingsPath.length === 0 ? value : sliceAtPath(value, row.settingsPath)
|
|
196
|
+
const refs = new Set<string>()
|
|
197
|
+
collectApiKeyEnvRefs(slice ?? value, refs)
|
|
198
|
+
for (const ref of refs) remember(row.provider, ref)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
for (const provider of providers) {
|
|
204
|
+
if (provider.id === DEEPSEEK_PROVIDER) remember(provider.id, DEEPSEEK_API_KEY_ENV)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const routes: LiveRoute[] = []
|
|
208
|
+
const seen = new Set<string>()
|
|
209
|
+
|
|
210
|
+
const push = (route: LiveRoute) => {
|
|
211
|
+
const key = `${route.provider}::${route.model}`
|
|
212
|
+
if (seen.has(key)) return
|
|
213
|
+
seen.add(key)
|
|
214
|
+
routes.push(route)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (llm !== undefined) {
|
|
218
|
+
for (const provider of providers) {
|
|
219
|
+
const storeId = storeIdForRoute(provider.id)
|
|
220
|
+
const oauthSignedIn = storeId !== undefined && oauth.ids.includes(storeId)
|
|
221
|
+
let models: { id: string; name: string }[] = []
|
|
222
|
+
try {
|
|
223
|
+
models = await llm.listModels(provider.id)
|
|
224
|
+
} catch {
|
|
225
|
+
models = []
|
|
226
|
+
}
|
|
227
|
+
if (models.length === 0) continue
|
|
228
|
+
|
|
229
|
+
const refs = [...(refsByProvider.get(provider.id) ?? [])]
|
|
230
|
+
let keyPresent = false
|
|
231
|
+
for (const ref of refs) {
|
|
232
|
+
if (await refConfigured(host.credentials, env, ref)) {
|
|
233
|
+
keyPresent = true
|
|
234
|
+
break
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const selectable = oauthSignedIn || keyPresent
|
|
239
|
+
const source: LiveRoute['source'] = oauthSignedIn ? 'oauth' : 'api-key'
|
|
240
|
+
if (!selectable) continue
|
|
241
|
+
|
|
242
|
+
for (const model of models) {
|
|
243
|
+
let resolved: { id: string; name: string; reasoning?: { efforts: LiveEffort[]; defaultEffort?: string } }
|
|
244
|
+
try {
|
|
245
|
+
resolved = await llm.resolveModelInfo(provider.id, model.id, signal)
|
|
246
|
+
} catch {
|
|
247
|
+
resolved = { id: model.id, name: model.name }
|
|
248
|
+
}
|
|
249
|
+
const { efforts, defaultEffort } = effortsOf(resolved)
|
|
250
|
+
push({
|
|
251
|
+
provider: provider.id,
|
|
252
|
+
providerName: provider.name,
|
|
253
|
+
model: model.id,
|
|
254
|
+
modelName: resolved.name || model.name,
|
|
255
|
+
selectable: true,
|
|
256
|
+
source,
|
|
257
|
+
...oauthSignedIn ? { oauthSignedIn: true } : {},
|
|
258
|
+
routeRegistered: true,
|
|
259
|
+
efforts,
|
|
260
|
+
...defaultEffort === undefined ? {} : { defaultEffort },
|
|
261
|
+
})
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
for (const id of oauth.ids) {
|
|
267
|
+
const route = OAUTH_ROUTE_BY_STORE_ID[id]
|
|
268
|
+
if (route === undefined) continue
|
|
269
|
+
if (registered.has(route)) continue
|
|
270
|
+
const isAntigravity = id === 'antigravity' || route === ANTIGRAVITY_PROVIDER
|
|
271
|
+
push({
|
|
272
|
+
provider: route,
|
|
273
|
+
providerName: isAntigravity ? 'Google Antigravity' : id,
|
|
274
|
+
model: '*',
|
|
275
|
+
modelName: isAntigravity
|
|
276
|
+
? '(install dsh-antigravity-oauth to load this route)'
|
|
277
|
+
: '(install dsh-oauth-login to load this route)',
|
|
278
|
+
selectable: false,
|
|
279
|
+
source: 'oauth',
|
|
280
|
+
oauthSignedIn: true,
|
|
281
|
+
routeRegistered: false,
|
|
282
|
+
efforts: [],
|
|
283
|
+
hint: isAntigravity
|
|
284
|
+
? 'Signed in at $DSH_HOME/.dsh-antigravity-oauth.json. Install dsh-antigravity-oauth so the route is live.'
|
|
285
|
+
: 'Signed in at $DSH_HOME/.dsh-oauth-auth.json. Install https://github.com/aa2246740/dsh-oauth-login so the route is live.',
|
|
286
|
+
})
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const selectableCount = routes.filter(route => route.selectable).length
|
|
290
|
+
return {
|
|
291
|
+
routes,
|
|
292
|
+
selectableCount,
|
|
293
|
+
oauthPluginPresent,
|
|
294
|
+
oauthStorePresent: oauth.present,
|
|
295
|
+
oauthSignedInProviders: oauth.ids,
|
|
296
|
+
overlayPath: overlay.path,
|
|
297
|
+
overlayMissing: overlay.missing,
|
|
298
|
+
inheritParent: true,
|
|
299
|
+
recommendOauthLogin,
|
|
300
|
+
...selectableCount === 0
|
|
301
|
+
? {
|
|
302
|
+
emptyReason: recommendOauthLogin
|
|
303
|
+
? 'No logged-in API key and no dsh-oauth-login or dsh-antigravity-oauth store. Children inherit this conversation. Add a key in DSH, or install/login https://github.com/aa2246740/dsh-oauth-login / dsh-antigravity-oauth.'
|
|
304
|
+
: 'No selectable live route. Children inherit this conversation.',
|
|
305
|
+
}
|
|
306
|
+
: {},
|
|
307
|
+
}
|
|
308
|
+
}
|