@noodleseed/one 0.71.0 → 0.73.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/dist/agent-skills-state.d.ts +40 -0
- package/dist/agent-skills-state.d.ts.map +1 -0
- package/dist/agent-skills-state.js +184 -0
- package/dist/agent-skills-state.js.map +1 -0
- package/dist/agents.d.ts +15 -4
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +196 -76
- package/dist/agents.js.map +1 -1
- package/dist/auth-discovery.d.ts +2 -0
- package/dist/auth-discovery.d.ts.map +1 -1
- package/dist/auth-discovery.js +63 -4
- package/dist/auth-discovery.js.map +1 -1
- package/dist/bin.js +0 -0
- package/dist/commands/catalog-data-config.d.ts.map +1 -1
- package/dist/commands/catalog-data-config.js +10 -1
- package/dist/commands/catalog-data-config.js.map +1 -1
- package/dist/commands/catalog-data-resources.d.ts.map +1 -1
- package/dist/commands/catalog-data-resources.js +5 -5
- package/dist/commands/catalog-data-resources.js.map +1 -1
- package/dist/commands/config-values.d.ts +10 -2
- package/dist/commands/config-values.d.ts.map +1 -1
- package/dist/commands/config-values.js +81 -1
- package/dist/commands/config-values.js.map +1 -1
- package/dist/skills-update.d.ts +1 -0
- package/dist/skills-update.d.ts.map +1 -1
- package/dist/skills-update.js +81 -5
- package/dist/skills-update.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/behavior-skills.d.ts +20 -0
- package/node_modules/@noodle-borg/agent-kit/dist/behavior-skills.d.ts.map +1 -0
- package/node_modules/@noodle-borg/agent-kit/dist/behavior-skills.js +280 -0
- package/node_modules/@noodle-borg/agent-kit/dist/behavior-skills.js.map +1 -0
- package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/index.d.ts +18 -4
- package/node_modules/@noodle-borg/agent-kit/dist/index.d.ts.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/index.js +57 -46
- package/node_modules/@noodle-borg/agent-kit/dist/index.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-feedback-ref.js +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-feedback-ref.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-registry.d.ts +31 -0
- package/node_modules/@noodle-borg/agent-kit/dist/skill-registry.d.ts.map +1 -0
- package/node_modules/@noodle-borg/agent-kit/dist/skill-registry.js +116 -0
- package/node_modules/@noodle-borg/agent-kit/dist/skill-registry.js.map +1 -0
- package/node_modules/@noodle-borg/agent-kit/dist/skill-router.d.ts +3 -3
- package/node_modules/@noodle-borg/agent-kit/dist/skill-router.d.ts.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-router.js +35 -25
- package/node_modules/@noodle-borg/agent-kit/dist/skill-router.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
- package/node_modules/@noodle-borg/auth/dist/jwt-issuer.d.ts +2 -0
- package/node_modules/@noodle-borg/auth/dist/jwt-issuer.d.ts.map +1 -1
- package/node_modules/@noodle-borg/auth/dist/jwt-issuer.js +1 -0
- package/node_modules/@noodle-borg/auth/dist/jwt-issuer.js.map +1 -1
- package/node_modules/@noodle-borg/auth/dist/verify.d.ts +2 -0
- package/node_modules/@noodle-borg/auth/dist/verify.d.ts.map +1 -1
- package/node_modules/@noodle-borg/auth/dist/verify.js +16 -0
- package/node_modules/@noodle-borg/auth/dist/verify.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/auth/deploy-gate.d.ts +3 -0
- package/node_modules/@noodle-borg/service/dist/auth/deploy-gate.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/auth/deploy-gate.js +1 -0
- package/node_modules/@noodle-borg/service/dist/auth/deploy-gate.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/config-value-projection.d.ts +58 -0
- package/node_modules/@noodle-borg/service/dist/config-value-projection.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/config-value-projection.js +40 -0
- package/node_modules/@noodle-borg/service/dist/config-value-projection.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/authorization-initiation.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/authorization-initiation.js +4 -0
- package/node_modules/@noodle-borg/service/dist/oauth/authorization-initiation.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/consent-claims.d.ts +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/consent-claims.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/consent-claims.js +10 -0
- package/node_modules/@noodle-borg/service/dist/oauth/consent-claims.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-flow.d.ts +3 -1
- package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-flow.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-flow.js +2 -0
- package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-flow.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/fresh-auth.d.ts +6 -0
- package/node_modules/@noodle-borg/service/dist/oauth/fresh-auth.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/fresh-auth.js +14 -0
- package/node_modules/@noodle-borg/service/dist/oauth/fresh-auth.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/google.d.ts +3 -2
- package/node_modules/@noodle-borg/service/dist/oauth/google.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/google.js +8 -4
- package/node_modules/@noodle-borg/service/dist/oauth/google.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/provider.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/provider.js +7 -2
- package/node_modules/@noodle-borg/service/dist/oauth/provider.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/store-postgres-schema.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/store-postgres-schema.js +4 -0
- package/node_modules/@noodle-borg/service/dist/oauth/store-postgres-schema.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/store-postgres.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/store-postgres.js +36 -12
- package/node_modules/@noodle-borg/service/dist/oauth/store-postgres.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/store.d.ts +3 -0
- package/node_modules/@noodle-borg/service/dist/oauth/store.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/store.js +19 -7
- package/node_modules/@noodle-borg/service/dist/oauth/store.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/token-issuer.d.ts +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/token-issuer.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/token-issuer.js +13 -5
- package/node_modules/@noodle-borg/service/dist/oauth/token-issuer.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-callback-handler.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-callback-handler.js +5 -0
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-callback-handler.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-consent.d.ts +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-consent.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-consent.js +33 -21
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-consent.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-federation.d.ts +2 -1
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-federation.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-federation.js +2 -2
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-federation.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-human.d.ts +4 -1
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-human.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-human.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-provider-choice.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-provider-choice.js +4 -0
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-provider-choice.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/workos.d.ts +4 -2
- package/node_modules/@noodle-borg/service/dist/oauth/workos.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/workos.js +5 -3
- package/node_modules/@noodle-borg/service/dist/oauth/workos.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/auth-discovery.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/auth-discovery.js +46 -0
- package/node_modules/@noodle-borg/service/dist/routes/auth-discovery.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/config-contracts.d.ts +181 -0
- package/node_modules/@noodle-borg/service/dist/routes/config-contracts.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/config-contracts.js +50 -0
- package/node_modules/@noodle-borg/service/dist/routes/config-contracts.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/config-values-dispatch.d.ts +20 -0
- package/node_modules/@noodle-borg/service/dist/routes/config-values-dispatch.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/config-values-dispatch.js +37 -0
- package/node_modules/@noodle-borg/service/dist/routes/config-values-dispatch.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/config-values-paths.d.ts +12 -0
- package/node_modules/@noodle-borg/service/dist/routes/config-values-paths.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/config-values-paths.js +88 -0
- package/node_modules/@noodle-borg/service/dist/routes/config-values-paths.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/config-values.d.ts +8 -0
- package/node_modules/@noodle-borg/service/dist/routes/config-values.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/config-values.js +218 -0
- package/node_modules/@noodle-borg/service/dist/routes/config-values.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.d.ts +2 -3
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.js +2 -71
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/paths.d.ts +2 -9
- package/node_modules/@noodle-borg/service/dist/routes/paths.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/paths.js +2 -40
- package/node_modules/@noodle-borg/service/dist/routes/paths.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/service.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/service.js +15 -13
- package/node_modules/@noodle-borg/service/dist/service.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/config-values.d.ts +57 -0
- package/node_modules/@noodle-borg/service/dist/store/config-values.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store/config-values.js +98 -0
- package/node_modules/@noodle-borg/service/dist/store/config-values.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-config.d.ts +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-config.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-config.js +22 -3
- package/node_modules/@noodle-borg/service/dist/store/postgres-config.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres.d.ts +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres.js +2 -2
- package/node_modules/@noodle-borg/service/dist/store/postgres.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store.d.ts +1 -56
- package/node_modules/@noodle-borg/service/dist/store.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store.js +1 -84
- package/node_modules/@noodle-borg/service/dist/store.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type AgentTarget } from '@noodle-borg/agent-kit';
|
|
2
|
+
export interface ManagedSkillFileInput {
|
|
3
|
+
readonly path: string;
|
|
4
|
+
readonly content: string;
|
|
5
|
+
readonly skill: string;
|
|
6
|
+
readonly skillVersion: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ManagedSkillFileAction {
|
|
9
|
+
readonly path: string;
|
|
10
|
+
readonly target: AgentTarget;
|
|
11
|
+
readonly action: 'created' | 'unchanged' | 'overwritten' | 'removed' | 'skipped';
|
|
12
|
+
readonly reason?: 'user-edited-removed-generated-file';
|
|
13
|
+
}
|
|
14
|
+
export interface ManagedSkillStateFile {
|
|
15
|
+
readonly path: string;
|
|
16
|
+
readonly sha256: string;
|
|
17
|
+
readonly skill: string;
|
|
18
|
+
readonly skillVersion: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ManagedSkillState {
|
|
21
|
+
readonly schemaVersion: 1;
|
|
22
|
+
readonly packageVersion: string;
|
|
23
|
+
readonly target: AgentTarget;
|
|
24
|
+
readonly files: readonly ManagedSkillStateFile[];
|
|
25
|
+
}
|
|
26
|
+
export declare function managedSkillsStatePath(target: AgentTarget): string;
|
|
27
|
+
export declare function assertManagedSkillFilesSafe(input: {
|
|
28
|
+
readonly project: string;
|
|
29
|
+
readonly target: AgentTarget;
|
|
30
|
+
readonly files: readonly Pick<ManagedSkillFileInput, 'path'>[];
|
|
31
|
+
}): void;
|
|
32
|
+
export declare function reconcileManagedSkillFiles(input: {
|
|
33
|
+
readonly project: string;
|
|
34
|
+
readonly target: AgentTarget;
|
|
35
|
+
readonly packageVersion: string;
|
|
36
|
+
readonly files: readonly ManagedSkillFileInput[];
|
|
37
|
+
readonly write: boolean;
|
|
38
|
+
}): readonly ManagedSkillFileAction[];
|
|
39
|
+
export declare function readManagedSkillState(project: string, target: AgentTarget): ManagedSkillState | undefined;
|
|
40
|
+
//# sourceMappingURL=agent-skills-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-skills-state.d.ts","sourceRoot":"","sources":["../src/agent-skills-state.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,WAAW,EAAiB,MAAM,wBAAwB,CAAC;AAEzE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,aAAa,GAAG,SAAS,GAAG,SAAS,CAAC;IACjF,QAAQ,CAAC,MAAM,CAAC,EAAE,oCAAoC,CAAC;CACxD;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAClD;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAElE;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,EAAE,CAAC;CAChE,GAAG,IAAI,CASP;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IAChD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACjD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB,GAAG,SAAS,sBAAsB,EAAE,CAmEpC;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,WAAW,GAClB,iBAAiB,GAAG,SAAS,CAE/B"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { existsSync, lstatSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync, } from 'node:fs';
|
|
3
|
+
import { dirname, join, resolve } from 'node:path';
|
|
4
|
+
import { contentSha256 } from '@noodle-borg/agent-kit';
|
|
5
|
+
export function managedSkillsStatePath(target) {
|
|
6
|
+
return `${skillRoot(target)}/.noodle-managed.json`;
|
|
7
|
+
}
|
|
8
|
+
export function assertManagedSkillFilesSafe(input) {
|
|
9
|
+
assertManagedPathSafe(input.project, skillRoot(input.target));
|
|
10
|
+
assertManagedPathSafe(input.project, managedSkillsStatePath(input.target));
|
|
11
|
+
for (const file of input.files) {
|
|
12
|
+
if (!isOwnedPath(input.target, file.path)) {
|
|
13
|
+
throw new Error(`invalid managed skill path: ${file.path}`);
|
|
14
|
+
}
|
|
15
|
+
assertManagedPathSafe(input.project, file.path);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function reconcileManagedSkillFiles(input) {
|
|
19
|
+
const files = validateInputs(input.target, input.files);
|
|
20
|
+
if (input.write) {
|
|
21
|
+
assertManagedSkillFilesSafe({
|
|
22
|
+
project: input.project,
|
|
23
|
+
target: input.target,
|
|
24
|
+
files,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const nextPaths = new Set(files.map((file) => file.path));
|
|
28
|
+
const previous = readState(input.project, input.target);
|
|
29
|
+
if (input.write && previous !== undefined) {
|
|
30
|
+
for (const file of previous.files)
|
|
31
|
+
assertManagedPathSafe(input.project, file.path);
|
|
32
|
+
}
|
|
33
|
+
const actions = files.map((file) => {
|
|
34
|
+
const full = join(input.project, file.path);
|
|
35
|
+
const existing = existsSync(full) ? readFileSync(full, 'utf8') : undefined;
|
|
36
|
+
return {
|
|
37
|
+
path: file.path,
|
|
38
|
+
target: input.target,
|
|
39
|
+
action: existing === undefined
|
|
40
|
+
? 'created'
|
|
41
|
+
: existing === file.content
|
|
42
|
+
? 'unchanged'
|
|
43
|
+
: 'overwritten',
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
const removable = [];
|
|
47
|
+
for (const file of previous?.files ?? []) {
|
|
48
|
+
if (nextPaths.has(file.path) || !isOwnedPath(input.target, file.path))
|
|
49
|
+
continue;
|
|
50
|
+
const full = join(input.project, file.path);
|
|
51
|
+
if (!existsSync(full))
|
|
52
|
+
continue;
|
|
53
|
+
if (contentSha256(readFileSync(full, 'utf8')) === file.sha256) {
|
|
54
|
+
removable.push(file.path);
|
|
55
|
+
actions.push({ path: file.path, target: input.target, action: 'removed' });
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
actions.push({
|
|
59
|
+
path: file.path,
|
|
60
|
+
target: input.target,
|
|
61
|
+
action: 'skipped',
|
|
62
|
+
reason: 'user-edited-removed-generated-file',
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (!input.write)
|
|
67
|
+
return actions;
|
|
68
|
+
for (const file of files) {
|
|
69
|
+
const action = actions.find((candidate) => candidate.path === file.path)?.action;
|
|
70
|
+
if (action !== 'unchanged')
|
|
71
|
+
atomicWrite(join(input.project, file.path), file.content);
|
|
72
|
+
}
|
|
73
|
+
for (const path of removable)
|
|
74
|
+
rmSync(join(input.project, path), { force: true });
|
|
75
|
+
const state = {
|
|
76
|
+
schemaVersion: 1,
|
|
77
|
+
packageVersion: input.packageVersion,
|
|
78
|
+
target: input.target,
|
|
79
|
+
files: files.map((file) => ({
|
|
80
|
+
path: file.path,
|
|
81
|
+
sha256: contentSha256(file.content),
|
|
82
|
+
skill: file.skill,
|
|
83
|
+
skillVersion: file.skillVersion,
|
|
84
|
+
})),
|
|
85
|
+
};
|
|
86
|
+
atomicWrite(join(input.project, managedSkillsStatePath(input.target)), `${JSON.stringify(state, null, 2)}\n`);
|
|
87
|
+
return actions;
|
|
88
|
+
}
|
|
89
|
+
export function readManagedSkillState(project, target) {
|
|
90
|
+
return readState(project, target);
|
|
91
|
+
}
|
|
92
|
+
function validateInputs(target, files) {
|
|
93
|
+
const paths = new Set();
|
|
94
|
+
for (const file of files) {
|
|
95
|
+
if (!isOwnedPath(target, file.path) || paths.has(file.path)) {
|
|
96
|
+
throw new Error(`invalid or duplicate managed skill path: ${file.path}`);
|
|
97
|
+
}
|
|
98
|
+
if (!file.path.startsWith(`${skillRoot(target)}/${file.skill}/`)) {
|
|
99
|
+
throw new Error(`managed skill identity does not match path: ${file.path}`);
|
|
100
|
+
}
|
|
101
|
+
paths.add(file.path);
|
|
102
|
+
}
|
|
103
|
+
return files;
|
|
104
|
+
}
|
|
105
|
+
function readState(project, target) {
|
|
106
|
+
try {
|
|
107
|
+
const value = JSON.parse(readFileSync(join(project, managedSkillsStatePath(target)), 'utf8'));
|
|
108
|
+
if (!isRecord(value) || value.schemaVersion !== 1 || value.target !== target)
|
|
109
|
+
return undefined;
|
|
110
|
+
if (typeof value.packageVersion !== 'string' || !Array.isArray(value.files))
|
|
111
|
+
return undefined;
|
|
112
|
+
const files = [];
|
|
113
|
+
const paths = new Set();
|
|
114
|
+
for (const file of value.files) {
|
|
115
|
+
if (!isRecord(file) ||
|
|
116
|
+
typeof file.path !== 'string' ||
|
|
117
|
+
typeof file.sha256 !== 'string' ||
|
|
118
|
+
typeof file.skill !== 'string' ||
|
|
119
|
+
typeof file.skillVersion !== 'string' ||
|
|
120
|
+
!/^[a-f0-9]{64}$/.test(file.sha256) ||
|
|
121
|
+
!isOwnedPath(target, file.path) ||
|
|
122
|
+
paths.has(file.path)) {
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
paths.add(file.path);
|
|
126
|
+
files.push({
|
|
127
|
+
path: file.path,
|
|
128
|
+
sha256: file.sha256,
|
|
129
|
+
skill: file.skill,
|
|
130
|
+
skillVersion: file.skillVersion,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
return { schemaVersion: 1, packageVersion: value.packageVersion, target, files };
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function atomicWrite(path, content) {
|
|
140
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
141
|
+
const temporary = `${path}.tmp-${process.pid}-${randomUUID()}`;
|
|
142
|
+
writeFileSync(temporary, content);
|
|
143
|
+
renameSync(temporary, path);
|
|
144
|
+
}
|
|
145
|
+
function assertManagedPathSafe(project, relativePath) {
|
|
146
|
+
const absoluteProject = resolve(project);
|
|
147
|
+
const segments = relativePath.split('/');
|
|
148
|
+
let current = absoluteProject;
|
|
149
|
+
for (let index = 0; index <= segments.length; index += 1) {
|
|
150
|
+
const stats = lstatIfPresent(current);
|
|
151
|
+
if (stats?.isSymbolicLink()) {
|
|
152
|
+
throw new Error(`refusing managed skill path with symbolic link: ${current}`);
|
|
153
|
+
}
|
|
154
|
+
if (index < segments.length && stats !== undefined && !stats.isDirectory()) {
|
|
155
|
+
throw new Error(`refusing managed skill path with non-directory ancestor: ${current}`);
|
|
156
|
+
}
|
|
157
|
+
if (index < segments.length)
|
|
158
|
+
current = join(current, segments[index] ?? '');
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function lstatIfPresent(path) {
|
|
162
|
+
try {
|
|
163
|
+
return lstatSync(path);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
if (isRecord(error) && error.code === 'ENOENT')
|
|
167
|
+
return undefined;
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
function skillRoot(target) {
|
|
172
|
+
return target === 'codex' ? '.agents/skills' : '.claude/skills';
|
|
173
|
+
}
|
|
174
|
+
function isOwnedPath(target, path) {
|
|
175
|
+
const prefix = `${skillRoot(target)}/`;
|
|
176
|
+
return (path.startsWith(prefix) &&
|
|
177
|
+
!path.includes('\\') &&
|
|
178
|
+
path.split('/').every((segment) => segment !== '' && segment !== '.' && segment !== '..') &&
|
|
179
|
+
path !== managedSkillsStatePath(target));
|
|
180
|
+
}
|
|
181
|
+
function isRecord(value) {
|
|
182
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=agent-skills-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-skills-state.js","sourceRoot":"","sources":["../src/agent-skills-state.ts"],"names":[],"mappings":"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"}
|
package/dist/agents.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AgentTarget } from '@noodle-borg/agent-kit';
|
|
1
|
+
import { type AgentTarget, type SkillRegistry } from '@noodle-borg/agent-kit';
|
|
2
2
|
import { type JsonError } from './commands/output.js';
|
|
3
3
|
import { type ConfigLocation } from './config.js';
|
|
4
4
|
interface AgentArgs {
|
|
@@ -14,13 +14,24 @@ interface AgentArgs {
|
|
|
14
14
|
type ResolvedAgentArgs = AgentArgs & {
|
|
15
15
|
readonly agents: readonly AgentTarget[];
|
|
16
16
|
};
|
|
17
|
-
type AgentSetupInput = Omit<ResolvedAgentArgs, 'action' | 'refresh'> & {
|
|
18
|
-
readonly skillsOverride?:
|
|
17
|
+
export type AgentSetupInput = Omit<ResolvedAgentArgs, 'action' | 'refresh'> & {
|
|
18
|
+
readonly skillsOverride?: ResolvedSkillsSnapshot;
|
|
19
|
+
readonly registry?: SkillRegistry;
|
|
19
20
|
};
|
|
21
|
+
export interface ResolvedSkillsSnapshot {
|
|
22
|
+
readonly packageVersion: string;
|
|
23
|
+
readonly files: readonly {
|
|
24
|
+
readonly path: string;
|
|
25
|
+
readonly content: string;
|
|
26
|
+
readonly target: AgentTarget;
|
|
27
|
+
readonly skill: string;
|
|
28
|
+
readonly skillVersion: string;
|
|
29
|
+
}[];
|
|
30
|
+
}
|
|
20
31
|
export interface AgentFileAction {
|
|
21
32
|
readonly path: string;
|
|
22
33
|
readonly target: AgentTarget;
|
|
23
|
-
readonly action: 'created' | 'unchanged' | 'updated' | 'skipped' | 'overwritten';
|
|
34
|
+
readonly action: 'created' | 'unchanged' | 'updated' | 'skipped' | 'overwritten' | 'removed';
|
|
24
35
|
readonly reason?: string;
|
|
25
36
|
}
|
|
26
37
|
export interface AgentSetupReport {
|
package/dist/agents.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"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"}
|
package/dist/agents.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { delimiter, dirname, join, resolve } from 'node:path';
|
|
3
|
-
import { AGENT_KIT_VERSION, contentSha256, parseAgentTargets, reconcileManagedBlock, renderAgentFiles,
|
|
3
|
+
import { AGENT_KIT_VERSION, contentSha256, parseAgentTargets, reconcileManagedBlock, renderAgentFiles, } from '@noodle-borg/agent-kit';
|
|
4
|
+
import { assertManagedSkillFilesSafe, readManagedSkillState, reconcileManagedSkillFiles, } from './agent-skills-state.js';
|
|
4
5
|
import { printJsonFailure, printJsonOk } from './commands/output.js';
|
|
5
6
|
import { configDir, readConfig } from './config.js';
|
|
6
7
|
import { readPluginCompatibility } from './plugin-mode/compatibility.js';
|
|
@@ -35,27 +36,28 @@ export async function runAgents(rest, env = process.env, configLocation) {
|
|
|
35
36
|
return 2;
|
|
36
37
|
}
|
|
37
38
|
export function setupAgents(args) {
|
|
38
|
-
const projectDefaults = readResolvedProjectConfig(args.project);
|
|
39
|
-
const link = readProjectLink(args.project);
|
|
40
|
-
const org = link?.org ?? projectDefaults.org;
|
|
41
|
-
const app = link?.app ?? projectDefaults.app;
|
|
42
39
|
const planned = renderAgentFiles({
|
|
43
40
|
targets: args.agents,
|
|
44
|
-
|
|
41
|
+
...(args.registry !== undefined ? { registry: args.registry } : {}),
|
|
42
|
+
project: resolveAgentProjectMetadata(args.project),
|
|
45
43
|
});
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
44
|
+
// A registry-fresh snapshot replaces the bundled generated tree as one complete unit. The managed
|
|
45
|
+
// host block stays bundled because it is project-specific.
|
|
46
|
+
const generatedFiles = args.skillsOverride === undefined
|
|
47
|
+
? planned.filter((file) => file.mode === 'generated-file')
|
|
48
|
+
: args.skillsOverride.files.filter((file) => args.agents.includes(file.target));
|
|
49
|
+
validateResolvedSkillsSnapshot(args.agents, generatedFiles);
|
|
50
|
+
if (args.write) {
|
|
51
|
+
for (const target of args.agents) {
|
|
52
|
+
assertManagedSkillFilesSafe({
|
|
53
|
+
project: args.project,
|
|
54
|
+
target,
|
|
55
|
+
files: generatedFiles.filter((file) => file.target === target),
|
|
56
|
+
});
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
59
|
const files = [];
|
|
58
|
-
for (const file of planned) {
|
|
60
|
+
for (const file of planned.filter((candidate) => candidate.mode === 'managed-block')) {
|
|
59
61
|
const full = join(args.project, file.path);
|
|
60
62
|
const existing = existsSync(full) ? readFileSync(full, 'utf8') : undefined;
|
|
61
63
|
if (!args.write) {
|
|
@@ -66,35 +68,38 @@ export function setupAgents(args) {
|
|
|
66
68
|
});
|
|
67
69
|
continue;
|
|
68
70
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (
|
|
71
|
+
const result = reconcileManagedBlock({
|
|
72
|
+
...(existing !== undefined ? { existing } : {}),
|
|
73
|
+
block: file.content,
|
|
74
|
+
force: args.force,
|
|
75
|
+
});
|
|
76
|
+
if (result.action !== 'unchanged' && result.action !== 'skipped') {
|
|
77
|
+
if (args.write) {
|
|
76
78
|
mkdirSync(dirname(full), { recursive: true });
|
|
77
79
|
writeFileSync(full, result.content);
|
|
78
80
|
}
|
|
79
|
-
files.push({
|
|
80
|
-
path: file.path,
|
|
81
|
-
target: file.target,
|
|
82
|
-
action: result.action,
|
|
83
|
-
...(result.reason !== undefined ? { reason: result.reason } : {}),
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
const action = existing === undefined
|
|
88
|
-
? 'created'
|
|
89
|
-
: existing === file.content
|
|
90
|
-
? 'unchanged'
|
|
91
|
-
: 'overwritten';
|
|
92
|
-
if (action !== 'unchanged') {
|
|
93
|
-
mkdirSync(dirname(full), { recursive: true });
|
|
94
|
-
writeFileSync(full, file.content);
|
|
95
|
-
}
|
|
96
|
-
files.push({ path: file.path, target: file.target, action });
|
|
97
81
|
}
|
|
82
|
+
files.push({
|
|
83
|
+
path: file.path,
|
|
84
|
+
target: file.target,
|
|
85
|
+
action: result.action,
|
|
86
|
+
...(result.reason !== undefined ? { reason: result.reason } : {}),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
for (const target of args.agents) {
|
|
90
|
+
const generated = generatedFiles.filter((file) => file.target === target);
|
|
91
|
+
files.push(...reconcileManagedSkillFiles({
|
|
92
|
+
project: args.project,
|
|
93
|
+
target,
|
|
94
|
+
packageVersion: args.skillsOverride?.packageVersion ?? AGENT_KIT_VERSION,
|
|
95
|
+
files: generated.map((file) => ({
|
|
96
|
+
path: file.path,
|
|
97
|
+
content: file.content,
|
|
98
|
+
skill: file.skill ?? failMissingSkillIdentity(file.path),
|
|
99
|
+
skillVersion: file.skillVersion ?? failMissingSkillIdentity(file.path),
|
|
100
|
+
})),
|
|
101
|
+
write: args.write,
|
|
102
|
+
}));
|
|
98
103
|
}
|
|
99
104
|
return {
|
|
100
105
|
ok: true,
|
|
@@ -107,6 +112,44 @@ export function setupAgents(args) {
|
|
|
107
112
|
: [],
|
|
108
113
|
};
|
|
109
114
|
}
|
|
115
|
+
function resolveAgentProjectMetadata(project) {
|
|
116
|
+
const projectDefaults = readResolvedProjectConfig(project);
|
|
117
|
+
const link = readProjectLink(project);
|
|
118
|
+
const org = link?.org ?? projectDefaults.org;
|
|
119
|
+
const app = link?.app ?? projectDefaults.app;
|
|
120
|
+
return Object.assign({}, projectDefaults.name !== undefined ? { name: projectDefaults.name } : {}, projectDefaults.entrypoint !== undefined ? { entrypoint: projectDefaults.entrypoint } : {}, projectDefaults.env !== undefined ? { env: projectDefaults.env } : {}, projectDefaults.accessMode !== undefined ? { accessMode: projectDefaults.accessMode } : {}, projectDefaults.template !== undefined ? { template: projectDefaults.template } : {}, org !== undefined ? { org } : {}, app !== undefined ? { app } : {});
|
|
121
|
+
}
|
|
122
|
+
function validateResolvedSkillsSnapshot(targets, files) {
|
|
123
|
+
const paths = new Set();
|
|
124
|
+
for (const file of files) {
|
|
125
|
+
const expectedRoot = `${file.target === 'codex' ? '.agents' : '.claude'}/skills/${file.skill ?? ''}/`;
|
|
126
|
+
if (file.skill === undefined ||
|
|
127
|
+
!file.path.startsWith(expectedRoot) ||
|
|
128
|
+
file.path.includes('\\') ||
|
|
129
|
+
file.path
|
|
130
|
+
.split('/')
|
|
131
|
+
.some((segment) => segment === '' || segment === '.' || segment === '..') ||
|
|
132
|
+
paths.has(file.path)) {
|
|
133
|
+
throw new Error(`resolved skill snapshot has invalid or duplicate path: ${file.path}`);
|
|
134
|
+
}
|
|
135
|
+
paths.add(file.path);
|
|
136
|
+
}
|
|
137
|
+
for (const target of targets) {
|
|
138
|
+
const targetFiles = files.filter((file) => file.target === target);
|
|
139
|
+
if (targetFiles.length === 0)
|
|
140
|
+
throw new Error(`resolved skill snapshot is missing ${target}`);
|
|
141
|
+
const skills = new Set(targetFiles.map((file) => file.skill));
|
|
142
|
+
for (const skill of skills) {
|
|
143
|
+
if (skill === undefined ||
|
|
144
|
+
!targetFiles.some((file) => file.skill === skill && file.path.endsWith(`/skills/${skill}/SKILL.md`))) {
|
|
145
|
+
throw new Error(`resolved skill snapshot is missing SKILL.md for ${target}/${skill ?? '?'}`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function failMissingSkillIdentity(path) {
|
|
151
|
+
throw new Error(`generated skill file is missing registry identity: ${path}`);
|
|
152
|
+
}
|
|
110
153
|
/** Resolve the active Agent Kit profile before rendering any project agent files. */
|
|
111
154
|
export async function setupAgentsWithResolvedSkills(args, env = process.env, configLocation) {
|
|
112
155
|
// Interactive writes may fetch registry-latest, while plugin mode resolves the exact compatibility pin.
|
|
@@ -175,17 +218,20 @@ async function resolveSkillsOverride(refresh, configLocation, pluginRequiredVers
|
|
|
175
218
|
});
|
|
176
219
|
if (result.status !== 'ready' || result.kit === undefined)
|
|
177
220
|
return undefined;
|
|
178
|
-
|
|
179
|
-
// destination so the override replaces every file in the tree, not just the SKILL.md.
|
|
180
|
-
const installedByPublish = new Map(skillFileMappings().map((m) => [m.publishPath, m.installedPath]));
|
|
181
|
-
const override = new Map();
|
|
221
|
+
const files = [];
|
|
182
222
|
for (const file of result.kit.manifest.files) {
|
|
183
223
|
const content = result.kit.files.get(file.path);
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
224
|
+
if (content === undefined)
|
|
225
|
+
return undefined;
|
|
226
|
+
files.push({
|
|
227
|
+
path: file.installedPath,
|
|
228
|
+
content,
|
|
229
|
+
target: file.agentTarget,
|
|
230
|
+
skill: file.skill,
|
|
231
|
+
skillVersion: file.skillVersion,
|
|
232
|
+
});
|
|
187
233
|
}
|
|
188
|
-
return
|
|
234
|
+
return { packageVersion: result.kit.version, files };
|
|
189
235
|
}
|
|
190
236
|
async function runAgentDoctor(args, env, configLocation) {
|
|
191
237
|
const pluginRequiredVersion = pluginRequiredAgentKitVersion(env);
|
|
@@ -197,26 +243,64 @@ async function runAgentDoctor(args, env, configLocation) {
|
|
|
197
243
|
version: pluginRequiredVersion,
|
|
198
244
|
})
|
|
199
245
|
: undefined;
|
|
200
|
-
const
|
|
201
|
-
const pinnedExpectedByPath = new Map();
|
|
202
|
-
if (pluginPinnedKit !== undefined) {
|
|
203
|
-
for (const file of pluginPinnedKit.manifest.files) {
|
|
204
|
-
const installedPath = installedByPublish.get(file.path);
|
|
205
|
-
const content = pluginPinnedKit.files.get(file.path);
|
|
206
|
-
if (installedPath !== undefined && content !== undefined) {
|
|
207
|
-
pinnedExpectedByPath.set(installedPath, content);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
246
|
+
const projectMetadata = resolveAgentProjectMetadata(args.project);
|
|
211
247
|
const checks = args.agents.flatMap((target) => {
|
|
212
|
-
const
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
248
|
+
const bundled = renderAgentFiles({ targets: [target], project: projectMetadata });
|
|
249
|
+
const state = readManagedSkillState(args.project, target);
|
|
250
|
+
const useOwnedSnapshot = pluginPinnedKit === undefined &&
|
|
251
|
+
state !== undefined &&
|
|
252
|
+
state.packageVersion !== AGENT_KIT_VERSION;
|
|
253
|
+
const generatedBase = pluginPinnedKit !== undefined
|
|
254
|
+
? pluginPinnedKit.manifest.files
|
|
255
|
+
.filter((file) => file.agentTarget === target)
|
|
256
|
+
.map((file) => ({
|
|
257
|
+
path: file.installedPath,
|
|
258
|
+
mode: 'generated-file',
|
|
259
|
+
skill: file.skill,
|
|
260
|
+
skillVersion: file.skillVersion,
|
|
261
|
+
expectedSha256: file.sha256,
|
|
262
|
+
}))
|
|
263
|
+
: useOwnedSnapshot
|
|
264
|
+
? state.files.map((file) => ({
|
|
265
|
+
path: file.path,
|
|
266
|
+
mode: 'generated-file',
|
|
267
|
+
skill: file.skill,
|
|
268
|
+
skillVersion: file.skillVersion,
|
|
269
|
+
expectedSha256: file.sha256,
|
|
270
|
+
}))
|
|
271
|
+
: bundled
|
|
272
|
+
.filter((file) => file.mode === 'generated-file')
|
|
273
|
+
.map((file) => ({
|
|
274
|
+
path: file.path,
|
|
275
|
+
mode: file.mode,
|
|
276
|
+
skill: file.skill ?? failMissingSkillIdentity(file.path),
|
|
277
|
+
skillVersion: file.skillVersion ?? failMissingSkillIdentity(file.path),
|
|
278
|
+
expectedSha256: contentSha256(file.content),
|
|
279
|
+
}));
|
|
280
|
+
const generated = pluginPinnedKit === undefined && state !== undefined && !useOwnedSnapshot
|
|
281
|
+
? [
|
|
282
|
+
...generatedBase,
|
|
283
|
+
...state.files
|
|
284
|
+
.filter((file) => !generatedBase.some((candidate) => candidate.path === file.path))
|
|
285
|
+
.map((file) => ({
|
|
286
|
+
path: file.path,
|
|
287
|
+
mode: 'generated-file',
|
|
288
|
+
skill: file.skill,
|
|
289
|
+
skillVersion: file.skillVersion,
|
|
290
|
+
expectedSha256: file.sha256,
|
|
291
|
+
})),
|
|
292
|
+
]
|
|
293
|
+
: generatedBase;
|
|
294
|
+
const files = [
|
|
295
|
+
...bundled
|
|
296
|
+
.filter((file) => file.mode === 'managed-block')
|
|
297
|
+
.map((file) => ({
|
|
298
|
+
path: file.path,
|
|
299
|
+
mode: file.mode,
|
|
300
|
+
expectedContent: file.content,
|
|
301
|
+
})),
|
|
302
|
+
...generated,
|
|
303
|
+
];
|
|
220
304
|
const referenceBaselineAvailable = pluginRequiredVersion === undefined ||
|
|
221
305
|
pluginRequiredVersion === AGENT_KIT_VERSION ||
|
|
222
306
|
pluginPinnedKit !== undefined;
|
|
@@ -236,27 +320,64 @@ async function runAgentDoctor(args, env, configLocation) {
|
|
|
236
320
|
message: 'run noodle agents setup --write',
|
|
237
321
|
};
|
|
238
322
|
}
|
|
239
|
-
|
|
323
|
+
if (file.mode === 'managed-block' && file.expectedContent !== undefined) {
|
|
324
|
+
const reconciliation = reconcileManagedBlock({
|
|
325
|
+
existing: readFileSync(path, 'utf8'),
|
|
326
|
+
block: file.expectedContent.trimEnd(),
|
|
327
|
+
});
|
|
328
|
+
if (reconciliation.action !== 'unchanged') {
|
|
329
|
+
return {
|
|
330
|
+
name: file.path,
|
|
331
|
+
level: 'WARN',
|
|
332
|
+
message: 'modified or stale; run noodle agents setup --write',
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
const skillVersion = file.mode === 'generated-file' && file.skill !== undefined
|
|
337
|
+
? readInstalledSkillVersion(join(args.project, `${target === 'codex' ? '.agents' : '.claude'}/skills/${file.skill}/SKILL.md`))
|
|
338
|
+
: undefined;
|
|
240
339
|
if (file.mode === 'generated-file' && file.path.endsWith('/SKILL.md')) {
|
|
241
|
-
const
|
|
340
|
+
const comparisonVersion = pluginRequiredVersion ?? expectedSkillsVersion;
|
|
341
|
+
const pluginVersionMismatch = pluginRequiredVersion !== undefined && skillVersion !== pluginRequiredVersion;
|
|
242
342
|
const staleness = pluginVersionMismatch
|
|
243
343
|
? 'stale'
|
|
244
|
-
: skillStaleness(
|
|
344
|
+
: skillStaleness(skillVersion, comparisonVersion);
|
|
245
345
|
const expectedVersionLabel = pluginRequiredVersion !== undefined ? 'plugin-required' : 'registry';
|
|
346
|
+
if (staleness !== 'stale' && file.expectedSha256 !== undefined) {
|
|
347
|
+
const current = contentSha256(readFileSync(path, 'utf8')) === file.expectedSha256;
|
|
348
|
+
if (!current) {
|
|
349
|
+
return {
|
|
350
|
+
name: file.path,
|
|
351
|
+
level: 'WARN',
|
|
352
|
+
message: 'modified; run noodle agents setup --write',
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
}
|
|
246
356
|
return {
|
|
247
357
|
name: file.path,
|
|
248
358
|
level: staleness === 'stale' ? 'WARN' : 'PASS',
|
|
249
359
|
message: staleness === 'stale'
|
|
250
360
|
? pluginVersionMismatch
|
|
251
|
-
? `installed v${
|
|
252
|
-
: `installed v${
|
|
361
|
+
? `installed v${skillVersion ?? '?'} does not match ${expectedVersionLabel} v${comparisonVersion}`
|
|
362
|
+
: `installed v${skillVersion ?? '?'} is older than ${expectedVersionLabel} v${comparisonVersion}`
|
|
253
363
|
: staleness === 'current'
|
|
254
364
|
? `current`
|
|
255
365
|
: 'present',
|
|
256
366
|
};
|
|
257
367
|
}
|
|
258
368
|
if (file.mode === 'generated-file' &&
|
|
259
|
-
|
|
369
|
+
!file.path.endsWith('/SKILL.md') &&
|
|
370
|
+
pluginRequiredVersion !== undefined &&
|
|
371
|
+
pluginPinnedKit === undefined &&
|
|
372
|
+
skillVersion === pluginRequiredVersion) {
|
|
373
|
+
return {
|
|
374
|
+
name: file.path,
|
|
375
|
+
level: 'WARN',
|
|
376
|
+
message: `plugin-required v${pluginRequiredVersion} cache unavailable; run noodle agents setup --write`,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
if (file.mode === 'generated-file' &&
|
|
380
|
+
skillVersion === file.skillVersion &&
|
|
260
381
|
!file.path.endsWith('/SKILL.md')) {
|
|
261
382
|
if (!referenceBaselineAvailable) {
|
|
262
383
|
return {
|
|
@@ -265,9 +386,8 @@ async function runAgentDoctor(args, env, configLocation) {
|
|
|
265
386
|
message: `plugin-required v${pluginRequiredVersion} cache unavailable; run noodle agents setup --write`,
|
|
266
387
|
};
|
|
267
388
|
}
|
|
268
|
-
const expected = expectedByPath.get(file.path);
|
|
269
389
|
const actual = readFileSync(path, 'utf8');
|
|
270
|
-
const current =
|
|
390
|
+
const current = file.expectedSha256 !== undefined && contentSha256(actual) === file.expectedSha256;
|
|
271
391
|
return {
|
|
272
392
|
name: file.path,
|
|
273
393
|
level: current ? 'PASS' : 'WARN',
|