@kindgi/cli 0.1.4-rc.5 → 0.1.5-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -10
- package/dist/build/defaults.d.ts +3 -1
- package/dist/build/defaults.d.ts.map +1 -1
- package/dist/build/defaults.js +44 -1
- package/dist/build/defaults.js.map +1 -1
- package/dist/build/java-image.d.ts +31 -0
- package/dist/build/java-image.d.ts.map +1 -0
- package/dist/build/java-image.js +146 -0
- package/dist/build/java-image.js.map +1 -0
- package/dist/build/pack-root.d.ts +1 -31
- package/dist/build/pack-root.d.ts.map +1 -1
- package/dist/build/pack-root.js +22 -2
- package/dist/build/pack-root.js.map +1 -1
- package/dist/build/runners.d.ts +44 -0
- package/dist/build/runners.d.ts.map +1 -1
- package/dist/build/scala-image.d.ts +21 -0
- package/dist/build/scala-image.d.ts.map +1 -0
- package/dist/build/scala-image.js +150 -0
- package/dist/build/scala-image.js.map +1 -0
- package/dist/cli-pin.d.ts +16 -0
- package/dist/cli-pin.d.ts.map +1 -0
- package/dist/cli-pin.js +66 -0
- package/dist/cli-pin.js.map +1 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +9 -8
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/approvals.d.ts.map +1 -1
- package/dist/commands/approvals.js +30 -4
- package/dist/commands/approvals.js.map +1 -1
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +100 -37
- package/dist/commands/artifacts.js.map +1 -1
- package/dist/commands/auth.js +2 -2
- package/dist/commands/blocks.d.ts.map +1 -1
- package/dist/commands/blocks.js +5 -4
- package/dist/commands/blocks.js.map +1 -1
- package/dist/commands/build.d.ts +10 -2
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +109 -16
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/capabilities.d.ts.map +1 -1
- package/dist/commands/capabilities.js +37 -10
- package/dist/commands/capabilities.js.map +1 -1
- package/dist/commands/console.d.ts +21 -0
- package/dist/commands/console.d.ts.map +1 -0
- package/dist/commands/console.js +87 -0
- package/dist/commands/console.js.map +1 -0
- package/dist/commands/conversations.d.ts.map +1 -1
- package/dist/commands/conversations.js +13 -2
- package/dist/commands/conversations.js.map +1 -1
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +2 -2
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts +11 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +211 -39
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/doctor.d.ts +18 -5
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +421 -21
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/env-scoped.d.ts +44 -0
- package/dist/commands/env-scoped.d.ts.map +1 -0
- package/dist/commands/env-scoped.js +222 -0
- package/dist/commands/env-scoped.js.map +1 -0
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +85 -123
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/eval-runs.d.ts +9 -0
- package/dist/commands/eval-runs.d.ts.map +1 -1
- package/dist/commands/eval-runs.js +20 -19
- package/dist/commands/eval-runs.js.map +1 -1
- package/dist/commands/eval-suites.d.ts.map +1 -1
- package/dist/commands/eval-suites.js +16 -8
- package/dist/commands/eval-suites.js.map +1 -1
- package/dist/commands/exports.d.ts +3 -0
- package/dist/commands/exports.d.ts.map +1 -0
- package/dist/commands/exports.js +82 -0
- package/dist/commands/exports.js.map +1 -0
- package/dist/commands/feedback.d.ts.map +1 -1
- package/dist/commands/feedback.js +6 -5
- package/dist/commands/feedback.js.map +1 -1
- package/dist/commands/flows.d.ts.map +1 -1
- package/dist/commands/flows.js +2 -1
- package/dist/commands/flows.js.map +1 -1
- package/dist/commands/gate-policies.d.ts.map +1 -1
- package/dist/commands/gate-policies.js +2 -1
- package/dist/commands/gate-policies.js.map +1 -1
- package/dist/commands/guardrails.d.ts.map +1 -1
- package/dist/commands/guardrails.js +3 -2
- package/dist/commands/guardrails.js.map +1 -1
- package/dist/commands/helpers.js +5 -5
- package/dist/commands/helpers.js.map +1 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +14 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +254 -18
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/judge-classes.d.ts.map +1 -1
- package/dist/commands/judge-classes.js +11 -10
- package/dist/commands/judge-classes.js.map +1 -1
- package/dist/commands/judgments.d.ts.map +1 -1
- package/dist/commands/judgments.js +7 -6
- package/dist/commands/judgments.js.map +1 -1
- package/dist/commands/key.js +4 -4
- package/dist/commands/memory.d.ts.map +1 -1
- package/dist/commands/memory.js +277 -25
- package/dist/commands/memory.js.map +1 -1
- package/dist/commands/people.d.ts +3 -0
- package/dist/commands/people.d.ts.map +1 -0
- package/dist/commands/people.js +166 -0
- package/dist/commands/people.js.map +1 -0
- package/dist/commands/proposals.d.ts.map +1 -1
- package/dist/commands/proposals.js +390 -69
- package/dist/commands/proposals.js.map +1 -1
- package/dist/commands/provenance.d.ts.map +1 -1
- package/dist/commands/provenance.js +6 -7
- package/dist/commands/provenance.js.map +1 -1
- package/dist/commands/providers.d.ts.map +1 -1
- package/dist/commands/providers.js +46 -7
- package/dist/commands/providers.js.map +1 -1
- package/dist/commands/reviewers.d.ts.map +1 -1
- package/dist/commands/reviewers.js +3 -2
- package/dist/commands/reviewers.js.map +1 -1
- package/dist/commands/runs.d.ts.map +1 -1
- package/dist/commands/runs.js +24 -14
- package/dist/commands/runs.js.map +1 -1
- package/dist/commands/schedules.d.ts +3 -0
- package/dist/commands/schedules.d.ts.map +1 -0
- package/dist/commands/schedules.js +275 -0
- package/dist/commands/schedules.js.map +1 -0
- package/dist/commands/secrets.d.ts.map +1 -1
- package/dist/commands/secrets.js +10 -11
- package/dist/commands/secrets.js.map +1 -1
- package/dist/commands/service-accounts.d.ts +3 -0
- package/dist/commands/service-accounts.d.ts.map +1 -0
- package/dist/commands/service-accounts.js +175 -0
- package/dist/commands/service-accounts.js.map +1 -0
- package/dist/commands/skills.d.ts +1 -1
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +11 -4
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/sso.d.ts +6 -0
- package/dist/commands/sso.d.ts.map +1 -0
- package/dist/commands/sso.js +318 -0
- package/dist/commands/sso.js.map +1 -0
- package/dist/commands/tokens.d.ts +11 -0
- package/dist/commands/tokens.d.ts.map +1 -1
- package/dist/commands/tokens.js +144 -11
- package/dist/commands/tokens.js.map +1 -1
- package/dist/commands/tools.d.ts.map +1 -1
- package/dist/commands/tools.js +4 -3
- package/dist/commands/tools.js.map +1 -1
- package/dist/commands/unwired.d.ts.map +1 -1
- package/dist/commands/unwired.js +1 -30
- package/dist/commands/unwired.js.map +1 -1
- package/dist/commands/upgrade.d.ts +11 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +160 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/context.d.ts +7 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +1 -0
- package/dist/context.js.map +1 -1
- package/dist/dev/defaults.d.ts +28 -11
- package/dist/dev/defaults.d.ts.map +1 -1
- package/dist/dev/defaults.js +114 -35
- package/dist/dev/defaults.js.map +1 -1
- package/dist/dev/google-credentials.d.ts +50 -0
- package/dist/dev/google-credentials.d.ts.map +1 -0
- package/dist/dev/google-credentials.js +157 -0
- package/dist/dev/google-credentials.js.map +1 -0
- package/dist/dev/java-builder.d.ts +56 -0
- package/dist/dev/java-builder.d.ts.map +1 -0
- package/dist/dev/java-builder.js +204 -0
- package/dist/dev/java-builder.js.map +1 -0
- package/dist/dev/jvm-run-files.d.ts +29 -0
- package/dist/dev/jvm-run-files.d.ts.map +1 -0
- package/dist/dev/jvm-run-files.js +94 -0
- package/dist/dev/jvm-run-files.js.map +1 -0
- package/dist/dev/lines.d.ts +13 -0
- package/dist/dev/lines.d.ts.map +1 -0
- package/dist/dev/lines.js +24 -0
- package/dist/dev/lines.js.map +1 -0
- package/dist/dev/log-view.d.ts +116 -0
- package/dist/dev/log-view.d.ts.map +1 -0
- package/dist/dev/log-view.js +233 -0
- package/dist/dev/log-view.js.map +1 -0
- package/dist/dev/pack-code.d.ts +79 -4
- package/dist/dev/pack-code.d.ts.map +1 -1
- package/dist/dev/pack-code.js +262 -3
- package/dist/dev/pack-code.js.map +1 -1
- package/dist/dev/pack-env.d.ts.map +1 -1
- package/dist/dev/pack-env.js +4 -0
- package/dist/dev/pack-env.js.map +1 -1
- package/dist/dev/pack-service.d.ts +11 -1
- package/dist/dev/pack-service.d.ts.map +1 -1
- package/dist/dev/pack-service.js +56 -20
- package/dist/dev/pack-service.js.map +1 -1
- package/dist/dev/paths.d.ts +6 -0
- package/dist/dev/paths.d.ts.map +1 -1
- package/dist/dev/paths.js +8 -0
- package/dist/dev/paths.js.map +1 -1
- package/dist/dev/project-database.js +1 -1
- package/dist/dev/project-database.js.map +1 -1
- package/dist/dev/runners.d.ts +35 -9
- package/dist/dev/runners.d.ts.map +1 -1
- package/dist/dev/runtime-container.d.ts +10 -2
- package/dist/dev/runtime-container.d.ts.map +1 -1
- package/dist/dev/runtime-container.js +48 -20
- package/dist/dev/runtime-container.js.map +1 -1
- package/dist/dev/runtime-env.d.ts +10 -0
- package/dist/dev/runtime-env.d.ts.map +1 -1
- package/dist/dev/runtime-env.js +8 -4
- package/dist/dev/runtime-env.js.map +1 -1
- package/dist/dev/runtime-image.d.ts +1 -1
- package/dist/dev/runtime-image.js +1 -1
- package/dist/dev/scala-builder.d.ts +72 -0
- package/dist/dev/scala-builder.d.ts.map +1 -0
- package/dist/dev/scala-builder.js +347 -0
- package/dist/dev/scala-builder.js.map +1 -0
- package/dist/env/project-env.d.ts.map +1 -1
- package/dist/env/project-env.js +3 -1
- package/dist/env/project-env.js.map +1 -1
- package/dist/errors.d.ts +9 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +15 -0
- package/dist/errors.js.map +1 -1
- package/dist/help.d.ts +14 -0
- package/dist/help.d.ts.map +1 -1
- package/dist/help.js +55 -0
- package/dist/help.js.map +1 -1
- package/dist/init/dependency-specs.d.ts +26 -0
- package/dist/init/dependency-specs.d.ts.map +1 -1
- package/dist/init/dependency-specs.js +38 -0
- package/dist/init/dependency-specs.js.map +1 -1
- package/dist/init/java-augment.d.ts +24 -0
- package/dist/init/java-augment.d.ts.map +1 -0
- package/dist/init/java-augment.js +198 -0
- package/dist/init/java-augment.js.map +1 -0
- package/dist/init/mode-detect.d.ts +2 -2
- package/dist/init/mode-detect.d.ts.map +1 -1
- package/dist/init/mode-detect.js +12 -1
- package/dist/init/mode-detect.js.map +1 -1
- package/dist/init/scala-augment.d.ts +23 -0
- package/dist/init/scala-augment.d.ts.map +1 -0
- package/dist/init/scala-augment.js +213 -0
- package/dist/init/scala-augment.js.map +1 -0
- package/dist/init/template-files.d.ts +40 -2
- package/dist/init/template-files.d.ts.map +1 -1
- package/dist/init/template-files.js +56 -5
- package/dist/init/template-files.js.map +1 -1
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +30 -4
- package/dist/main.js.map +1 -1
- package/dist/open-url.d.ts +15 -0
- package/dist/open-url.d.ts.map +1 -0
- package/dist/open-url.js +41 -0
- package/dist/open-url.js.map +1 -0
- package/dist/package-manager.d.ts +10 -3
- package/dist/package-manager.d.ts.map +1 -1
- package/dist/package-manager.js +19 -1
- package/dist/package-manager.js.map +1 -1
- package/dist/providers/preset-loader.d.ts.map +1 -1
- package/dist/providers/preset-loader.js +9 -1
- package/dist/providers/preset-loader.js.map +1 -1
- package/dist/providers/presets/anthropic.json +35 -4
- package/dist/providers/presets/gemini-api.json +3 -0
- package/dist/providers/presets/gemini.json +3 -0
- package/dist/providers/presets/groq.json +1 -0
- package/dist/providers/presets/openai.json +36 -4
- package/dist/providers/presets/openrouter.json +6 -2
- package/dist/sdk-skills/kindgi-authoring-agents/SKILL.md +28 -4
- package/dist/sdk-skills/kindgi-authoring-flows/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-authoring-guardrails/SKILL.md +47 -3
- package/dist/sdk-skills/kindgi-authoring-mcp-servers/SKILL.md +7 -5
- package/dist/sdk-skills/kindgi-authoring-providers/SKILL.md +81 -52
- package/dist/sdk-skills/kindgi-authoring-tools/SKILL.md +27 -1
- package/dist/sdk-skills/kindgi-framework-feedback/SKILL.md +5 -4
- package/dist/sdk-skills/kindgi-getting-started/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-java-authoring-agents/SKILL.md +220 -0
- package/dist/sdk-skills/kindgi-java-authoring-flows/SKILL.md +390 -0
- package/dist/sdk-skills/kindgi-java-authoring-guardrails/SKILL.md +209 -0
- package/dist/sdk-skills/kindgi-java-authoring-tools/SKILL.md +334 -0
- package/dist/sdk-skills/kindgi-java-getting-started/SKILL.md +270 -0
- package/dist/sdk-skills/kindgi-python-authoring-agents/SKILL.md +23 -5
- package/dist/sdk-skills/kindgi-python-authoring-flows/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-python-authoring-guardrails/SKILL.md +10 -3
- package/dist/sdk-skills/kindgi-python-authoring-tools/SKILL.md +36 -5
- package/dist/sdk-skills/kindgi-python-getting-started/SKILL.md +2 -2
- package/dist/sdk-skills/kindgi-scala-authoring-agents/SKILL.md +217 -0
- package/dist/sdk-skills/kindgi-scala-authoring-flows/SKILL.md +357 -0
- package/dist/sdk-skills/kindgi-scala-authoring-guardrails/SKILL.md +199 -0
- package/dist/sdk-skills/kindgi-scala-authoring-tools/SKILL.md +302 -0
- package/dist/sdk-skills/kindgi-scala-getting-started/SKILL.md +302 -0
- package/dist/templates/java/.mvn/wrapper/maven-wrapper.properties +3 -0
- package/dist/templates/java/AGENTS.md +31 -0
- package/dist/templates/java/README.md.tmpl +69 -0
- package/dist/templates/java/gitignore +9 -0
- package/dist/templates/java/kindgi.config.json.tmpl +8 -0
- package/dist/templates/java/kindgiw +33 -0
- package/dist/templates/java/kindgiw.cmd +28 -0
- package/dist/templates/java/mvnw +295 -0
- package/dist/templates/java/pom.xml.tmpl +65 -0
- package/dist/templates/java/src/main/java/__PACKAGE__/agents/EchoAgent.java.tmpl +27 -0
- package/dist/templates/java/src/main/java/__PACKAGE__/flows/EchoFlow.java.tmpl +18 -0
- package/dist/templates/java/src/main/java/__PACKAGE__/guardrails/ResponseNotEmpty.java.tmpl +28 -0
- package/dist/templates/java/src/main/java/__PACKAGE__/tools/Echo.java.tmpl +22 -0
- package/dist/templates/java/src/main/java/__PACKAGE__/tools/Greet.java.tmpl +23 -0
- package/dist/templates/java/src/test/java/__PACKAGE__/ToolsTest.java.tmpl +30 -0
- package/dist/templates/minimal/README.md.tmpl +8 -14
- package/dist/templates/python/README.md.tmpl +6 -6
- package/dist/templates/sample/README.md.tmpl +7 -13
- package/dist/templates/scala/AGENTS.md +32 -0
- package/dist/templates/scala/README.md.tmpl +75 -0
- package/dist/templates/scala/build.sbt.tmpl +16 -0
- package/dist/templates/scala/gitignore +13 -0
- package/dist/templates/scala/kindgi.config.json.tmpl +8 -0
- package/dist/templates/scala/project/build.properties +1 -0
- package/dist/templates/scala/src/main/scala/__PACKAGE__/agents/EchoAgent.scala.tmpl +23 -0
- package/dist/templates/scala/src/main/scala/__PACKAGE__/flows/EchoFlow.scala.tmpl +16 -0
- package/dist/templates/scala/src/main/scala/__PACKAGE__/guardrails/ResponseNotEmpty.scala.tmpl +21 -0
- package/dist/templates/scala/src/main/scala/__PACKAGE__/tools/Echo.scala.tmpl +16 -0
- package/dist/templates/scala/src/main/scala/__PACKAGE__/tools/Greet.scala.tmpl +17 -0
- package/dist/templates/scala/src/test/scala/__PACKAGE__/ToolsSuite.scala.tmpl +23 -0
- package/package.json +13 -12
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
/**
|
|
4
|
+
* The Google credentials `kindgi dev` gives the runtime, for Vertex AI
|
|
5
|
+
* (the `gemini` provider preset): only those `KINDGI_DEV_GOOGLE_CREDENTIALS`
|
|
6
|
+
* names, read like the other dev settings (the shell, then the pack's env
|
|
7
|
+
* files), and mounted read-only.
|
|
8
|
+
*
|
|
9
|
+
* - `adc`: gcloud's application-default login
|
|
10
|
+
* (`gcloud auth application-default login`);
|
|
11
|
+
* - an absolute path: that credentials file (a service-account key, an
|
|
12
|
+
* impersonated-credentials file);
|
|
13
|
+
* - `off`, or unset: none. Nothing is mounted and nothing is set in the
|
|
14
|
+
* runtime's environment.
|
|
15
|
+
*
|
|
16
|
+
* Neither this machine's application-default login nor a shell's
|
|
17
|
+
* `GOOGLE_APPLICATION_CREDENTIALS` reaches the runtime on its own: either
|
|
18
|
+
* may be an account set up for other work. When a Vertex provider has no
|
|
19
|
+
* credentials, `kindgi dev` and `kindgi doctor` say how to give it some.
|
|
20
|
+
*
|
|
21
|
+
* Who the credentials are is read from the file, offline; no token is read
|
|
22
|
+
* or printed.
|
|
23
|
+
*/
|
|
24
|
+
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
25
|
+
import { isAbsolute, join } from 'node:path';
|
|
26
|
+
export const DEV_GOOGLE_CREDENTIALS_VAR = 'KINDGI_DEV_GOOGLE_CREDENTIALS';
|
|
27
|
+
/** The Vertex AI provider preset's id, and its adapter. */
|
|
28
|
+
export const VERTEX_PROVIDER_ID = 'gemini';
|
|
29
|
+
const GEMINI_ADAPTER_ID = '@kindgi/adapter-model-gemini';
|
|
30
|
+
/**
|
|
31
|
+
* The credentials `value` (`KINDGI_DEV_GOOGLE_CREDENTIALS`) names, or none.
|
|
32
|
+
* An error says what to fix: a value that's none of the three forms, a
|
|
33
|
+
* login that isn't there, a file that isn't a Google credentials file.
|
|
34
|
+
*/
|
|
35
|
+
export function resolveDevGoogleCredentials(value, hostEnv) {
|
|
36
|
+
const raw = value?.trim() ?? '';
|
|
37
|
+
if (raw === '' || raw === 'off')
|
|
38
|
+
return { kind: 'ok', credentials: undefined };
|
|
39
|
+
let path;
|
|
40
|
+
if (raw === 'adc') {
|
|
41
|
+
const adc = gcloudApplicationDefaultPath(hostEnv);
|
|
42
|
+
if (adc === undefined || !existsSync(adc)) {
|
|
43
|
+
return {
|
|
44
|
+
kind: 'error',
|
|
45
|
+
message: `${DEV_GOOGLE_CREDENTIALS_VAR}=adc, but there's no gcloud application-default login${adc !== undefined ? ` at ${adc}` : ''}. Run \`gcloud auth application-default login\`, or set ${DEV_GOOGLE_CREDENTIALS_VAR} to a credentials file's absolute path.`,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
path = adc;
|
|
49
|
+
}
|
|
50
|
+
else if (isAbsolute(raw)) {
|
|
51
|
+
if (!existsSync(raw) || !statSync(raw).isFile()) {
|
|
52
|
+
return {
|
|
53
|
+
kind: 'error',
|
|
54
|
+
message: `${DEV_GOOGLE_CREDENTIALS_VAR}="${raw}" isn't a file.`,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
path = raw;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
return {
|
|
61
|
+
kind: 'error',
|
|
62
|
+
message: `${DEV_GOOGLE_CREDENTIALS_VAR} must be \`adc\` (your gcloud application-default login), the absolute path of a Google credentials file, or \`off\`. Got "${raw}".`,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const who = describeGoogleCredentials(path, hostEnv);
|
|
66
|
+
if (who === undefined) {
|
|
67
|
+
return {
|
|
68
|
+
kind: 'error',
|
|
69
|
+
message: `${DEV_GOOGLE_CREDENTIALS_VAR}: ${path} isn't a Google credentials file (JSON with a "type").`,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return { kind: 'ok', credentials: { path, who } };
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Where `gcloud auth application-default login` writes: under
|
|
76
|
+
* `CLOUDSDK_CONFIG` when set, else `%APPDATA%\gcloud` on Windows, else
|
|
77
|
+
* `~/.config/gcloud`.
|
|
78
|
+
*/
|
|
79
|
+
export function gcloudApplicationDefaultPath(hostEnv) {
|
|
80
|
+
const file = 'application_default_credentials.json';
|
|
81
|
+
const config = hostEnv.CLOUDSDK_CONFIG;
|
|
82
|
+
if (config !== undefined && config !== '')
|
|
83
|
+
return join(config, file);
|
|
84
|
+
if (process.platform === 'win32') {
|
|
85
|
+
const appData = hostEnv.APPDATA;
|
|
86
|
+
return appData === undefined || appData === '' ? undefined : join(appData, 'gcloud', file);
|
|
87
|
+
}
|
|
88
|
+
const home = hostEnv.HOME;
|
|
89
|
+
return home === undefined || home === '' ? undefined : join(home, '.config', 'gcloud', file);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Whose credentials the file holds, from its non-secret fields only;
|
|
93
|
+
* `undefined` when it isn't a Google credentials file. A user login is
|
|
94
|
+
* "your gcloud application-default login" only when it's gcloud's own
|
|
95
|
+
* file (`gcloudApplicationDefaultPath`); any other is "a gcloud user login".
|
|
96
|
+
*/
|
|
97
|
+
export function describeGoogleCredentials(path, hostEnv = {}) {
|
|
98
|
+
let parsed;
|
|
99
|
+
try {
|
|
100
|
+
parsed = JSON.parse(readFileSync(path, 'utf8'));
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
if (typeof parsed !== 'object' || parsed === null)
|
|
106
|
+
return undefined;
|
|
107
|
+
const file = parsed;
|
|
108
|
+
const text = (key) => typeof file[key] === 'string' && file[key] !== '' ? file[key] : undefined;
|
|
109
|
+
const type = text('type');
|
|
110
|
+
if (type === undefined)
|
|
111
|
+
return undefined;
|
|
112
|
+
const quota = text('quota_project_id');
|
|
113
|
+
const withQuota = (who) => quota === undefined ? who : `${who}, quota project ${quota}`;
|
|
114
|
+
switch (type) {
|
|
115
|
+
case 'service_account':
|
|
116
|
+
return `service account ${text('client_email') ?? '(no client_email)'}`;
|
|
117
|
+
case 'authorized_user': {
|
|
118
|
+
const account = text('account');
|
|
119
|
+
// gcloud's own file says nothing about whose it is; any other user
|
|
120
|
+
// login is named as one, so a stray file can't pass as yours.
|
|
121
|
+
const named = path === gcloudApplicationDefaultPath(hostEnv)
|
|
122
|
+
? `your gcloud application-default login, ${account ?? 'a user account'}`
|
|
123
|
+
: `a gcloud user login${account === undefined ? '' : `, ${account}`}`;
|
|
124
|
+
return withQuota(named);
|
|
125
|
+
}
|
|
126
|
+
case 'impersonated_service_account': {
|
|
127
|
+
const url = text('service_account_impersonation_url') ?? '';
|
|
128
|
+
const target = /\/serviceAccounts\/([^/:]+)/.exec(url)?.[1];
|
|
129
|
+
return withQuota(`impersonating ${target ?? 'a service account'}`);
|
|
130
|
+
}
|
|
131
|
+
case 'external_account':
|
|
132
|
+
return 'an external account (workload identity federation)';
|
|
133
|
+
default:
|
|
134
|
+
return `a "${type}" credentials file`;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Whether a registration is Vertex AI: the Gemini adapter, not on the
|
|
139
|
+
* Gemini Developer API (`api: developer`, the `gemini-api` preset).
|
|
140
|
+
*/
|
|
141
|
+
export function isVertexRegistration(input) {
|
|
142
|
+
return input.adapter_id === GEMINI_ADAPTER_ID && input.adapter_config?.api !== 'developer';
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The line that says how to give Vertex providers credentials. `ids`
|
|
146
|
+
* names them; `GOOGLE_APPLICATION_CREDENTIALS` in the shell is offered
|
|
147
|
+
* when it names a file (not `/dev/null`, say, which only turns it off).
|
|
148
|
+
*/
|
|
149
|
+
export function vertexCredentialsHint(ids, hostEnv) {
|
|
150
|
+
const named = ids.length === 1 ? `Provider ${ids[0]}` : `Providers ${ids.join(', ')}`;
|
|
151
|
+
const shell = hostEnv.GOOGLE_APPLICATION_CREDENTIALS;
|
|
152
|
+
const fromShell = shell !== undefined && isAbsolute(shell) && existsSync(shell) && statSync(shell).isFile()
|
|
153
|
+
? `, or ${DEV_GOOGLE_CREDENTIALS_VAR}=$GOOGLE_APPLICATION_CREDENTIALS`
|
|
154
|
+
: ' (or a credentials file)';
|
|
155
|
+
return `${named} (Vertex AI) ${ids.length === 1 ? 'has' : 'have'} no Google credentials: set ${DEV_GOOGLE_CREDENTIALS_VAR}=adc${fromShell}, in the pack's .env or the shell, and restart kindgi dev.`;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=google-credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-credentials.js","sourceRoot":"","sources":["../../src/dev/google-credentials.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `PackBuilder` of a Java pack. Maven compiles the pack
|
|
3
|
+
* (`target/classes`) and, the first time and whenever `pom.xml` changes,
|
|
4
|
+
* resolves its classpath. The build writes the classpath as an `@argfile`
|
|
5
|
+
* (`java.args`), which the indexer and the pack service pass to `java`, so
|
|
6
|
+
* their commands stay the same while the classpath changes; and it
|
|
7
|
+
* extracts the launcher (`kindgi-pack-java`) from the pack's own
|
|
8
|
+
* kindgi-pack jar, so the launcher always matches the service it starts.
|
|
9
|
+
*
|
|
10
|
+
* javac's errors come back located `file:line:col`, as the bundler's do for
|
|
11
|
+
* a Node pack. A build with errors leaves the previous pack service and
|
|
12
|
+
* index in place.
|
|
13
|
+
*
|
|
14
|
+
* The watch covers the pack's sources and resources (`src/main/**`) and
|
|
15
|
+
* `pom.xml`, with a scan behind it (`scan-backstop.ts`): `fs.watch` can
|
|
16
|
+
* drop events.
|
|
17
|
+
*/
|
|
18
|
+
import { watch } from 'node:fs';
|
|
19
|
+
import { type JavaPackCode } from './pack-code.js';
|
|
20
|
+
import type { PackBuilder } from './runners.js';
|
|
21
|
+
import { type WatchEvents } from './shared-watch.js';
|
|
22
|
+
/**
|
|
23
|
+
* The dependency plugin, named in full: Maven then needs no plugin-prefix
|
|
24
|
+
* lookup (remote metadata), and every pack resolves its classpath with the
|
|
25
|
+
* same version.
|
|
26
|
+
*/
|
|
27
|
+
export declare const MAVEN_DEPENDENCY_PLUGIN = "org.apache.maven.plugins:maven-dependency-plugin:3.11.0";
|
|
28
|
+
export interface JavaPackBuilderOptions {
|
|
29
|
+
readonly packDir: string;
|
|
30
|
+
readonly code: JavaPackCode;
|
|
31
|
+
/** The pack's environment (Maven and `java` run with it, plus `JAVA_HOME`). */
|
|
32
|
+
readonly env: () => Promise<Readonly<Record<string, string>>>;
|
|
33
|
+
readonly debounceMs?: number;
|
|
34
|
+
/** How often the sources are also scanned (`fs.watch` can miss events). */
|
|
35
|
+
readonly scanIntervalMs?: number;
|
|
36
|
+
/** Test seam: `node:fs.watch` (a watch of its own, when not `share`). */
|
|
37
|
+
readonly watchFs?: typeof watch;
|
|
38
|
+
/** Share the pack directory's watch with its other watchers (default: on macOS). */
|
|
39
|
+
readonly share?: boolean;
|
|
40
|
+
/** Test seam: `node:fs/promises`'s `watch`, which a shared watch uses. */
|
|
41
|
+
readonly watchEvents?: WatchEvents;
|
|
42
|
+
/** Test seam: what the sources are now (`javaSourcesSignature`). */
|
|
43
|
+
readonly scanSources?: () => Promise<string>;
|
|
44
|
+
}
|
|
45
|
+
/** Whether a change to `relPath` (relative to the pack root) is a change to the pack's code. */
|
|
46
|
+
export declare function isJavaSourceChange(relPath: string): boolean;
|
|
47
|
+
/** The sources a build reads, with their mtimes and sizes (`scan-backstop.ts`). */
|
|
48
|
+
export declare function javaSourcesSignature(packDir: string): Promise<string>;
|
|
49
|
+
/**
|
|
50
|
+
* javac's errors in Maven's output, `file:line:col: message` with the file
|
|
51
|
+
* relative to the pack root; the last lines of the output when Maven failed
|
|
52
|
+
* some other way.
|
|
53
|
+
*/
|
|
54
|
+
export declare function mavenErrors(output: string, packDirs: string | readonly string[], exitCode: number | null): string[];
|
|
55
|
+
export declare function createJavaPackBuilder(options: JavaPackBuilderOptions): PackBuilder;
|
|
56
|
+
//# sourceMappingURL=java-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"java-builder.d.ts","sourceRoot":"","sources":["../../src/dev/java-builder.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAkB,KAAK,EAAE,MAAM,SAAS,CAAC;AAMhD,OAAO,EAAE,KAAK,YAAY,EAAW,MAAM,gBAAgB,CAAC;AAC5D,OAAO,KAAK,EAAa,WAAW,EAAE,MAAM,cAAc,CAAC;AAO3D,OAAO,EAA0B,KAAK,WAAW,EAAoB,MAAM,mBAAmB,CAAC;AAI/F;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,4DAA4D,CAAC;AAGjG,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,+EAA+E;IAC/E,QAAQ,CAAC,GAAG,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAC9D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,yEAAyE;IACzE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IAChC,oFAAoF;IACpF,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IACnC,oEAAoE;IACpE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9C;AAED,gGAAgG;AAChG,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQ3D;AAED,mFAAmF;AACnF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMrE;AAKD;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,EACpC,QAAQ,EAAE,MAAM,GAAG,IAAI,GACtB,MAAM,EAAE,CAwBV;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,WAAW,CA4GlF"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
/**
|
|
4
|
+
* The `PackBuilder` of a Java pack. Maven compiles the pack
|
|
5
|
+
* (`target/classes`) and, the first time and whenever `pom.xml` changes,
|
|
6
|
+
* resolves its classpath. The build writes the classpath as an `@argfile`
|
|
7
|
+
* (`java.args`), which the indexer and the pack service pass to `java`, so
|
|
8
|
+
* their commands stay the same while the classpath changes; and it
|
|
9
|
+
* extracts the launcher (`kindgi-pack-java`) from the pack's own
|
|
10
|
+
* kindgi-pack jar, so the launcher always matches the service it starts.
|
|
11
|
+
*
|
|
12
|
+
* javac's errors come back located `file:line:col`, as the bundler's do for
|
|
13
|
+
* a Node pack. A build with errors leaves the previous pack service and
|
|
14
|
+
* index in place.
|
|
15
|
+
*
|
|
16
|
+
* The watch covers the pack's sources and resources (`src/main/**`) and
|
|
17
|
+
* `pom.xml`, with a scan behind it (`scan-backstop.ts`): `fs.watch` can
|
|
18
|
+
* drop events.
|
|
19
|
+
*/
|
|
20
|
+
import { watch } from 'node:fs';
|
|
21
|
+
import { mkdir, readFile, realpath, stat } from 'node:fs/promises';
|
|
22
|
+
import { watch as watchEventsReal } from 'node:fs/promises';
|
|
23
|
+
import { delimiter, isAbsolute, join, relative } from 'node:path';
|
|
24
|
+
import { runProcess, writeJvmRunFiles } from './jvm-run-files.js';
|
|
25
|
+
import { javaEnv } from './pack-code.js';
|
|
26
|
+
import { DEFAULT_SCAN_INTERVAL_MS, scanSignature, startScanBackstop, } from './scan-backstop.js';
|
|
27
|
+
import { SHARE_WATCH_BY_DEFAULT, directoryWatches } from './shared-watch.js';
|
|
28
|
+
const SKIPPED_DIRS = ['target', 'node_modules', 'build', 'out'];
|
|
29
|
+
/**
|
|
30
|
+
* The dependency plugin, named in full: Maven then needs no plugin-prefix
|
|
31
|
+
* lookup (remote metadata), and every pack resolves its classpath with the
|
|
32
|
+
* same version.
|
|
33
|
+
*/
|
|
34
|
+
export const MAVEN_DEPENDENCY_PLUGIN = 'org.apache.maven.plugins:maven-dependency-plugin:3.11.0';
|
|
35
|
+
const DEFAULT_DEBOUNCE_MS = 150;
|
|
36
|
+
/** Whether a change to `relPath` (relative to the pack root) is a change to the pack's code. */
|
|
37
|
+
export function isJavaSourceChange(relPath) {
|
|
38
|
+
const segments = relPath.split(/[\\/]/);
|
|
39
|
+
if (segments.slice(0, -1).some((s) => s.startsWith('.') || SKIPPED_DIRS.includes(s))) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const name = segments[segments.length - 1] ?? '';
|
|
43
|
+
if (name.startsWith('.'))
|
|
44
|
+
return false;
|
|
45
|
+
return relPath === 'pom.xml' || (segments[0] === 'src' && segments[1] === 'main');
|
|
46
|
+
}
|
|
47
|
+
/** The sources a build reads, with their mtimes and sizes (`scan-backstop.ts`). */
|
|
48
|
+
export function javaSourcesSignature(packDir) {
|
|
49
|
+
return scanSignature({
|
|
50
|
+
folders: [{ abs: packDir, rel: '' }],
|
|
51
|
+
includes: isJavaSourceChange,
|
|
52
|
+
skipDir: (name) => name.startsWith('.') || SKIPPED_DIRS.includes(name),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/** One located compiler error, from Maven's `[ERROR] /abs/File.java:[line,col] message`. */
|
|
56
|
+
const COMPILER_ERROR = /^\[ERROR\] (.+\.java):\[(\d+),(\d+)\] (.*)$/;
|
|
57
|
+
/**
|
|
58
|
+
* javac's errors in Maven's output, `file:line:col: message` with the file
|
|
59
|
+
* relative to the pack root; the last lines of the output when Maven failed
|
|
60
|
+
* some other way.
|
|
61
|
+
*/
|
|
62
|
+
export function mavenErrors(output, packDirs, exitCode) {
|
|
63
|
+
// The pack root as given, and as Maven may report it (symlinks resolved: /var → /private/var).
|
|
64
|
+
const roots = typeof packDirs === 'string' ? [packDirs] : packDirs;
|
|
65
|
+
const located = [];
|
|
66
|
+
for (const line of output.split('\n')) {
|
|
67
|
+
const m = COMPILER_ERROR.exec(line.trimEnd());
|
|
68
|
+
if (m === null)
|
|
69
|
+
continue;
|
|
70
|
+
const [, file = '', row = '0', col = '0', message = ''] = m;
|
|
71
|
+
let rel = file;
|
|
72
|
+
if (isAbsolute(file)) {
|
|
73
|
+
const inside = roots
|
|
74
|
+
.map((root) => relative(root, file))
|
|
75
|
+
.find((r) => !r.startsWith('..') && !isAbsolute(r));
|
|
76
|
+
rel = (inside ?? file).split(/[\\/]/).join('/');
|
|
77
|
+
}
|
|
78
|
+
located.push(`${rel}:${row}:${col}: ${message}`);
|
|
79
|
+
}
|
|
80
|
+
if (located.length > 0)
|
|
81
|
+
return [...new Set(located)];
|
|
82
|
+
const tail = output
|
|
83
|
+
.split('\n')
|
|
84
|
+
.map((l) => l.trimEnd())
|
|
85
|
+
.filter((l) => l !== '' && !l.startsWith('[INFO]'))
|
|
86
|
+
.slice(-8);
|
|
87
|
+
return [`the pack's Maven build failed (exit ${exitCode}):`, ...tail.map((l) => ` ${l}`)];
|
|
88
|
+
}
|
|
89
|
+
export function createJavaPackBuilder(options) {
|
|
90
|
+
const { packDir, code } = options;
|
|
91
|
+
const watchFs = options.watchFs ?? watch;
|
|
92
|
+
const scan = options.scanSources ?? (() => javaSourcesSignature(packDir));
|
|
93
|
+
const classpathFile = join(code.workDir, 'classpath.txt');
|
|
94
|
+
let resolvedFor;
|
|
95
|
+
let watcher;
|
|
96
|
+
let unsubscribe;
|
|
97
|
+
let backstop;
|
|
98
|
+
let timer;
|
|
99
|
+
async function build() {
|
|
100
|
+
const env = javaEnv(code, await options.env());
|
|
101
|
+
await mkdir(code.workDir, { recursive: true });
|
|
102
|
+
// The classpath is resolved (online) the first time and when pom.xml
|
|
103
|
+
// changes; otherwise the compile runs offline, so a save never waits on
|
|
104
|
+
// the network.
|
|
105
|
+
const pom = await signatureOf(join(packDir, 'pom.xml'));
|
|
106
|
+
const resolve = resolvedFor === undefined || resolvedFor !== pom;
|
|
107
|
+
const [program, ...prefix] = code.maven;
|
|
108
|
+
const goals = resolve
|
|
109
|
+
? [
|
|
110
|
+
'compile',
|
|
111
|
+
`${MAVEN_DEPENDENCY_PLUGIN}:build-classpath`,
|
|
112
|
+
`-Dmdep.outputFile=${classpathFile}`,
|
|
113
|
+
]
|
|
114
|
+
: ['-o', 'compile'];
|
|
115
|
+
const maven = await runProcess(program, [...prefix, '-B', '-q', ...goals], { ...env, ...code.mavenEnv }, packDir);
|
|
116
|
+
if (maven.code !== 0) {
|
|
117
|
+
const roots = [packDir, await realpath(packDir).catch(() => packDir)];
|
|
118
|
+
return {
|
|
119
|
+
kind: 'err',
|
|
120
|
+
errors: mavenErrors(`${maven.stdout}\n${maven.stderr}`, roots, maven.code),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
if (resolve)
|
|
124
|
+
resolvedFor = pom;
|
|
125
|
+
let dependencies;
|
|
126
|
+
try {
|
|
127
|
+
dependencies = (await readFile(classpathFile, 'utf8'))
|
|
128
|
+
.trim()
|
|
129
|
+
.split(delimiter)
|
|
130
|
+
.filter((p) => p !== '');
|
|
131
|
+
}
|
|
132
|
+
catch (cause) {
|
|
133
|
+
return {
|
|
134
|
+
kind: 'err',
|
|
135
|
+
errors: [`Maven wrote no classpath (${classpathFile}): ${cause.message}`],
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
const errors = await writeJvmRunFiles({
|
|
139
|
+
code,
|
|
140
|
+
packDir,
|
|
141
|
+
env,
|
|
142
|
+
classpath: [join(packDir, 'target', 'classes'), ...dependencies],
|
|
143
|
+
missingKindgiPack: "com.kindgi.pack isn't on the pack's classpath: add the com.kindgi:kindgi-pack dependency to pom.xml.",
|
|
144
|
+
});
|
|
145
|
+
if (errors.length > 0)
|
|
146
|
+
return { kind: 'err', errors };
|
|
147
|
+
return { kind: 'ok', bundleMap: {} };
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
build,
|
|
151
|
+
async watch(onBuild) {
|
|
152
|
+
if (watcher !== undefined || unsubscribe !== undefined)
|
|
153
|
+
return;
|
|
154
|
+
const schedule = () => {
|
|
155
|
+
if (timer !== undefined)
|
|
156
|
+
clearTimeout(timer);
|
|
157
|
+
timer = setTimeout(() => {
|
|
158
|
+
timer = undefined;
|
|
159
|
+
void (backstop?.mark() ?? Promise.resolve()).then(build).then(onBuild);
|
|
160
|
+
}, options.debounceMs ?? DEFAULT_DEBOUNCE_MS);
|
|
161
|
+
};
|
|
162
|
+
if (options.share ?? SHARE_WATCH_BY_DEFAULT) {
|
|
163
|
+
unsubscribe = directoryWatches(options.watchEvents ?? watchEventsReal).subscribe(packDir, (rel) => {
|
|
164
|
+
if (rel !== undefined && isJavaSourceChange(rel))
|
|
165
|
+
schedule();
|
|
166
|
+
}, schedule);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
watcher = watchFs(packDir, { recursive: true }, (_event, filename) => {
|
|
170
|
+
if (filename === null || !isJavaSourceChange(filename.toString()))
|
|
171
|
+
return;
|
|
172
|
+
schedule();
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
backstop = await startScanBackstop({
|
|
176
|
+
scan,
|
|
177
|
+
intervalMs: options.scanIntervalMs ?? DEFAULT_SCAN_INTERVAL_MS,
|
|
178
|
+
onChange: schedule,
|
|
179
|
+
});
|
|
180
|
+
},
|
|
181
|
+
// New or removed files need no entry list: Maven compiles what is there.
|
|
182
|
+
syncEntries: () => Promise.resolve(false),
|
|
183
|
+
async dispose() {
|
|
184
|
+
if (timer !== undefined)
|
|
185
|
+
clearTimeout(timer);
|
|
186
|
+
backstop?.stop();
|
|
187
|
+
backstop = undefined;
|
|
188
|
+
unsubscribe?.();
|
|
189
|
+
unsubscribe = undefined;
|
|
190
|
+
watcher?.close();
|
|
191
|
+
watcher = undefined;
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
async function signatureOf(file) {
|
|
196
|
+
try {
|
|
197
|
+
const s = await stat(file);
|
|
198
|
+
return `${s.mtimeMs}:${s.size}`;
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
return 'missing';
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=java-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"java-builder.js","sourceRoot":"","sources":["../../src/dev/java-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type JvmPackCode } from './pack-code.js';
|
|
2
|
+
/** A classpath as a `java` `@argfile` line: quoted, with `\` and `"` escaped. */
|
|
3
|
+
export declare function argsFileText(classpath: readonly string[]): string;
|
|
4
|
+
/**
|
|
5
|
+
* Writes the `@argfile` for `classpath` and, when the classpath changed or
|
|
6
|
+
* the launcher is missing, extracts the launcher with it.
|
|
7
|
+
*
|
|
8
|
+
* @param missingKindgiPack what to say when kindgi-pack isn't on the
|
|
9
|
+
* classpath (where the pack's build declares its dependency)
|
|
10
|
+
* @returns the build errors to show; empty when both are written
|
|
11
|
+
*/
|
|
12
|
+
export declare function writeJvmRunFiles(opts: {
|
|
13
|
+
readonly code: JvmPackCode;
|
|
14
|
+
readonly packDir: string;
|
|
15
|
+
readonly env: Readonly<Record<string, string>>;
|
|
16
|
+
readonly classpath: readonly string[];
|
|
17
|
+
readonly missingKindgiPack: string;
|
|
18
|
+
}): Promise<string[]>;
|
|
19
|
+
export declare function writeAtomically(file: string, text: string): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* A child process, to its end: its exit code and output. With `timeoutMs`,
|
|
22
|
+
* a child still running then is killed (`SIGTERM`) and its code is null.
|
|
23
|
+
*/
|
|
24
|
+
export declare function runProcess(program: string, args: readonly string[], env: Readonly<Record<string, string>>, cwd: string, timeoutMs?: number): Promise<{
|
|
25
|
+
code: number | null;
|
|
26
|
+
stdout: string;
|
|
27
|
+
stderr: string;
|
|
28
|
+
}>;
|
|
29
|
+
//# sourceMappingURL=jvm-run-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jvm-run-files.d.ts","sourceRoot":"","sources":["../../src/dev/jvm-run-files.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,WAAW,EAA8B,MAAM,gBAAgB,CAAC;AAE9E,iFAAiF;AACjF,wBAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAGjE;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/C,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;CACpC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAwBpB;AAWD,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/E;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACrC,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA2BlE"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
/**
|
|
4
|
+
* What a JVM pack's build leaves for the indexer and the pack service,
|
|
5
|
+
* whichever tool built it (Maven, sbt): the classpath as an `@argfile`
|
|
6
|
+
* (`java.args`), which they pass to `java`, so their commands stay the same
|
|
7
|
+
* while the classpath changes; and the launcher (`kindgi-pack-java`),
|
|
8
|
+
* extracted from the pack's own kindgi-pack jar, so it always matches the
|
|
9
|
+
* service it starts.
|
|
10
|
+
*/
|
|
11
|
+
import { spawn } from 'node:child_process';
|
|
12
|
+
import { readFile, rename, stat, writeFile } from 'node:fs/promises';
|
|
13
|
+
import { delimiter } from 'node:path';
|
|
14
|
+
import { javaArgsFile, javaLauncher } from './pack-code.js';
|
|
15
|
+
/** A classpath as a `java` `@argfile` line: quoted, with `\` and `"` escaped. */
|
|
16
|
+
export function argsFileText(classpath) {
|
|
17
|
+
const quoted = classpath.join(delimiter).replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
18
|
+
return `-cp "${quoted}"\n`;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Writes the `@argfile` for `classpath` and, when the classpath changed or
|
|
22
|
+
* the launcher is missing, extracts the launcher with it.
|
|
23
|
+
*
|
|
24
|
+
* @param missingKindgiPack what to say when kindgi-pack isn't on the
|
|
25
|
+
* classpath (where the pack's build declares its dependency)
|
|
26
|
+
* @returns the build errors to show; empty when both are written
|
|
27
|
+
*/
|
|
28
|
+
export async function writeJvmRunFiles(opts) {
|
|
29
|
+
const argsText = argsFileText(opts.classpath);
|
|
30
|
+
const argsPath = javaArgsFile(opts.code);
|
|
31
|
+
const changed = (await readFile(argsPath, 'utf8').catch(() => '')) !== argsText;
|
|
32
|
+
if (changed)
|
|
33
|
+
await writeAtomically(argsPath, argsText);
|
|
34
|
+
const launcherPath = javaLauncher(opts.code);
|
|
35
|
+
if (changed || !(await exists(launcherPath))) {
|
|
36
|
+
const launcher = await runProcess(opts.code.java, [`@${argsPath}`, 'com.kindgi.pack.Main', 'launcher'], opts.env, opts.packDir);
|
|
37
|
+
if (launcher.code !== 0 || !launcher.stdout.startsWith('#!')) {
|
|
38
|
+
const missing = /ClassNotFoundException|Could not find or load main class/.test(launcher.stderr);
|
|
39
|
+
return missing
|
|
40
|
+
? [opts.missingKindgiPack]
|
|
41
|
+
: [`kindgi-pack's launcher could not be written: ${launcher.stderr.trim()}`];
|
|
42
|
+
}
|
|
43
|
+
await writeAtomically(launcherPath, launcher.stdout);
|
|
44
|
+
}
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
async function exists(file) {
|
|
48
|
+
try {
|
|
49
|
+
await stat(file);
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export async function writeAtomically(file, text) {
|
|
57
|
+
const tmp = `${file}.tmp-${process.pid}`;
|
|
58
|
+
await writeFile(tmp, text, 'utf8');
|
|
59
|
+
await rename(tmp, file);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A child process, to its end: its exit code and output. With `timeoutMs`,
|
|
63
|
+
* a child still running then is killed (`SIGTERM`) and its code is null.
|
|
64
|
+
*/
|
|
65
|
+
export function runProcess(program, args, env, cwd, timeoutMs) {
|
|
66
|
+
return new Promise((resolvePromise) => {
|
|
67
|
+
const child = spawn(program, [...args], { env, cwd, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
68
|
+
const timer = timeoutMs === undefined
|
|
69
|
+
? undefined
|
|
70
|
+
: setTimeout(() => {
|
|
71
|
+
stderr += `\n(stopped after ${timeoutMs} ms)`;
|
|
72
|
+
child.kill('SIGTERM');
|
|
73
|
+
}, timeoutMs);
|
|
74
|
+
let stdout = '';
|
|
75
|
+
let stderr = '';
|
|
76
|
+
child.stdout.on('data', (chunk) => {
|
|
77
|
+
stdout += chunk.toString('utf8');
|
|
78
|
+
});
|
|
79
|
+
child.stderr.on('data', (chunk) => {
|
|
80
|
+
stderr += chunk.toString('utf8');
|
|
81
|
+
});
|
|
82
|
+
child.once('error', (cause) => {
|
|
83
|
+
if (timer !== undefined)
|
|
84
|
+
clearTimeout(timer);
|
|
85
|
+
resolvePromise({ code: null, stdout, stderr: cause.message });
|
|
86
|
+
});
|
|
87
|
+
child.once('close', (code) => {
|
|
88
|
+
if (timer !== undefined)
|
|
89
|
+
clearTimeout(timer);
|
|
90
|
+
resolvePromise({ code, stdout, stderr });
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=jvm-run-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jvm-run-files.js","sourceRoot":"","sources":["../../src/dev/jvm-run-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A process's output as lines. A chunk can end mid-line (a long JSON
|
|
3
|
+
* record often does), so each line goes to `onLine` once it's complete;
|
|
4
|
+
* `end()` passes on what's left. Empty lines are skipped, and a `\r`
|
|
5
|
+
* before the line break is dropped. Give it text: a stream with
|
|
6
|
+
* `setEncoding('utf8')` never splits a character between chunks.
|
|
7
|
+
*/
|
|
8
|
+
export interface LineReader {
|
|
9
|
+
push(chunk: string): void;
|
|
10
|
+
end(): void;
|
|
11
|
+
}
|
|
12
|
+
export declare function lineReader(onLine: (line: string) => void): LineReader;
|
|
13
|
+
//# sourceMappingURL=lines.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lines.d.ts","sourceRoot":"","sources":["../../src/dev/lines.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,IAAI,IAAI,CAAC;CACb;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,UAAU,CAkBrE"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
export function lineReader(onLine) {
|
|
4
|
+
let rest = '';
|
|
5
|
+
const emit = (line) => {
|
|
6
|
+
const text = line.endsWith('\r') ? line.slice(0, -1) : line;
|
|
7
|
+
if (text !== '')
|
|
8
|
+
onLine(text);
|
|
9
|
+
};
|
|
10
|
+
return {
|
|
11
|
+
push(chunk) {
|
|
12
|
+
const parts = (rest + chunk).split('\n');
|
|
13
|
+
rest = parts.pop() ?? '';
|
|
14
|
+
for (const part of parts)
|
|
15
|
+
emit(part);
|
|
16
|
+
},
|
|
17
|
+
end() {
|
|
18
|
+
const last = rest;
|
|
19
|
+
rest = '';
|
|
20
|
+
emit(last);
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=lines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lines.js","sourceRoot":"","sources":["../../src/dev/lines.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAcjC,MAAM,UAAU,UAAU,CAAC,MAA8B;IACvD,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,MAAM,IAAI,GAAG,CAAC,IAAY,EAAQ,EAAE;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5D,IAAI,IAAI,KAAK,EAAE;YAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC,CAAC;IACF,OAAO;QACL,IAAI,CAAC,KAAK;YACR,MAAM,KAAK,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzC,IAAI,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;YACzB,KAAK,MAAM,IAAI,IAAI,KAAK;gBAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC;QACD,GAAG;YACD,MAAM,IAAI,GAAG,IAAI,CAAC;YAClB,IAAI,GAAG,EAAE,CAAC;YACV,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,CAAC;KACF,CAAC;AACJ,CAAC"}
|