@kontourai/flow-agents 1.0.1 → 1.1.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/.github/workflows/ci.yml +110 -0
- package/CHANGELOG.md +16 -0
- package/build/src/cli/console-learning-projection.js +19 -2
- package/build/src/cli/effective-backlog-settings.js +18 -2
- package/build/src/cli/fixture-retirement-audit.js +19 -2
- package/build/src/cli/init.js +19 -2
- package/build/src/cli/promote-workflow-artifact.js +19 -2
- package/build/src/cli/publish-change-helper.js +19 -2
- package/build/src/cli/pull-work-provider.js +19 -2
- package/build/src/cli/runtime-adapter.js +20 -2
- package/build/src/cli/usage-feedback.js +19 -2
- package/build/src/cli/utterance-check.js +19 -2
- package/build/src/cli/validate-hook-influence.js +19 -2
- package/build/src/cli/veritas-governance.js +19 -2
- package/build/src/cli/workflow-artifact-cleanup-audit.js +19 -2
- package/build/src/runtime-adapters.js +55 -24
- package/build/src/tools/build-universal-bundles.js +19 -2
- package/build/src/tools/generate-context-map.js +19 -2
- package/build/src/tools/validate-package.js +19 -2
- package/build/src/tools/validate-source-tree.js +19 -2
- package/context/scripts/telemetry/console-presets.sh +1 -1
- package/docs/kit-authoring-guide.md +20 -3
- package/evals/ci/run-baseline.sh +55 -8
- package/evals/integration/test_runtime_adapter_activation.sh +138 -17
- package/evals/run.sh +2 -0
- package/evals/static/test_console_presets.sh +49 -0
- package/package.json +1 -1
- package/scripts/telemetry/console-presets.sh +1 -1
- package/src/cli/console-learning-projection.ts +7 -1
- package/src/cli/effective-backlog-settings.ts +6 -1
- package/src/cli/fixture-retirement-audit.ts +7 -1
- package/src/cli/init.ts +7 -1
- package/src/cli/promote-workflow-artifact.ts +7 -1
- package/src/cli/publish-change-helper.ts +7 -1
- package/src/cli/pull-work-provider.ts +7 -1
- package/src/cli/runtime-adapter.ts +8 -1
- package/src/cli/usage-feedback.ts +7 -1
- package/src/cli/utterance-check.ts +7 -1
- package/src/cli/validate-hook-influence.ts +7 -1
- package/src/cli/veritas-governance.ts +7 -1
- package/src/cli/workflow-artifact-cleanup-audit.ts +7 -1
- package/src/runtime-adapters.ts +54 -26
- package/src/tools/build-universal-bundles.ts +7 -1
- package/src/tools/generate-context-map.ts +7 -1
- package/src/tools/validate-package.ts +7 -1
- package/src/tools/validate-source-tree.ts +7 -1
package/src/cli/init.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
3
4
|
import * as os from "node:os";
|
|
4
5
|
import * as path from "node:path";
|
|
5
6
|
import { createInterface } from "node:readline/promises";
|
|
@@ -458,4 +459,9 @@ export async function mainDogfood(argv = process.argv.slice(2)): Promise<number>
|
|
|
458
459
|
}
|
|
459
460
|
}
|
|
460
461
|
|
|
461
|
-
|
|
462
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
463
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
464
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
465
|
+
const _selfRealPath = (() => { try { return fs.realpathSync(fileURLToPath(import.meta.url)); } catch { return fileURLToPath(import.meta.url); } })();
|
|
466
|
+
const _argv1RealPath = (() => { try { return fs.realpathSync(process.argv[1]); } catch { return process.argv[1]; } })();
|
|
467
|
+
if (_selfRealPath === _argv1RealPath) { process.exitCode = await main(); }
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
2
3
|
import * as path from "node:path";
|
|
3
4
|
import { parseArgs, flagString } from "../lib/args.js";
|
|
4
5
|
import { isoNow, relPath } from "../lib/fs.js";
|
|
@@ -61,4 +62,9 @@ export function main(argv = process.argv.slice(2)): number {
|
|
|
61
62
|
return 0;
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
|
|
65
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
66
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
67
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
68
|
+
const _selfRealPath = (() => { try { return fs.realpathSync(fileURLToPath(import.meta.url)); } catch { return fileURLToPath(import.meta.url); } })();
|
|
69
|
+
const _argv1RealPath = (() => { try { return fs.realpathSync(process.argv[1]); } catch { return process.argv[1]; } })();
|
|
70
|
+
if (_selfRealPath === _argv1RealPath) { process.exitCode = main(); }
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
2
3
|
import * as path from "node:path";
|
|
3
4
|
import { parseArgs, flagString } from "../lib/args.js";
|
|
4
5
|
import { readJson } from "../lib/fs.js";
|
|
@@ -140,4 +141,9 @@ export function main(argv = process.argv.slice(2)): number {
|
|
|
140
141
|
}
|
|
141
142
|
}
|
|
142
143
|
|
|
143
|
-
|
|
144
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
145
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
146
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
147
|
+
const _selfRealPath = (() => { try { return fs.realpathSync(fileURLToPath(import.meta.url)); } catch { return fileURLToPath(import.meta.url); } })();
|
|
148
|
+
const _argv1RealPath = (() => { try { return fs.realpathSync(process.argv[1]); } catch { return process.argv[1]; } })();
|
|
149
|
+
if (_selfRealPath === _argv1RealPath) { process.exitCode = main(); }
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
2
3
|
import { parseArgs, flagList, flagString } from "../lib/args.js";
|
|
3
4
|
|
|
4
5
|
const FLOW_ARTIFACT_PATTERN = /(?<path>\.flow-agents\/[^\s`'")]+)/g;
|
|
@@ -478,4 +479,9 @@ export function main(argv = process.argv.slice(2)): number {
|
|
|
478
479
|
return 0;
|
|
479
480
|
}
|
|
480
481
|
|
|
481
|
-
|
|
482
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
483
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
484
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
485
|
+
const _selfRealPath = (() => { try { return fs.realpathSync(fileURLToPath(import.meta.url)); } catch { return fileURLToPath(import.meta.url); } })();
|
|
486
|
+
const _argv1RealPath = (() => { try { return fs.realpathSync(process.argv[1]); } catch { return process.argv[1]; } })();
|
|
487
|
+
if (_selfRealPath === _argv1RealPath) { process.exitCode = main(); }
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
1
3
|
import * as path from "node:path";
|
|
2
4
|
import { parseArgs, flagString } from "../lib/args.js";
|
|
3
5
|
import { activateCodexLocal, activateStrandsLocal } from "../runtime-adapters.js";
|
|
@@ -26,4 +28,9 @@ export function main(argv = process.argv.slice(2)): number {
|
|
|
26
28
|
return Array.isArray(result.errors) && result.errors.length ? 1 : 0;
|
|
27
29
|
}
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
32
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
33
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
34
|
+
const _selfRealPath = (() => { try { return fs.realpathSync(fileURLToPath(import.meta.url)); } catch { return fileURLToPath(import.meta.url); } })();
|
|
35
|
+
const _argv1RealPath = (() => { try { return fs.realpathSync(process.argv[1]); } catch { return process.argv[1]; } })();
|
|
36
|
+
if (_selfRealPath === _argv1RealPath) { process.exitCode = main(); }
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
2
3
|
import * as os from "node:os";
|
|
3
4
|
import * as path from "node:path";
|
|
4
5
|
import { parseArgs, flagBool, flagList, flagString } from "../lib/args.js";
|
|
@@ -415,4 +416,9 @@ export function main(argv = process.argv.slice(2)): number {
|
|
|
415
416
|
}
|
|
416
417
|
}
|
|
417
418
|
|
|
418
|
-
|
|
419
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
420
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
421
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
422
|
+
const _selfRealPath = (() => { try { return fs.realpathSync(fileURLToPath(import.meta.url)); } catch { return fileURLToPath(import.meta.url); } })();
|
|
423
|
+
const _argv1RealPath = (() => { try { return fs.realpathSync(process.argv[1]); } catch { return process.argv[1]; } })();
|
|
424
|
+
if (_selfRealPath === _argv1RealPath) { process.exitCode = main(); }
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
2
3
|
import * as path from "node:path";
|
|
3
4
|
import { flagBool, flagString, parseArgs } from "../lib/args.js";
|
|
4
5
|
|
|
@@ -321,4 +322,9 @@ export async function main(argv = process.argv.slice(2)): Promise<number> {
|
|
|
321
322
|
return runCheck(rest);
|
|
322
323
|
}
|
|
323
324
|
|
|
324
|
-
|
|
325
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
326
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
327
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
328
|
+
const _selfRealPath = (() => { try { return fs.realpathSync(fileURLToPath(import.meta.url)); } catch { return fileURLToPath(import.meta.url); } })();
|
|
329
|
+
const _argv1RealPath = (() => { try { return fs.realpathSync(process.argv[1]); } catch { return process.argv[1]; } })();
|
|
330
|
+
if (_selfRealPath === _argv1RealPath) { process.exitCode = await main(); }
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
2
3
|
|
|
3
4
|
const validTiers = new Set(["adapter", "design-target", "installed-command", "live-acceptance", "documented-runtime-gap"]);
|
|
4
5
|
const validRuntimes = new Set(["codex", "claude-code", "kiro-cli"]);
|
|
@@ -116,4 +117,9 @@ export function main(argv = process.argv.slice(2)): number {
|
|
|
116
117
|
}
|
|
117
118
|
}
|
|
118
119
|
|
|
119
|
-
|
|
120
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
121
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
122
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
123
|
+
const _selfRealPath = (() => { try { return fs.realpathSync(fileURLToPath(import.meta.url)); } catch { return fileURLToPath(import.meta.url); } })();
|
|
124
|
+
const _argv1RealPath = (() => { try { return fs.realpathSync(process.argv[1]); } catch { return process.argv[1]; } })();
|
|
125
|
+
if (_selfRealPath === _argv1RealPath) { process.exitCode = main(); }
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
2
3
|
import * as path from "node:path";
|
|
3
4
|
import { spawnSync } from "node:child_process";
|
|
4
5
|
import { flagBool, flagString, parseArgs } from "../lib/args.js";
|
|
@@ -319,4 +320,9 @@ export function main(argv = process.argv.slice(2)): number {
|
|
|
319
320
|
return options ? runEvidence(options) : 2;
|
|
320
321
|
}
|
|
321
322
|
|
|
322
|
-
|
|
323
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
324
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
325
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
326
|
+
const _selfRealPath = (() => { try { return fs.realpathSync(fileURLToPath(import.meta.url)); } catch { return fileURLToPath(import.meta.url); } })();
|
|
327
|
+
const _argv1RealPath = (() => { try { return fs.realpathSync(process.argv[1]); } catch { return process.argv[1]; } })();
|
|
328
|
+
if (_selfRealPath === _argv1RealPath) { process.exitCode = main(); }
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
2
3
|
import * as path from "node:path";
|
|
3
4
|
import { flagBool, flagString, parseArgs } from "../lib/args.js";
|
|
4
5
|
|
|
@@ -278,4 +279,9 @@ export function main(argv = process.argv.slice(2)): number {
|
|
|
278
279
|
return 0;
|
|
279
280
|
}
|
|
280
281
|
|
|
281
|
-
|
|
282
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
283
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
284
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
285
|
+
const _selfRealPath = (() => { try { return fs.realpathSync(fileURLToPath(import.meta.url)); } catch { return fileURLToPath(import.meta.url); } })();
|
|
286
|
+
const _argv1RealPath = (() => { try { return fs.realpathSync(process.argv[1]); } catch { return process.argv[1]; } })();
|
|
287
|
+
if (_selfRealPath === _argv1RealPath) { process.exitCode = main(); }
|
package/src/runtime-adapters.ts
CHANGED
|
@@ -126,31 +126,47 @@ function safeSegment(value: string): string {
|
|
|
126
126
|
return value.replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^[.-]+|[.-]+$/g, "") || "asset";
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
// Asset classes that are directly activated (copied to the runtime directory) by both adapters.
|
|
130
|
+
// flows: gate definitions read by the adapter's flow-routing layer.
|
|
131
|
+
// skills: agent guidance markdown copied to skills/<kit-id>/ for agent discovery.
|
|
132
|
+
// docs: documentation markdown copied to docs/<kit-id>/ for agent reference.
|
|
133
|
+
const ACTIVATED_ASSET_CLASSES = new Set(["flows", "skills", "docs"]);
|
|
134
|
+
|
|
129
135
|
export function activateCodexLocal(sourceRoot: string, dest: string): Record<string, unknown> {
|
|
130
136
|
const inventory = readKitInventory(sourceRoot, dest);
|
|
131
137
|
const runtimeDir = path.join(dest, ".flow-agents", "runtime", "codex");
|
|
132
138
|
const generated: Record<string, string>[] = [];
|
|
133
139
|
const skipped: Record<string, string | null>[] = [];
|
|
134
140
|
for (const asset of inventory.assets) {
|
|
135
|
-
if (asset.asset_class
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
141
|
+
if (asset.asset_class === "flows") {
|
|
142
|
+
if (!asset.asset_id) {
|
|
143
|
+
skipped.push({ asset_class: asset.asset_class, path: asset.relative_path, kit_id: asset.kit_id, asset_id: null, reason: "flow asset is missing an id" });
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
const output = path.join(runtimeDir, "flows", safeSegment(asset.kit_id), `${safeSegment(asset.asset_id)}.flow.json`);
|
|
147
|
+
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
148
|
+
fs.copyFileSync(asset.source_path, output);
|
|
149
|
+
generated.push({ asset_class: asset.asset_class, path: relPath(dest, output), kit_id: asset.kit_id, asset_id: asset.asset_id, source_path: asset.source_path.split(path.sep).join("/") });
|
|
150
|
+
} else if (asset.asset_class === "skills" || asset.asset_class === "docs") {
|
|
151
|
+
// Copy skills and docs to runtime/<adapter>/<class>/<kit-id>/<filename> so the
|
|
152
|
+
// agent's guidance index (AGENTS.md) can reference them and they are co-located
|
|
153
|
+
// with flow definitions for the same kit.
|
|
154
|
+
const filename = path.basename(asset.source_path);
|
|
155
|
+
const output = path.join(runtimeDir, asset.asset_class, safeSegment(asset.kit_id), filename);
|
|
156
|
+
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
157
|
+
fs.copyFileSync(asset.source_path, output);
|
|
158
|
+
generated.push({ asset_class: asset.asset_class, path: relPath(dest, output), kit_id: asset.kit_id, asset_id: asset.asset_id ?? "", source_path: asset.source_path.split(path.sep).join("/") });
|
|
159
|
+
} else {
|
|
160
|
+
skipped.push({ asset_class: asset.asset_class, path: asset.relative_path, kit_id: asset.kit_id, asset_id: asset.asset_id, reason: "asset class is not activated by codex-local" });
|
|
142
161
|
}
|
|
143
|
-
const output = path.join(runtimeDir, "flows", safeSegment(asset.kit_id), `${safeSegment(asset.asset_id)}.flow.json`);
|
|
144
|
-
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
145
|
-
fs.copyFileSync(asset.source_path, output);
|
|
146
|
-
generated.push({ asset_class: asset.asset_class, path: relPath(dest, output), kit_id: asset.kit_id, asset_id: asset.asset_id, source_path: asset.source_path.split(path.sep).join("/") });
|
|
147
162
|
}
|
|
148
163
|
fs.mkdirSync(runtimeDir, { recursive: true });
|
|
149
|
-
const
|
|
164
|
+
const supportedClasses = Array.from(ACTIVATED_ASSET_CLASSES);
|
|
165
|
+
const manifest = { schema_version: "1.0", adapter: "codex-local", supported_asset_classes: supportedClasses, generated_runtime_files: generated, skipped_assets: skipped, warnings: inventory.warnings, errors: inventory.errors };
|
|
150
166
|
const manifestPath = path.join(runtimeDir, "activation.json");
|
|
151
167
|
writeJson(manifestPath, manifest);
|
|
152
168
|
generated.push({ asset_class: "activation-manifest", path: relPath(dest, manifestPath), kit_id: "runtime", asset_id: "codex-local.activation", source_path: manifestPath.split(path.sep).join("/") });
|
|
153
|
-
return { selected_adapter: "codex-local", supported_asset_classes:
|
|
169
|
+
return { selected_adapter: "codex-local", supported_asset_classes: supportedClasses, generated_runtime_files: generated, skipped_assets: skipped, warnings: inventory.warnings, errors: inventory.errors };
|
|
154
170
|
}
|
|
155
171
|
|
|
156
172
|
// Decision Q3 (Issue #32): Option (a) — new adapter id "strands-local" rather than
|
|
@@ -163,27 +179,39 @@ export function activateStrandsLocal(sourceRoot: string, dest: string): Record<s
|
|
|
163
179
|
const inventory = readKitInventory(sourceRoot, dest);
|
|
164
180
|
// Runtime flows land at .flow-agents/runtime/strands/flows/<kit-id>/<asset-id>.flow.json
|
|
165
181
|
// so the Strands steering context can glob for *.flow.json under this path.
|
|
182
|
+
// Runtime skills land at .flow-agents/runtime/strands/skills/<kit-id>/<filename> and
|
|
183
|
+
// docs at .flow-agents/runtime/strands/docs/<kit-id>/<filename> for system-prompt injection.
|
|
166
184
|
const runtimeDir = path.join(dest, ".flow-agents", "runtime", "strands");
|
|
167
185
|
const generated: Record<string, string>[] = [];
|
|
168
186
|
const skipped: Record<string, string | null>[] = [];
|
|
169
187
|
for (const asset of inventory.assets) {
|
|
170
|
-
if (asset.asset_class
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
188
|
+
if (asset.asset_class === "flows") {
|
|
189
|
+
if (!asset.asset_id) {
|
|
190
|
+
skipped.push({ asset_class: asset.asset_class, path: asset.relative_path, kit_id: asset.kit_id, asset_id: null, reason: "flow asset is missing an id" });
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
const output = path.join(runtimeDir, "flows", safeSegment(asset.kit_id), `${safeSegment(asset.asset_id)}.flow.json`);
|
|
194
|
+
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
195
|
+
fs.copyFileSync(asset.source_path, output);
|
|
196
|
+
generated.push({ asset_class: asset.asset_class, path: relPath(dest, output), kit_id: asset.kit_id, asset_id: asset.asset_id, source_path: asset.source_path.split(path.sep).join("/") });
|
|
197
|
+
} else if (asset.asset_class === "skills" || asset.asset_class === "docs") {
|
|
198
|
+
// Mirror the codex-local layout: strands/<class>/<kit-id>/<filename>.
|
|
199
|
+
// The Strands system-prompt injection layer can glob for all *.md files under
|
|
200
|
+
// .flow-agents/runtime/strands/skills/ to include agent guidance in the context.
|
|
201
|
+
const filename = path.basename(asset.source_path);
|
|
202
|
+
const output = path.join(runtimeDir, asset.asset_class, safeSegment(asset.kit_id), filename);
|
|
203
|
+
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
204
|
+
fs.copyFileSync(asset.source_path, output);
|
|
205
|
+
generated.push({ asset_class: asset.asset_class, path: relPath(dest, output), kit_id: asset.kit_id, asset_id: asset.asset_id ?? "", source_path: asset.source_path.split(path.sep).join("/") });
|
|
206
|
+
} else {
|
|
207
|
+
skipped.push({ asset_class: asset.asset_class, path: asset.relative_path, kit_id: asset.kit_id, asset_id: asset.asset_id, reason: "asset class is not activated by strands-local" });
|
|
177
208
|
}
|
|
178
|
-
const output = path.join(runtimeDir, "flows", safeSegment(asset.kit_id), `${safeSegment(asset.asset_id)}.flow.json`);
|
|
179
|
-
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
180
|
-
fs.copyFileSync(asset.source_path, output);
|
|
181
|
-
generated.push({ asset_class: asset.asset_class, path: relPath(dest, output), kit_id: asset.kit_id, asset_id: asset.asset_id, source_path: asset.source_path.split(path.sep).join("/") });
|
|
182
209
|
}
|
|
183
210
|
fs.mkdirSync(runtimeDir, { recursive: true });
|
|
184
|
-
const
|
|
211
|
+
const supportedClasses = Array.from(ACTIVATED_ASSET_CLASSES);
|
|
212
|
+
const manifest = { schema_version: "1.0", adapter: "strands-local", supported_asset_classes: supportedClasses, generated_runtime_files: generated, skipped_assets: skipped, warnings: inventory.warnings, errors: inventory.errors };
|
|
185
213
|
const manifestPath = path.join(runtimeDir, "activation.json");
|
|
186
214
|
writeJson(manifestPath, manifest);
|
|
187
215
|
generated.push({ asset_class: "activation-manifest", path: relPath(dest, manifestPath), kit_id: "runtime", asset_id: "strands-local.activation", source_path: manifestPath.split(path.sep).join("/") });
|
|
188
|
-
return { selected_adapter: "strands-local", supported_asset_classes:
|
|
216
|
+
return { selected_adapter: "strands-local", supported_asset_classes: supportedClasses, generated_runtime_files: generated, skipped_assets: skipped, warnings: inventory.warnings, errors: inventory.errors };
|
|
189
217
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import fs from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { loadJson, readText, root, walkFiles, writeText } from "./common.js";
|
|
5
6
|
|
|
@@ -646,4 +647,9 @@ export function main(): number {
|
|
|
646
647
|
}
|
|
647
648
|
return 0;
|
|
648
649
|
}
|
|
649
|
-
|
|
650
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
651
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
652
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
653
|
+
const _selfRealPath = (() => { try { return fs.realpathSync(fileURLToPath(import.meta.url)); } catch { return fileURLToPath(import.meta.url); } })();
|
|
654
|
+
const _argv1RealPath = (() => { try { return fs.realpathSync(process.argv[1]); } catch { return process.argv[1]; } })();
|
|
655
|
+
if (_selfRealPath === _argv1RealPath) { process.exitCode = main(); }
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import fs from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { exists, loadJson, markdownTable, oneLine, readText, rel, root, writeText } from "./common.js";
|
|
5
6
|
|
|
@@ -196,4 +197,9 @@ export function main(argv = process.argv.slice(2)): number {
|
|
|
196
197
|
return 0;
|
|
197
198
|
}
|
|
198
199
|
|
|
199
|
-
|
|
200
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
201
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
202
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
203
|
+
const _selfRealPath = (() => { try { return fs.realpathSync(fileURLToPath(import.meta.url)); } catch { return fileURLToPath(import.meta.url); } })();
|
|
204
|
+
const _argv1RealPath = (() => { try { return fs.realpathSync(process.argv[1]); } catch { return process.argv[1]; } })();
|
|
205
|
+
if (_selfRealPath === _argv1RealPath) { process.exitCode = main(); }
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import fs from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
|
|
5
6
|
export function main(argv = process.argv.slice(2)): number {
|
|
@@ -54,4 +55,9 @@ export function main(argv = process.argv.slice(2)): number {
|
|
|
54
55
|
console.log(errors === 0 ? "Result: PASS" : `Result: FAIL (${errors} error(s))`);
|
|
55
56
|
return errors === 0 ? 0 : 1;
|
|
56
57
|
}
|
|
57
|
-
|
|
58
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
59
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
60
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
61
|
+
const _selfRealPath = (() => { try { return fs.realpathSync(fileURLToPath(import.meta.url)); } catch { return fileURLToPath(import.meta.url); } })();
|
|
62
|
+
const _argv1RealPath = (() => { try { return fs.realpathSync(process.argv[1]); } catch { return process.argv[1]; } })();
|
|
63
|
+
if (_selfRealPath === _argv1RealPath) { process.exitCode = main(); }
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import fs from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { spawnSync } from "node:child_process";
|
|
5
6
|
import { loadJson, readText, rel, root, walkFiles } from "./common.js";
|
|
@@ -491,4 +492,9 @@ export function main(argv = process.argv.slice(2)): number {
|
|
|
491
492
|
console.log("Source tree validation passed.");
|
|
492
493
|
return 0;
|
|
493
494
|
}
|
|
494
|
-
|
|
495
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
496
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
497
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
498
|
+
const _selfRealPath = (() => { try { return fs.realpathSync(fileURLToPath(import.meta.url)); } catch { return fileURLToPath(import.meta.url); } })();
|
|
499
|
+
const _argv1RealPath = (() => { try { return fs.realpathSync(process.argv[1]); } catch { return process.argv[1]; } })();
|
|
500
|
+
if (_selfRealPath === _argv1RealPath) { process.exitCode = main(); }
|