@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/.github/workflows/ci.yml
CHANGED
|
@@ -196,6 +196,55 @@ jobs:
|
|
|
196
196
|
continue-on-error: true
|
|
197
197
|
run: bash evals/ci/run-baseline.sh --check bundle-install-integration
|
|
198
198
|
|
|
199
|
+
- name: Bundle lifecycle integration
|
|
200
|
+
continue-on-error: true
|
|
201
|
+
run: bash evals/ci/run-baseline.sh --check bundle-lifecycle-integration
|
|
202
|
+
|
|
203
|
+
- name: Activate npx context integration
|
|
204
|
+
continue-on-error: true
|
|
205
|
+
run: bash evals/ci/run-baseline.sh --check activate-npx-context-integration
|
|
206
|
+
|
|
207
|
+
- name: Kit conformance levels integration
|
|
208
|
+
continue-on-error: true
|
|
209
|
+
run: bash evals/ci/run-baseline.sh --check kit-conformance-levels-integration
|
|
210
|
+
|
|
211
|
+
- name: Local Flow Kit install integration
|
|
212
|
+
continue-on-error: true
|
|
213
|
+
run: bash evals/ci/run-baseline.sh --check local-flow-kit-install-integration
|
|
214
|
+
|
|
215
|
+
- name: Flow Kit install-git integration
|
|
216
|
+
continue-on-error: true
|
|
217
|
+
run: bash evals/ci/run-baseline.sh --check flow-kit-install-git-integration
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
- name: Context map integration
|
|
221
|
+
continue-on-error: true
|
|
222
|
+
run: bash evals/ci/run-baseline.sh --check context-map-integration
|
|
223
|
+
|
|
224
|
+
- name: Effective backlog settings integration
|
|
225
|
+
continue-on-error: true
|
|
226
|
+
run: bash evals/ci/run-baseline.sh --check effective-backlog-settings-integration
|
|
227
|
+
|
|
228
|
+
- name: Flow agents statusline integration
|
|
229
|
+
continue-on-error: true
|
|
230
|
+
run: bash evals/ci/run-baseline.sh --check flow-agents-statusline-integration
|
|
231
|
+
|
|
232
|
+
- name: Telemetry contract integration
|
|
233
|
+
continue-on-error: true
|
|
234
|
+
run: bash evals/ci/run-baseline.sh --check telemetry-contract-integration
|
|
235
|
+
|
|
236
|
+
- name: Telemetry doctor integration
|
|
237
|
+
continue-on-error: true
|
|
238
|
+
run: bash evals/ci/run-baseline.sh --check telemetry-doctor-integration
|
|
239
|
+
|
|
240
|
+
- name: Utterance check integration
|
|
241
|
+
continue-on-error: true
|
|
242
|
+
run: bash evals/ci/run-baseline.sh --check utterance-check-integration
|
|
243
|
+
|
|
244
|
+
- name: Pull work provider integration
|
|
245
|
+
continue-on-error: true
|
|
246
|
+
run: bash evals/ci/run-baseline.sh --check pull-work-provider-integration
|
|
247
|
+
|
|
199
248
|
- name: Finalize CI evidence
|
|
200
249
|
if: always()
|
|
201
250
|
run: bash evals/ci/run-baseline.sh --finalize
|
|
@@ -208,3 +257,64 @@ jobs:
|
|
|
208
257
|
path: evals/results/ci-baseline/runtime-and-kit/
|
|
209
258
|
if-no-files-found: warn
|
|
210
259
|
retention-days: 14
|
|
260
|
+
|
|
261
|
+
usage-feedback:
|
|
262
|
+
name: Usage Feedback
|
|
263
|
+
runs-on: ubuntu-latest
|
|
264
|
+
timeout-minutes: 15
|
|
265
|
+
env:
|
|
266
|
+
FLOW_AGENTS_CI_LANE: usage-feedback
|
|
267
|
+
FLOW_AGENTS_CI_RESULTS_DIR: evals/results/ci-baseline/usage-feedback
|
|
268
|
+
|
|
269
|
+
steps:
|
|
270
|
+
- name: Checkout
|
|
271
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
272
|
+
|
|
273
|
+
- name: Set up Node.js
|
|
274
|
+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
275
|
+
with:
|
|
276
|
+
node-version: "22"
|
|
277
|
+
|
|
278
|
+
- name: Install Node dependencies
|
|
279
|
+
run: npm ci
|
|
280
|
+
|
|
281
|
+
- name: Install shell tools
|
|
282
|
+
run: |
|
|
283
|
+
sudo apt-get update
|
|
284
|
+
sudo apt-get install -y jq ripgrep
|
|
285
|
+
|
|
286
|
+
- name: Initialize CI evidence
|
|
287
|
+
run: bash evals/ci/run-baseline.sh --init
|
|
288
|
+
|
|
289
|
+
- name: Usage feedback import integration
|
|
290
|
+
continue-on-error: true
|
|
291
|
+
run: bash evals/ci/run-baseline.sh --check usage-feedback-import-integration
|
|
292
|
+
|
|
293
|
+
- name: Usage feedback outcomes integration
|
|
294
|
+
continue-on-error: true
|
|
295
|
+
run: bash evals/ci/run-baseline.sh --check usage-feedback-outcomes-integration
|
|
296
|
+
|
|
297
|
+
- name: Usage feedback report integration
|
|
298
|
+
continue-on-error: true
|
|
299
|
+
run: bash evals/ci/run-baseline.sh --check usage-feedback-report-integration
|
|
300
|
+
|
|
301
|
+
- name: Usage feedback dashboard integration
|
|
302
|
+
continue-on-error: true
|
|
303
|
+
run: bash evals/ci/run-baseline.sh --check usage-feedback-dashboard-integration
|
|
304
|
+
|
|
305
|
+
- name: Usage feedback global integration
|
|
306
|
+
continue-on-error: true
|
|
307
|
+
run: bash evals/ci/run-baseline.sh --check usage-feedback-global-integration
|
|
308
|
+
|
|
309
|
+
- name: Finalize CI evidence
|
|
310
|
+
if: always()
|
|
311
|
+
run: bash evals/ci/run-baseline.sh --finalize
|
|
312
|
+
|
|
313
|
+
- name: Upload CI evidence artifacts
|
|
314
|
+
if: always()
|
|
315
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
316
|
+
with:
|
|
317
|
+
name: flow-agents-ci-usage-feedback
|
|
318
|
+
path: evals/results/ci-baseline/usage-feedback/
|
|
319
|
+
if-no-files-found: warn
|
|
320
|
+
retention-days: 14
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.1.0](https://github.com/kontourai/flow-agents/compare/v1.0.1...v1.1.0) (2026-06-15)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* activate skills and docs in kit runtime adapters (fix [#58](https://github.com/kontourai/flow-agents/issues/58)) ([dc726fd](https://github.com/kontourai/flow-agents/commit/dc726fd1d56e79b5bda577985aa87befe3a1eb9d))
|
|
9
|
+
* activate skills and docs in kit runtime adapters (fix [#58](https://github.com/kontourai/flow-agents/issues/58)) ([dc774e0](https://github.com/kontourai/flow-agents/commit/dc774e001b54f7a09f6ab81a6aafcf2ad8552b6d))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Fixes
|
|
13
|
+
|
|
14
|
+
* apply realpathSync entry-guard to 7 remaining CLI/tool files ([c1b3272](https://github.com/kontourai/flow-agents/commit/c1b3272c623055662a63c5d11c6dbef5aabe1cf0))
|
|
15
|
+
* apply realpathSync entry-guard to all 16 affected CLI/tool files (closes [#71](https://github.com/kontourai/flow-agents/issues/71)) ([8a676b0](https://github.com/kontourai/flow-agents/commit/8a676b0c9c91464d64755719ff778a13e298beb9))
|
|
16
|
+
* apply realpathSync entry-guard to remaining 10 CLI/tool files ([159bb78](https://github.com/kontourai/flow-agents/commit/159bb785b6b28f99b0a3a5c95e0d4428512f4314))
|
|
17
|
+
* use hosted console io preset ([5b4bb7b](https://github.com/kontourai/flow-agents/commit/5b4bb7bc86d154bcf4d529a62e398a2196b702cc))
|
|
18
|
+
|
|
3
19
|
## [1.0.1](https://github.com/kontourai/flow-agents/compare/v1.0.0...v1.0.1) (2026-06-12)
|
|
4
20
|
|
|
5
21
|
|
|
@@ -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
|
import { buildWorkflowLearningProjection, readWorkflowLearningSources } from "../lib/workflow-learning-projection.js";
|
|
@@ -119,5 +120,21 @@ export function main(argv = process.argv.slice(2)) {
|
|
|
119
120
|
return 1;
|
|
120
121
|
}
|
|
121
122
|
}
|
|
122
|
-
|
|
123
|
-
|
|
123
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
124
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
125
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
126
|
+
const _selfRealPath = (() => { try {
|
|
127
|
+
return fs.realpathSync(fileURLToPath(import.meta.url));
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return fileURLToPath(import.meta.url);
|
|
131
|
+
} })();
|
|
132
|
+
const _argv1RealPath = (() => { try {
|
|
133
|
+
return fs.realpathSync(process.argv[1]);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return process.argv[1];
|
|
137
|
+
} })();
|
|
138
|
+
if (_selfRealPath === _argv1RealPath) {
|
|
139
|
+
process.exitCode = main();
|
|
140
|
+
}
|
|
@@ -98,5 +98,21 @@ export function main(argv = process.argv.slice(2)) {
|
|
|
98
98
|
return 1;
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
102
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
103
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
104
|
+
const _selfRealPath = (() => { try {
|
|
105
|
+
return fs.realpathSync(fileURLToPath(import.meta.url));
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return fileURLToPath(import.meta.url);
|
|
109
|
+
} })();
|
|
110
|
+
const _argv1RealPath = (() => { try {
|
|
111
|
+
return fs.realpathSync(process.argv[1]);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return process.argv[1];
|
|
115
|
+
} })();
|
|
116
|
+
if (_selfRealPath === _argv1RealPath) {
|
|
117
|
+
process.exitCode = main();
|
|
118
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
3
4
|
import * as path from "node:path";
|
|
4
5
|
const root = path.resolve(".");
|
|
5
6
|
const fixtureRoot = "evals/fixtures";
|
|
@@ -136,5 +137,21 @@ export function main(argv = process.argv.slice(2)) {
|
|
|
136
137
|
return 1;
|
|
137
138
|
}
|
|
138
139
|
}
|
|
139
|
-
|
|
140
|
-
|
|
140
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
141
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
142
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
143
|
+
const _selfRealPath = (() => { try {
|
|
144
|
+
return fs.realpathSync(fileURLToPath(import.meta.url));
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return fileURLToPath(import.meta.url);
|
|
148
|
+
} })();
|
|
149
|
+
const _argv1RealPath = (() => { try {
|
|
150
|
+
return fs.realpathSync(process.argv[1]);
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return process.argv[1];
|
|
154
|
+
} })();
|
|
155
|
+
if (_selfRealPath === _argv1RealPath) {
|
|
156
|
+
process.exitCode = main();
|
|
157
|
+
}
|
package/build/src/cli/init.js
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";
|
|
@@ -445,5 +446,21 @@ export async function mainDogfood(argv = process.argv.slice(2)) {
|
|
|
445
446
|
return 2;
|
|
446
447
|
}
|
|
447
448
|
}
|
|
448
|
-
|
|
449
|
-
|
|
449
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
450
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
451
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
452
|
+
const _selfRealPath = (() => { try {
|
|
453
|
+
return fs.realpathSync(fileURLToPath(import.meta.url));
|
|
454
|
+
}
|
|
455
|
+
catch {
|
|
456
|
+
return fileURLToPath(import.meta.url);
|
|
457
|
+
} })();
|
|
458
|
+
const _argv1RealPath = (() => { try {
|
|
459
|
+
return fs.realpathSync(process.argv[1]);
|
|
460
|
+
}
|
|
461
|
+
catch {
|
|
462
|
+
return process.argv[1];
|
|
463
|
+
} })();
|
|
464
|
+
if (_selfRealPath === _argv1RealPath) {
|
|
465
|
+
process.exitCode = await main();
|
|
466
|
+
}
|
|
@@ -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";
|
|
@@ -59,5 +60,21 @@ export function main(argv = process.argv.slice(2)) {
|
|
|
59
60
|
console.log(`archived_artifact=${archive}`);
|
|
60
61
|
return 0;
|
|
61
62
|
}
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
64
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
65
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
66
|
+
const _selfRealPath = (() => { try {
|
|
67
|
+
return fs.realpathSync(fileURLToPath(import.meta.url));
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return fileURLToPath(import.meta.url);
|
|
71
|
+
} })();
|
|
72
|
+
const _argv1RealPath = (() => { try {
|
|
73
|
+
return fs.realpathSync(process.argv[1]);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return process.argv[1];
|
|
77
|
+
} })();
|
|
78
|
+
if (_selfRealPath === _argv1RealPath) {
|
|
79
|
+
process.exitCode = main();
|
|
80
|
+
}
|
|
@@ -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";
|
|
@@ -150,5 +151,21 @@ export function main(argv = process.argv.slice(2)) {
|
|
|
150
151
|
return 1;
|
|
151
152
|
}
|
|
152
153
|
}
|
|
153
|
-
|
|
154
|
-
|
|
154
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
155
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
156
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
157
|
+
const _selfRealPath = (() => { try {
|
|
158
|
+
return fs.realpathSync(fileURLToPath(import.meta.url));
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return fileURLToPath(import.meta.url);
|
|
162
|
+
} })();
|
|
163
|
+
const _argv1RealPath = (() => { try {
|
|
164
|
+
return fs.realpathSync(process.argv[1]);
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return process.argv[1];
|
|
168
|
+
} })();
|
|
169
|
+
if (_selfRealPath === _argv1RealPath) {
|
|
170
|
+
process.exitCode = main();
|
|
171
|
+
}
|
|
@@ -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
|
const FLOW_ARTIFACT_PATTERN = /(?<path>\.flow-agents\/[^\s`'")]+)/g;
|
|
4
5
|
const GITHUB_ISSUE_PATTERN = /(?:(?<owner>[A-Za-z0-9_.-]+)\/(?<repo>[A-Za-z0-9_.-]+))?#(?<number>\d+)/g;
|
|
@@ -465,5 +466,21 @@ export function main(argv = process.argv.slice(2)) {
|
|
|
465
466
|
console.log(JSON.stringify({ items }, null, 2));
|
|
466
467
|
return 0;
|
|
467
468
|
}
|
|
468
|
-
|
|
469
|
-
|
|
469
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
470
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
471
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
472
|
+
const _selfRealPath = (() => { try {
|
|
473
|
+
return fs.realpathSync(fileURLToPath(import.meta.url));
|
|
474
|
+
}
|
|
475
|
+
catch {
|
|
476
|
+
return fileURLToPath(import.meta.url);
|
|
477
|
+
} })();
|
|
478
|
+
const _argv1RealPath = (() => { try {
|
|
479
|
+
return fs.realpathSync(process.argv[1]);
|
|
480
|
+
}
|
|
481
|
+
catch {
|
|
482
|
+
return process.argv[1];
|
|
483
|
+
} })();
|
|
484
|
+
if (_selfRealPath === _argv1RealPath) {
|
|
485
|
+
process.exitCode = main();
|
|
486
|
+
}
|
|
@@ -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";
|
|
@@ -23,5 +25,21 @@ export function main(argv = process.argv.slice(2)) {
|
|
|
23
25
|
console.log(JSON.stringify(result, null, 2));
|
|
24
26
|
return Array.isArray(result.errors) && result.errors.length ? 1 : 0;
|
|
25
27
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
29
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
30
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
31
|
+
const _selfRealPath = (() => { try {
|
|
32
|
+
return fs.realpathSync(fileURLToPath(import.meta.url));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return fileURLToPath(import.meta.url);
|
|
36
|
+
} })();
|
|
37
|
+
const _argv1RealPath = (() => { try {
|
|
38
|
+
return fs.realpathSync(process.argv[1]);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return process.argv[1];
|
|
42
|
+
} })();
|
|
43
|
+
if (_selfRealPath === _argv1RealPath) {
|
|
44
|
+
process.exitCode = main();
|
|
45
|
+
}
|
|
@@ -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";
|
|
@@ -439,5 +440,21 @@ export function main(argv = process.argv.slice(2)) {
|
|
|
439
440
|
return 1;
|
|
440
441
|
}
|
|
441
442
|
}
|
|
442
|
-
|
|
443
|
-
|
|
443
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
444
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
445
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
446
|
+
const _selfRealPath = (() => { try {
|
|
447
|
+
return fs.realpathSync(fileURLToPath(import.meta.url));
|
|
448
|
+
}
|
|
449
|
+
catch {
|
|
450
|
+
return fileURLToPath(import.meta.url);
|
|
451
|
+
} })();
|
|
452
|
+
const _argv1RealPath = (() => { try {
|
|
453
|
+
return fs.realpathSync(process.argv[1]);
|
|
454
|
+
}
|
|
455
|
+
catch {
|
|
456
|
+
return process.argv[1];
|
|
457
|
+
} })();
|
|
458
|
+
if (_selfRealPath === _argv1RealPath) {
|
|
459
|
+
process.exitCode = main();
|
|
460
|
+
}
|
|
@@ -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
|
// ---------------------------------------------------------------------------
|
|
@@ -232,5 +233,21 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
232
233
|
}
|
|
233
234
|
return runCheck(rest);
|
|
234
235
|
}
|
|
235
|
-
|
|
236
|
-
|
|
236
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
237
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
238
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
239
|
+
const _selfRealPath = (() => { try {
|
|
240
|
+
return fs.realpathSync(fileURLToPath(import.meta.url));
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
return fileURLToPath(import.meta.url);
|
|
244
|
+
} })();
|
|
245
|
+
const _argv1RealPath = (() => { try {
|
|
246
|
+
return fs.realpathSync(process.argv[1]);
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
return process.argv[1];
|
|
250
|
+
} })();
|
|
251
|
+
if (_selfRealPath === _argv1RealPath) {
|
|
252
|
+
process.exitCode = await main();
|
|
253
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
2
3
|
const validTiers = new Set(["adapter", "design-target", "installed-command", "live-acceptance", "documented-runtime-gap"]);
|
|
3
4
|
const validRuntimes = new Set(["codex", "claude-code", "kiro-cli"]);
|
|
4
5
|
const validHooks = new Set(["workflow-steering", "stop-goal-fit"]);
|
|
@@ -148,5 +149,21 @@ export function main(argv = process.argv.slice(2)) {
|
|
|
148
149
|
return 1;
|
|
149
150
|
}
|
|
150
151
|
}
|
|
151
|
-
|
|
152
|
-
|
|
152
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
153
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
154
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
155
|
+
const _selfRealPath = (() => { try {
|
|
156
|
+
return fs.realpathSync(fileURLToPath(import.meta.url));
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return fileURLToPath(import.meta.url);
|
|
160
|
+
} })();
|
|
161
|
+
const _argv1RealPath = (() => { try {
|
|
162
|
+
return fs.realpathSync(process.argv[1]);
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return process.argv[1];
|
|
166
|
+
} })();
|
|
167
|
+
if (_selfRealPath === _argv1RealPath) {
|
|
168
|
+
process.exitCode = main();
|
|
169
|
+
}
|
|
@@ -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";
|
|
@@ -258,5 +259,21 @@ export function main(argv = process.argv.slice(2)) {
|
|
|
258
259
|
const options = parseEvidenceOptions(argv);
|
|
259
260
|
return options ? runEvidence(options) : 2;
|
|
260
261
|
}
|
|
261
|
-
|
|
262
|
-
|
|
262
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
263
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
264
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
265
|
+
const _selfRealPath = (() => { try {
|
|
266
|
+
return fs.realpathSync(fileURLToPath(import.meta.url));
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
return fileURLToPath(import.meta.url);
|
|
270
|
+
} })();
|
|
271
|
+
const _argv1RealPath = (() => { try {
|
|
272
|
+
return fs.realpathSync(process.argv[1]);
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
return process.argv[1];
|
|
276
|
+
} })();
|
|
277
|
+
if (_selfRealPath === _argv1RealPath) {
|
|
278
|
+
process.exitCode = main();
|
|
279
|
+
}
|
|
@@ -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
|
const ACTIVE_STATUSES = new Set([
|
|
@@ -268,5 +269,21 @@ export function main(argv = process.argv.slice(2)) {
|
|
|
268
269
|
printText(result);
|
|
269
270
|
return 0;
|
|
270
271
|
}
|
|
271
|
-
|
|
272
|
-
|
|
272
|
+
// Use process.exitCode (not process.exit) to allow stdout to be flushed before exit.
|
|
273
|
+
// Resolve real paths to handle symlinks (e.g. /tmp -> /private/tmp on macOS) so the
|
|
274
|
+
// entry-point guard fires correctly when the module is loaded directly as a script.
|
|
275
|
+
const _selfRealPath = (() => { try {
|
|
276
|
+
return fs.realpathSync(fileURLToPath(import.meta.url));
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
return fileURLToPath(import.meta.url);
|
|
280
|
+
} })();
|
|
281
|
+
const _argv1RealPath = (() => { try {
|
|
282
|
+
return fs.realpathSync(process.argv[1]);
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
return process.argv[1];
|
|
286
|
+
} })();
|
|
287
|
+
if (_selfRealPath === _argv1RealPath) {
|
|
288
|
+
process.exitCode = main();
|
|
289
|
+
}
|
|
@@ -118,31 +118,48 @@ export function readKitInventory(sourceRoot, dest) {
|
|
|
118
118
|
function safeSegment(value) {
|
|
119
119
|
return value.replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^[.-]+|[.-]+$/g, "") || "asset";
|
|
120
120
|
}
|
|
121
|
+
// Asset classes that are directly activated (copied to the runtime directory) by both adapters.
|
|
122
|
+
// flows: gate definitions read by the adapter's flow-routing layer.
|
|
123
|
+
// skills: agent guidance markdown copied to skills/<kit-id>/ for agent discovery.
|
|
124
|
+
// docs: documentation markdown copied to docs/<kit-id>/ for agent reference.
|
|
125
|
+
const ACTIVATED_ASSET_CLASSES = new Set(["flows", "skills", "docs"]);
|
|
121
126
|
export function activateCodexLocal(sourceRoot, dest) {
|
|
122
127
|
const inventory = readKitInventory(sourceRoot, dest);
|
|
123
128
|
const runtimeDir = path.join(dest, ".flow-agents", "runtime", "codex");
|
|
124
129
|
const generated = [];
|
|
125
130
|
const skipped = [];
|
|
126
131
|
for (const asset of inventory.assets) {
|
|
127
|
-
if (asset.asset_class
|
|
128
|
-
|
|
129
|
-
|
|
132
|
+
if (asset.asset_class === "flows") {
|
|
133
|
+
if (!asset.asset_id) {
|
|
134
|
+
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" });
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const output = path.join(runtimeDir, "flows", safeSegment(asset.kit_id), `${safeSegment(asset.asset_id)}.flow.json`);
|
|
138
|
+
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
139
|
+
fs.copyFileSync(asset.source_path, output);
|
|
140
|
+
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("/") });
|
|
130
141
|
}
|
|
131
|
-
if (
|
|
132
|
-
|
|
133
|
-
|
|
142
|
+
else if (asset.asset_class === "skills" || asset.asset_class === "docs") {
|
|
143
|
+
// Copy skills and docs to runtime/<adapter>/<class>/<kit-id>/<filename> so the
|
|
144
|
+
// agent's guidance index (AGENTS.md) can reference them and they are co-located
|
|
145
|
+
// with flow definitions for the same kit.
|
|
146
|
+
const filename = path.basename(asset.source_path);
|
|
147
|
+
const output = path.join(runtimeDir, asset.asset_class, safeSegment(asset.kit_id), filename);
|
|
148
|
+
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
149
|
+
fs.copyFileSync(asset.source_path, output);
|
|
150
|
+
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("/") });
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
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" });
|
|
134
154
|
}
|
|
135
|
-
const output = path.join(runtimeDir, "flows", safeSegment(asset.kit_id), `${safeSegment(asset.asset_id)}.flow.json`);
|
|
136
|
-
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
137
|
-
fs.copyFileSync(asset.source_path, output);
|
|
138
|
-
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("/") });
|
|
139
155
|
}
|
|
140
156
|
fs.mkdirSync(runtimeDir, { recursive: true });
|
|
141
|
-
const
|
|
157
|
+
const supportedClasses = Array.from(ACTIVATED_ASSET_CLASSES);
|
|
158
|
+
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 };
|
|
142
159
|
const manifestPath = path.join(runtimeDir, "activation.json");
|
|
143
160
|
writeJson(manifestPath, manifest);
|
|
144
161
|
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("/") });
|
|
145
|
-
return { selected_adapter: "codex-local", supported_asset_classes:
|
|
162
|
+
return { selected_adapter: "codex-local", supported_asset_classes: supportedClasses, generated_runtime_files: generated, skipped_assets: skipped, warnings: inventory.warnings, errors: inventory.errors };
|
|
146
163
|
}
|
|
147
164
|
// Decision Q3 (Issue #32): Option (a) — new adapter id "strands-local" rather than
|
|
148
165
|
// loading kit flows inside FlowAgentsHooks. Rationale: activation is a workspace-prep
|
|
@@ -154,27 +171,41 @@ export function activateStrandsLocal(sourceRoot, dest) {
|
|
|
154
171
|
const inventory = readKitInventory(sourceRoot, dest);
|
|
155
172
|
// Runtime flows land at .flow-agents/runtime/strands/flows/<kit-id>/<asset-id>.flow.json
|
|
156
173
|
// so the Strands steering context can glob for *.flow.json under this path.
|
|
174
|
+
// Runtime skills land at .flow-agents/runtime/strands/skills/<kit-id>/<filename> and
|
|
175
|
+
// docs at .flow-agents/runtime/strands/docs/<kit-id>/<filename> for system-prompt injection.
|
|
157
176
|
const runtimeDir = path.join(dest, ".flow-agents", "runtime", "strands");
|
|
158
177
|
const generated = [];
|
|
159
178
|
const skipped = [];
|
|
160
179
|
for (const asset of inventory.assets) {
|
|
161
|
-
if (asset.asset_class
|
|
162
|
-
|
|
163
|
-
|
|
180
|
+
if (asset.asset_class === "flows") {
|
|
181
|
+
if (!asset.asset_id) {
|
|
182
|
+
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" });
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
const output = path.join(runtimeDir, "flows", safeSegment(asset.kit_id), `${safeSegment(asset.asset_id)}.flow.json`);
|
|
186
|
+
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
187
|
+
fs.copyFileSync(asset.source_path, output);
|
|
188
|
+
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("/") });
|
|
164
189
|
}
|
|
165
|
-
if (
|
|
166
|
-
|
|
167
|
-
|
|
190
|
+
else if (asset.asset_class === "skills" || asset.asset_class === "docs") {
|
|
191
|
+
// Mirror the codex-local layout: strands/<class>/<kit-id>/<filename>.
|
|
192
|
+
// The Strands system-prompt injection layer can glob for all *.md files under
|
|
193
|
+
// .flow-agents/runtime/strands/skills/ to include agent guidance in the context.
|
|
194
|
+
const filename = path.basename(asset.source_path);
|
|
195
|
+
const output = path.join(runtimeDir, asset.asset_class, safeSegment(asset.kit_id), filename);
|
|
196
|
+
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
197
|
+
fs.copyFileSync(asset.source_path, output);
|
|
198
|
+
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("/") });
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
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" });
|
|
168
202
|
}
|
|
169
|
-
const output = path.join(runtimeDir, "flows", safeSegment(asset.kit_id), `${safeSegment(asset.asset_id)}.flow.json`);
|
|
170
|
-
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
171
|
-
fs.copyFileSync(asset.source_path, output);
|
|
172
|
-
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("/") });
|
|
173
203
|
}
|
|
174
204
|
fs.mkdirSync(runtimeDir, { recursive: true });
|
|
175
|
-
const
|
|
205
|
+
const supportedClasses = Array.from(ACTIVATED_ASSET_CLASSES);
|
|
206
|
+
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 };
|
|
176
207
|
const manifestPath = path.join(runtimeDir, "activation.json");
|
|
177
208
|
writeJson(manifestPath, manifest);
|
|
178
209
|
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("/") });
|
|
179
|
-
return { selected_adapter: "strands-local", supported_asset_classes:
|
|
210
|
+
return { selected_adapter: "strands-local", supported_asset_classes: supportedClasses, generated_runtime_files: generated, skipped_assets: skipped, warnings: inventory.warnings, errors: inventory.errors };
|
|
180
211
|
}
|