@kici-dev/agent 0.1.9 → 0.1.11
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/dist/execution/dep-installer.d.ts +30 -22
- package/dist/execution/dep-packer.d.ts +20 -13
- package/dist/execution/dep-restore.d.ts +9 -5
- package/dist/execution/validate-kici-deps.d.ts +65 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +522 -2
- package/dist/server.js +511 -138
- package/dist/workflow-runner.js +363 -103
- package/package.json +4 -4
- package/sbom.spdx.json +48 -48
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Inline dependency installation for graceful degradation.
|
|
3
3
|
*
|
|
4
|
-
* When dep cache is unavailable or download fails, the agent
|
|
5
|
-
*
|
|
4
|
+
* When the dep cache is unavailable or a download fails, the agent installs
|
|
5
|
+
* `.kici/` dependencies directly with the repository's package manager.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* The package manager is detected from the cloned repo (npm / pnpm); the
|
|
8
|
+
* presence of `.kici/package.json` signals that deps should be installed. npm
|
|
9
|
+
* is the default and ships with every Node.js install; pnpm is used when the
|
|
10
|
+
* repo is a pnpm workspace so a `.kici/` member can resolve in-repo
|
|
11
|
+
* `workspace:` siblings. yarn is detected but not yet supported and is
|
|
12
|
+
* rejected with an actionable error.
|
|
9
13
|
*
|
|
10
|
-
* Security:
|
|
11
|
-
* cache poisoning across build jobs
|
|
12
|
-
* taint the cache used by subsequent builds.
|
|
13
|
-
*
|
|
14
|
-
* `--ignore-scripts` whenever a private
|
|
14
|
+
* Security: the install runs with an isolated per-invocation cache/store
|
|
15
|
+
* directory to prevent cache poisoning across build jobs — a malicious
|
|
16
|
+
* package.json in one repo cannot taint the cache used by subsequent builds.
|
|
17
|
+
* The same pressure rules out letting lifecycle scripts see synthesized auth
|
|
18
|
+
* env vars — the install runs with `--ignore-scripts` whenever a private
|
|
19
|
+
* registry is configured.
|
|
15
20
|
*/
|
|
16
21
|
import { type NpmRegistrySpec } from './npm-registry-config.js';
|
|
17
22
|
export interface InstallDepsOptions {
|
|
@@ -21,24 +26,27 @@ export interface InstallDepsOptions {
|
|
|
21
26
|
installEnvSecrets?: Record<string, string>;
|
|
22
27
|
/** Short job-scoped nonce — used as suffix on synthesized env-var names. */
|
|
23
28
|
jobIdShort?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Clone root (repo root). Package-manager detection runs against it first,
|
|
31
|
+
* then falls back to `kiciDir`. Defaults to `dirname(kiciDir)`.
|
|
32
|
+
*/
|
|
33
|
+
repoRoot?: string;
|
|
24
34
|
}
|
|
25
35
|
/**
|
|
26
|
-
* Install dependencies inline
|
|
36
|
+
* Install `.kici/` dependencies inline with the repo's package manager.
|
|
27
37
|
*
|
|
28
|
-
* Falls back to this when the dep cache is unavailable or download fails.
|
|
38
|
+
* Falls back to this when the dep cache is unavailable or a download fails.
|
|
39
|
+
* The install runs with an isolated cache/store directory (created in
|
|
40
|
+
* `os.tmpdir()`) to prevent cache poisoning between build jobs; the directory
|
|
41
|
+
* is removed after installation.
|
|
29
42
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
43
|
+
* If `opts.npmRegistries` / `opts.installEnvSecrets` is provided, a job-scoped
|
|
44
|
+
* `.kici/.npmrc` overlay is synthesized for the install, restored in `finally`,
|
|
45
|
+
* and the install runs with `--ignore-scripts` so lifecycle scripts in a
|
|
46
|
+
* committed `package.json` cannot exfiltrate the synthesized token env vars.
|
|
32
47
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* the original file in `finally`, and runs npm with `--ignore-scripts` so
|
|
36
|
-
* lifecycle scripts in committed `package.json` cannot exfiltrate the
|
|
37
|
-
* synthesized token env vars.
|
|
38
|
-
*
|
|
39
|
-
* @param kiciDir - Path to the .kici/ directory containing package.json
|
|
40
|
-
* @param opts - Optional registry / installEnv configuration. When absent,
|
|
41
|
-
* behavior is identical to the pre-private-registry version.
|
|
48
|
+
* @param kiciDir - Path to the `.kici/` directory containing package.json.
|
|
49
|
+
* @param opts - Optional registry / installEnv / repoRoot configuration.
|
|
42
50
|
*/
|
|
43
51
|
export declare function installDeps(kiciDir: string, opts?: InstallDepsOptions): Promise<void>;
|
|
44
52
|
//# sourceMappingURL=dep-installer.d.ts.map
|
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Dependency tarball creation for build agents.
|
|
3
3
|
*
|
|
4
|
-
* After installing dependencies
|
|
5
|
-
* into a gzip tarball for upload to the dep cache.
|
|
4
|
+
* After installing dependencies the build agent packs the dependency closure
|
|
5
|
+
* into a gzip tarball for upload to the dep cache. The closure is packed
|
|
6
|
+
* **repo-root-relative** (cwd = the clone root) so restore is a single layout
|
|
7
|
+
* regardless of package manager:
|
|
6
8
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
+
* - npm / yarn: just `.kici/node_modules`.
|
|
10
|
+
* - pnpm: `.kici/node_modules` plus the repo-root `node_modules/.pnpm` virtual
|
|
11
|
+
* store and the in-repo `workspace:` sibling package directories `.kici`
|
|
12
|
+
* depends on (with their built output). pnpm lays `.kici/node_modules` out as
|
|
13
|
+
* symlinks into the root store and into sibling dirs that live outside
|
|
14
|
+
* `.kici/`, so packing `.kici/node_modules` alone would capture dangling
|
|
15
|
+
* links — the store and siblings must travel together.
|
|
16
|
+
*
|
|
17
|
+
* Uses tar.gz (Node.js built-in zlib, no external binary) in portable mode to
|
|
18
|
+
* strip user/group info for cross-machine consistency; symlinks are preserved
|
|
19
|
+
* as symlinks so the pnpm link graph restores intact.
|
|
9
20
|
*/
|
|
10
21
|
/**
|
|
11
|
-
* Pack
|
|
12
|
-
*
|
|
13
|
-
* Creates a tar.gz archive of the `node_modules/` directory relative to
|
|
14
|
-
* kiciDir. The tarball is created in-memory and returned as a Buffer
|
|
15
|
-
* along with its content hash.
|
|
22
|
+
* Pack the dependency closure into a gzip tarball and compute its SHA-256 hash.
|
|
16
23
|
*
|
|
17
|
-
* @param kiciDir - Path to the
|
|
18
|
-
* @returns Object with tarball Buffer and SHA-256 hash string
|
|
19
|
-
* @throws Error if node_modules
|
|
24
|
+
* @param kiciDir - Path to the `.kici/` directory containing node_modules/.
|
|
25
|
+
* @returns Object with the tarball Buffer and its SHA-256 hash string.
|
|
26
|
+
* @throws Error if `.kici/node_modules` does not exist.
|
|
20
27
|
*/
|
|
21
28
|
export declare function packNodeModules(kiciDir: string): Promise<{
|
|
22
29
|
tarball: Buffer;
|
|
@@ -69,13 +69,17 @@ export declare function excludeScratchFromGit(repoWorkDir: string): Promise<void
|
|
|
69
69
|
*/
|
|
70
70
|
export declare function resolveOrchestratorUrl(url: string): string;
|
|
71
71
|
/**
|
|
72
|
-
* Restore dependencies from a cached tarball.
|
|
72
|
+
* Restore dependencies from a cached tarball into the cloned repo.
|
|
73
73
|
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
74
|
+
* The tarball is packed repo-root-relative (see `dep-packer.ts`): every manager
|
|
75
|
+
* carries `.kici/node_modules`; pnpm additionally carries the root
|
|
76
|
+
* `node_modules/.pnpm` store and the in-repo workspace siblings `.kici` resolves.
|
|
77
|
+
* Restore extracts into a scratch dir, then moves each entry into place — one
|
|
78
|
+
* code path for all managers.
|
|
77
79
|
*
|
|
78
|
-
* For
|
|
80
|
+
* For HTTP/HTTPS URLs: a streaming pipeline (response -> hash -> gunzip -> tar)
|
|
81
|
+
* with a 5-minute timeout and up to 2 retries avoids buffering whole tarballs.
|
|
82
|
+
* For file:// URLs: a buffer-based approach (local, no streaming benefit).
|
|
79
83
|
*
|
|
80
84
|
* @param workDir - Root directory of the cloned repository
|
|
81
85
|
* @param depsUrl - URL to the dependency tarball (http://, https://, or file://)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-install validation for `.kici/` dependency specifiers.
|
|
3
|
+
*
|
|
4
|
+
* The agent clones a single source repository and installs its `.kici/`
|
|
5
|
+
* dependencies with the repo's package manager. Local-protocol specifiers —
|
|
6
|
+
* `workspace:`, `file:`, `link:`, `portal:` — resolve a dependency against
|
|
7
|
+
* another package on the same filesystem rather than a registry. Whether they
|
|
8
|
+
* are resolvable depends on the manager and the layout:
|
|
9
|
+
*
|
|
10
|
+
* - npm has no `workspace:` protocol and cannot resolve any of these from a
|
|
11
|
+
* registry, so they are rejected up front with an actionable message
|
|
12
|
+
* instead of the raw `EUNSUPPORTEDPROTOCOL` npm would emit.
|
|
13
|
+
* - pnpm resolves `workspace:` against the repo's pnpm workspace (the agent
|
|
14
|
+
* clones the whole repo, so an in-repo sibling is present), and resolves
|
|
15
|
+
* `file:`/`link:`/`portal:` against a path — allowed when that path stays
|
|
16
|
+
* inside the cloned repo, rejected when it escapes the clone.
|
|
17
|
+
*
|
|
18
|
+
* This module performs that classification so unresolvable specifiers fail
|
|
19
|
+
* fast with guidance rather than a cryptic install error.
|
|
20
|
+
*/
|
|
21
|
+
import { PackageManager } from '@kici-dev/shared/package-manager';
|
|
22
|
+
/** Local-protocol specifier prefixes that resolve against the filesystem. */
|
|
23
|
+
export declare enum LocalDepProtocol {
|
|
24
|
+
Workspace = "workspace:",
|
|
25
|
+
File = "file:",
|
|
26
|
+
Link = "link:",
|
|
27
|
+
Portal = "portal:"
|
|
28
|
+
}
|
|
29
|
+
/** A dependency whose specifier uses a local (filesystem) protocol. */
|
|
30
|
+
export interface LocalProtocolDep {
|
|
31
|
+
name: string;
|
|
32
|
+
spec: string;
|
|
33
|
+
protocol: LocalDepProtocol;
|
|
34
|
+
}
|
|
35
|
+
interface PackageJsonShape {
|
|
36
|
+
[field: string]: unknown;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Scan a parsed `.kici/package.json` for dependency specifiers that use a
|
|
40
|
+
* local protocol (`workspace:`/`file:`/`link:`/`portal:`). Returns one entry
|
|
41
|
+
* per dependency, in field order. Returns an empty array when there are none.
|
|
42
|
+
*/
|
|
43
|
+
export declare function findLocalProtocolDeps(pkg: PackageJsonShape): LocalProtocolDep[];
|
|
44
|
+
/**
|
|
45
|
+
* Whether `.kici/package.json` declares any local-protocol dependency. Used to
|
|
46
|
+
* decide whether the agent must build the in-repo workspace dependency closure
|
|
47
|
+
* after a pnpm install (so a `workspace:` sibling's build output exists before
|
|
48
|
+
* the workflow that imports it loads).
|
|
49
|
+
*/
|
|
50
|
+
export declare function kiciHasLocalProtocolDeps(kiciDir: string): Promise<boolean>;
|
|
51
|
+
/** Build the actionable error for unresolvable local-protocol dependencies. */
|
|
52
|
+
export declare function formatUnresolvableDepError(offenders: readonly LocalProtocolDep[], packageManager: PackageManager): string;
|
|
53
|
+
/**
|
|
54
|
+
* Throw an actionable error when `.kici/package.json` declares a local-protocol
|
|
55
|
+
* dependency the detected package manager cannot resolve from the single cloned
|
|
56
|
+
* repository. A missing or unparseable package.json is left for the install to
|
|
57
|
+
* report.
|
|
58
|
+
*/
|
|
59
|
+
export declare function assertResolvableDeps(args: {
|
|
60
|
+
kiciDir: string;
|
|
61
|
+
repoRoot: string;
|
|
62
|
+
packageManager: PackageManager;
|
|
63
|
+
}): Promise<void>;
|
|
64
|
+
export {};
|
|
65
|
+
//# sourceMappingURL=validate-kici-deps.d.ts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export { loadConfig, type AppConfig } from './config.js';
|
|
2
|
+
export { installDeps, type InstallDepsOptions } from './execution/dep-installer.js';
|
|
3
|
+
export { findLocalProtocolDeps, assertResolvableDeps, formatUnresolvableDepError, kiciHasLocalProtocolDeps, LocalDepProtocol, type LocalProtocolDep, } from './execution/validate-kici-deps.js';
|
|
2
4
|
//# sourceMappingURL=index.d.ts.map
|