@fourier-labs/harbour 0.1.32 → 0.1.33
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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFile, readdir, writeFile } from "node:fs/promises";
|
|
1
|
+
import { readFile, readdir, rm, writeFile } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { readAppSchema } from "./app-schema.js";
|
|
4
4
|
import { describeRetainedChecks, syncRetainedChecks } from "./retained-checks.js";
|
|
@@ -128,8 +128,16 @@ export async function runKitGate(root, options) {
|
|
|
128
128
|
const done = await request("/_gate/report");
|
|
129
129
|
if (done?.status === 200) {
|
|
130
130
|
const result = await done.json();
|
|
131
|
-
if (result.report)
|
|
131
|
+
if (result.report) {
|
|
132
|
+
// The app is mounted read-only and the gate works on a mirror, so
|
|
133
|
+
// what it authored for the app to ship comes home here — today the
|
|
134
|
+
// governed-AI inventory (`.harbour/ai-inventory.json`), which the
|
|
135
|
+
// pipeline verifies against the source and which only the gate may
|
|
136
|
+
// write. Written before the caller pins the tree digest, like the
|
|
137
|
+
// regenerated retained checks.
|
|
138
|
+
await writeGateFiles(root, result.files ?? {}, output);
|
|
132
139
|
return result.report;
|
|
140
|
+
}
|
|
133
141
|
throw new CliError("LOCAL_RUNTIME_FAILED", `The kit gate could not run: ${result.error ?? "no report"}.`);
|
|
134
142
|
}
|
|
135
143
|
if (!(await runtime.gateRunning(container)))
|
|
@@ -288,3 +296,19 @@ export async function readReport(root) {
|
|
|
288
296
|
function lastLines(text, count = 5) { return text.trim().split("\n").slice(-count).join(" | ").slice(0, 600); }
|
|
289
297
|
/** A multi-line detail (one gate violation per line) keeps its lines, each under the check name. */
|
|
290
298
|
function indentLines(detail) { return detail.split("\n").map((line, index) => index ? ` ${line}` : line).join("\n"); }
|
|
299
|
+
/** Files the gate authored for the app (path → content, or null to remove), confined to `.harbour/`. */
|
|
300
|
+
export async function writeGateFiles(root, files, output) {
|
|
301
|
+
for (const [path, content] of Object.entries(files)) {
|
|
302
|
+
if (!/^\.harbour\/[A-Za-z0-9._-]+$/.test(path))
|
|
303
|
+
throw new CliError("LOCAL_RUNTIME_FAILED", `The kit gate named a file outside .harbour/: ${path}.`);
|
|
304
|
+
const target = join(root, path);
|
|
305
|
+
if (content === null) {
|
|
306
|
+
await rm(target, { force: true });
|
|
307
|
+
output(`Removed ${path}: the app no longer needs it.`);
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
await writeFile(target, content);
|
|
311
|
+
output(`Wrote ${path}.`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const PUBLISHED_KIT_BUNDLE = {
|
|
2
2
|
"schema": "harbour.kit-bundle/1.0",
|
|
3
|
-
"kitVersion": "0.1.
|
|
3
|
+
"kitVersion": "0.1.33",
|
|
4
4
|
"sdk": {
|
|
5
5
|
"package": "@harbour/app-sdk",
|
|
6
6
|
"version": "1.1.0",
|
|
@@ -8,8 +8,8 @@ export const PUBLISHED_KIT_BUNDLE = {
|
|
|
8
8
|
"url": "https://public.ecr.aws/v2/y6t4p3i8/harbour-kit-bundle/blobs/sha256:3f7ee9d3f7161e8fdb1f7eb89e045c6288a919a72902dbc5bf68ec73e6e578ce"
|
|
9
9
|
},
|
|
10
10
|
"images": {
|
|
11
|
-
"appGateway": "public.ecr.aws/y6t4p3i8/harbour-app-gateway@sha256:
|
|
12
|
-
"sessionFixture": "public.ecr.aws/y6t4p3i8/harbour-session-fixture@sha256:
|
|
11
|
+
"appGateway": "public.ecr.aws/y6t4p3i8/harbour-app-gateway@sha256:7f96a6d1c4f78164d4c4b22fe49e784e87674600bbdae31d8098b2ea6833de11",
|
|
12
|
+
"sessionFixture": "public.ecr.aws/y6t4p3i8/harbour-session-fixture@sha256:573fb296161d57303bddf5e8134de0384ab4e9ae768d81ff09e84d6ef31c58a6"
|
|
13
13
|
},
|
|
14
14
|
"brief": {
|
|
15
15
|
"fingerprint": "4b3c61acdce47995c15e5ce8c38d5e636a624cd79ef7bebb9401b6228d129d11"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const CLI_VERSION = "0.1.
|
|
1
|
+
export const CLI_VERSION = "0.1.33";
|
package/dist/src/analyzer.js
CHANGED
|
@@ -12,8 +12,8 @@ const MAX_FILE_BYTES = 256_000;
|
|
|
12
12
|
// application files. Keeping them out also makes reruns idempotent after a
|
|
13
13
|
// previous save has written a receipt into the selected workspace.
|
|
14
14
|
const IGNORED_DIRS = new Set([".git", ".harbour", ".next", ".nuxt", ".svelte-kit", ".turbo", "coverage", "dist", "build", "node_modules", "vendor"]);
|
|
15
|
-
/** The development kit commits its declaration, lock and journey checks under `.harbour` (see `isKitCommittedPath`); everything else there (local state, checks evidence, generated control files) stays out of the package. */
|
|
16
|
-
const KIT_CONTROL_FILES = [".harbour/integrations.json", ".harbour/kit.lock.json"];
|
|
15
|
+
/** The development kit commits its declaration, lock, governed-AI inventory and journey checks under `.harbour` (see `isKitCommittedPath`); everything else there (local state, checks evidence, generated control files) stays out of the package. The inventory is what the pipeline plans a kit app's AI over (data plane 0.78.2.0): the gate writes it under `harbour check`, the lane refuses an app whose source calls governed AI without it. */
|
|
16
|
+
const KIT_CONTROL_FILES = [".harbour/integrations.json", ".harbour/kit.lock.json", ".harbour/ai-inventory.json"];
|
|
17
17
|
const KIT_CHECKS_DIR = ".harbour/checks";
|
|
18
18
|
const SECRET_FILE_NAMES = new Set([".env", ".env.local", ".env.production", ".env.development", ".npmrc"]);
|
|
19
19
|
const TEXT_EXTENSIONS = new Set([".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs", ".json", ".html", ".css", ".py", ".rb", ".go", ".rs", ".java", ".cs", ".php", ".md", ".toml", ".yaml", ".yml", ".sh"]);
|
package/dist/src/secret-paths.js
CHANGED
|
@@ -25,7 +25,7 @@ export function isSourceIntakeExcludedPath(path) {
|
|
|
25
25
|
* Everything else there (local state, generated control files) stays local.
|
|
26
26
|
*/
|
|
27
27
|
export function isKitCommittedPath(path) {
|
|
28
|
-
return /(^|\/)\.harbour\/(?:integrations\.json|kit\.lock\.json|checks\/[^/]+\.(?:mjs|js|cjs))$/.test(path);
|
|
28
|
+
return /(^|\/)\.harbour\/(?:integrations\.json|kit\.lock\.json|ai-inventory\.json|checks\/[^/]+\.(?:mjs|js|cjs))$/.test(path);
|
|
29
29
|
}
|
|
30
30
|
/** Dependency and internal directories the intake never stages — `.harbour` except its committed kit files. */
|
|
31
31
|
export function isInternalSourcePath(path) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fourier-labs/harbour",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.33",
|
|
4
4
|
"description": "Harbour productionisation helper",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"harbour": {
|
|
35
35
|
"kitBundle": {
|
|
36
36
|
"repository": "public.ecr.aws/y6t4p3i8/harbour-kit-bundle",
|
|
37
|
-
"version": "0.1.
|
|
37
|
+
"version": "0.1.33"
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
}
|