@ikon85/agent-workflow-kit 0.44.1 → 0.44.2
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 +7 -0
- package/agent-workflow-kit.package.json +1 -1
- package/package.json +1 -1
- package/src/cli.mjs +6 -1
- package/src/commands/update.mjs +9 -1
- package/src/consumer-migrations.json +23 -1
- package/src/lib/consumerMigrations.mjs +55 -0
package/README.md
CHANGED
|
@@ -579,6 +579,13 @@ the old way. Decision record:
|
|
|
579
579
|
|
|
580
580
|
## Release notes
|
|
581
581
|
|
|
582
|
+
### 0.44.2
|
|
583
|
+
|
|
584
|
+
- changed: `src/cli.mjs`
|
|
585
|
+
- changed: `src/commands/update.mjs`
|
|
586
|
+
- changed: `src/consumer-migrations.json`
|
|
587
|
+
- changed: `src/lib/consumerMigrations.mjs`
|
|
588
|
+
|
|
582
589
|
### 0.44.1
|
|
583
590
|
|
|
584
591
|
- changed: `.claude/skills/skill-manifest.json`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ikon85/agent-workflow-kit",
|
|
3
|
-
"version": "0.44.
|
|
3
|
+
"version": "0.44.2",
|
|
4
4
|
"description": "Portable AI-agent workflow skills (plan → execute → land → learn) for Claude Code & Codex — grilling, TDD, diagnosis, two-axis code review, cross-model Codex review, design & domain-modeling, plus a skill router (ask-matt). npx init/update/diff/uninstall.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/cli.mjs
CHANGED
|
@@ -16,7 +16,9 @@ import {
|
|
|
16
16
|
} from './lib/contributionRouting.mjs';
|
|
17
17
|
import { CONSUMER_ORIGIN, KIT_ORIGIN } from './lib/manifest.mjs';
|
|
18
18
|
import { nonInteractiveUpdateDecision } from './lib/updateDecisions.mjs';
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
renderConsumerAdvisory, renderRequiredMigration,
|
|
21
|
+
} from './lib/consumerMigrations.mjs';
|
|
20
22
|
import { currentAgentSurface } from './lib/agentSurfaceRegistry.mjs';
|
|
21
23
|
import { createCommandAdapter } from '../scripts/release-state.mjs';
|
|
22
24
|
import { installedIdentityFromDir } from '../scripts/release-parity.mjs';
|
|
@@ -242,6 +244,9 @@ function printPlan(r) {
|
|
|
242
244
|
lines.push(renderRequiredMigration(action));
|
|
243
245
|
lines.push(` ${action.consequence} ${action.remediation}`);
|
|
244
246
|
}
|
|
247
|
+
for (const advisory of r.advisories ?? []) {
|
|
248
|
+
lines.push(renderConsumerAdvisory(advisory));
|
|
249
|
+
}
|
|
245
250
|
for (const owned of r.ownedDiffs ?? []) {
|
|
246
251
|
lines.push(`${owned.state} ${owned.path}`);
|
|
247
252
|
if (owned.binary) {
|
package/src/commands/update.mjs
CHANGED
|
@@ -14,7 +14,9 @@ import {
|
|
|
14
14
|
import {
|
|
15
15
|
inspectRoutingProfile, reconcileRoutingProfile,
|
|
16
16
|
} from '../lib/routingProfile.mjs';
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
evaluateConsumerAdvisories, evaluateConsumerMigrations,
|
|
19
|
+
} from '../lib/consumerMigrations.mjs';
|
|
18
20
|
|
|
19
21
|
const RELEASE_NAME = '@ikon85/agent-workflow-kit';
|
|
20
22
|
|
|
@@ -82,8 +84,12 @@ async function updatePackage(options) {
|
|
|
82
84
|
const requiredMigrations = await evaluateConsumerMigrations({
|
|
83
85
|
consumerRoot, kitVersion: pkg.kitVersion,
|
|
84
86
|
});
|
|
87
|
+
const advisories = await evaluateConsumerAdvisories({
|
|
88
|
+
consumerRoot, kitVersion: pkg.kitVersion,
|
|
89
|
+
});
|
|
85
90
|
const preview = await reconcile({ kitRoot, consumerRoot, decide: choosePreview, dryRun: true });
|
|
86
91
|
preview.requiredMigrations = requiredMigrations;
|
|
92
|
+
preview.advisories = advisories;
|
|
87
93
|
let previewFailure;
|
|
88
94
|
try {
|
|
89
95
|
Object.assign(preview, await previewReadinessAdoption({
|
|
@@ -109,6 +115,7 @@ async function updatePackage(options) {
|
|
|
109
115
|
kitRoot, consumerRoot, preview, decisions, decide, transition,
|
|
110
116
|
});
|
|
111
117
|
resolvedPreview.requiredMigrations = requiredMigrations;
|
|
118
|
+
resolvedPreview.advisories = advisories;
|
|
112
119
|
if (resolvedPreview.collisions.length) {
|
|
113
120
|
return terminal(resolvedPreview, 'conflicted', history, transition);
|
|
114
121
|
}
|
|
@@ -297,6 +304,7 @@ function reportOf(result) {
|
|
|
297
304
|
},
|
|
298
305
|
recommendation: updateRecommendation(result),
|
|
299
306
|
requiredMigrations: result.requiredMigrations ?? [],
|
|
307
|
+
advisories: result.advisories ?? [],
|
|
300
308
|
};
|
|
301
309
|
}
|
|
302
310
|
|
|
@@ -1,4 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"migrations": []
|
|
3
|
+
"migrations": [],
|
|
4
|
+
"advisories": [
|
|
5
|
+
{
|
|
6
|
+
"id": "retired-worktree-scratch-patterns",
|
|
7
|
+
"kind": "retired-key",
|
|
8
|
+
"retiredIn": "0.44.0",
|
|
9
|
+
"detect": {
|
|
10
|
+
"type": "json-key",
|
|
11
|
+
"path": "docs/agents/workflow-capabilities.json",
|
|
12
|
+
"key": ["worktreeLifecycle", "scratchPatterns"]
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"id": "retired-wrapup-generated-artifact-patterns",
|
|
17
|
+
"kind": "retired-key",
|
|
18
|
+
"retiredIn": "0.44.0",
|
|
19
|
+
"detect": {
|
|
20
|
+
"type": "json-key",
|
|
21
|
+
"path": "docs/agents/workflow-capabilities.json",
|
|
22
|
+
"key": ["wrapup", "landingGeneratedArtifactPatterns"]
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
]
|
|
4
26
|
}
|
|
@@ -10,6 +10,7 @@ import { compareSemver, parseSemver } from './semver.mjs';
|
|
|
10
10
|
export const CONSUMER_MIGRATION_SCHEMA_VERSION = 1;
|
|
11
11
|
const REGISTRY_URL = new URL('../consumer-migrations.json', import.meta.url);
|
|
12
12
|
const DETECTORS = new Set(['json-key']);
|
|
13
|
+
const ADVISORY_KINDS = new Set(['retired-key']);
|
|
13
14
|
const TEXT_FIELDS = ['id', 'title', 'workflow', 'decision', 'consequence', 'remediation'];
|
|
14
15
|
|
|
15
16
|
let shipped;
|
|
@@ -81,9 +82,28 @@ export function validateConsumerMigrationRegistry(registry) {
|
|
|
81
82
|
detect: validateDetector(entry.detect, id),
|
|
82
83
|
});
|
|
83
84
|
});
|
|
85
|
+
const advisories = (registry.advisories ?? []).map((entry) => {
|
|
86
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
|
|
87
|
+
throw new Error('consumer migration registry: each advisory must be an object');
|
|
88
|
+
}
|
|
89
|
+
const id = text(entry.id, 'id', entry.id);
|
|
90
|
+
if (seen.has(id)) throw new Error(`consumer migration registry: duplicate entry id ${id}`);
|
|
91
|
+
seen.add(id);
|
|
92
|
+
if (!ADVISORY_KINDS.has(entry.kind)) {
|
|
93
|
+
throw new Error(`consumer migration registry: unsupported advisory kind ${entry.kind} (${id})`);
|
|
94
|
+
}
|
|
95
|
+
parseSemver(entry.retiredIn);
|
|
96
|
+
return Object.freeze({
|
|
97
|
+
id,
|
|
98
|
+
kind: entry.kind,
|
|
99
|
+
retiredIn: entry.retiredIn,
|
|
100
|
+
detect: validateDetector(entry.detect, id),
|
|
101
|
+
});
|
|
102
|
+
});
|
|
84
103
|
return Object.freeze({
|
|
85
104
|
schemaVersion: registry.schemaVersion,
|
|
86
105
|
migrations: Object.freeze(migrations),
|
|
106
|
+
advisories: Object.freeze(advisories),
|
|
87
107
|
});
|
|
88
108
|
}
|
|
89
109
|
|
|
@@ -126,6 +146,12 @@ async function detect(consumerRoot, migration) {
|
|
|
126
146
|
return hasDecision(document, migration.detect.key) ? null : 'missing-decision';
|
|
127
147
|
}
|
|
128
148
|
|
|
149
|
+
async function detectPresent(consumerRoot, advisory) {
|
|
150
|
+
const { document, reason } = await readConsumerJson(consumerRoot, advisory.detect.path);
|
|
151
|
+
if (reason) return false;
|
|
152
|
+
return hasDecision(document, advisory.detect.key);
|
|
153
|
+
}
|
|
154
|
+
|
|
129
155
|
/**
|
|
130
156
|
* Report every registered migration the consumer still owes for `kitVersion`.
|
|
131
157
|
* Read-only by construction: an outstanding decision is named, never written —
|
|
@@ -155,7 +181,36 @@ export async function evaluateConsumerMigrations({ consumerRoot, kitVersion, reg
|
|
|
155
181
|
return pending;
|
|
156
182
|
}
|
|
157
183
|
|
|
184
|
+
/**
|
|
185
|
+
* Report obsolete consumer-owned configuration without mutating it. Advisory
|
|
186
|
+
* evaluation is fail-open: absent or unreadable project-layer evidence cannot
|
|
187
|
+
* prove that a retired key is present.
|
|
188
|
+
*/
|
|
189
|
+
export async function evaluateConsumerAdvisories({ consumerRoot, kitVersion, registry }) {
|
|
190
|
+
const source = registry ? validateConsumerMigrationRegistry(registry)
|
|
191
|
+
: await readShippedConsumerMigrationRegistry();
|
|
192
|
+
const advisories = [];
|
|
193
|
+
for (const advisory of source.advisories) {
|
|
194
|
+
if (compareSemver(kitVersion, advisory.retiredIn) < 0) continue;
|
|
195
|
+
if (!(await detectPresent(consumerRoot, advisory))) continue;
|
|
196
|
+
advisories.push({
|
|
197
|
+
id: advisory.id,
|
|
198
|
+
state: 'advisory',
|
|
199
|
+
kind: advisory.kind,
|
|
200
|
+
retiredIn: advisory.retiredIn,
|
|
201
|
+
path: advisory.detect.path,
|
|
202
|
+
key: advisory.detect.key.join('.'),
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
return advisories;
|
|
206
|
+
}
|
|
207
|
+
|
|
158
208
|
/** One rendering of the shared record, used by every human-facing update surface. */
|
|
159
209
|
export function renderRequiredMigration({ id, workflow, path, decision }) {
|
|
160
210
|
return `required migration: ${id} · ${workflow} · ${path} · ${decision}`;
|
|
161
211
|
}
|
|
212
|
+
|
|
213
|
+
export function renderConsumerAdvisory({ key, retiredIn }) {
|
|
214
|
+
return `update advisory: ${key} is no longer read since ${retiredIn}; `
|
|
215
|
+
+ 'the key is consumer-owned and safe to delete.';
|
|
216
|
+
}
|