@open-agent-toolkit/cli 0.3.15 → 0.3.17
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/assets/NOTICES.md +48 -0
- package/assets/agents/oat-phase-implementer.md +26 -6
- package/assets/agents/oat-reviewer.md +51 -1
- package/assets/bundle-metadata.json +1 -1
- package/assets/docs/contributing/documentation.md +4 -0
- package/assets/docs/contributing/skills.md +3 -1
- package/assets/docs/getting-started/bootstrap.md +1 -1
- package/assets/docs/getting-started/index.md +0 -4
- package/assets/docs/getting-started/tool-packs.md +0 -7
- package/assets/docs/provider-sync/commands.md +21 -0
- package/assets/docs/reference/cli-reference.md +44 -2
- package/assets/docs/reference/config-and-local-state.md +11 -2
- package/assets/docs/reference/configuration.md +10 -2
- package/assets/docs/reference/project-artifacts.md +43 -8
- package/assets/docs/skills/index.md +1 -0
- package/assets/docs/skills/recon.md +8 -5
- package/assets/docs/skills/repo-improve.md +9 -7
- package/assets/docs/workflows/advanced/autonomy.md +50 -0
- package/assets/docs/workflows/advanced/workflow-gates.md +109 -10
- package/assets/docs/workflows/approvals-and-automation.md +3 -1
- package/assets/docs/workflows/backlog-and-planning/backlog-lifecycle.md +25 -24
- package/assets/docs/workflows/backlog-and-planning/remote-project-management.md +0 -7
- package/assets/docs/workflows/ideas/lifecycle.md +2 -7
- package/assets/docs/workflows/projects/closeout/closeout-skills.md +62 -1
- package/assets/docs/workflows/projects/execution/implementation-execution.md +23 -3
- package/assets/docs/workflows/projects/execution/project-log.md +6 -0
- package/assets/docs/workflows/projects/lifecycle.md +7 -0
- package/assets/docs/workflows/projects/reviews/index.md +63 -1
- package/assets/docs/workflows/projects/reviews/review-flavors.md +8 -0
- package/assets/docs/workflows/waves/wave-workflows.md +11 -3
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-agent-instructions-apply/SKILL.md +14 -4
- package/assets/skills/oat-brainstorm/SKILL.md +17 -13
- package/assets/skills/oat-docs-apply/SKILL.md +13 -3
- package/assets/skills/oat-doctor/SKILL.md +11 -1
- package/assets/skills/oat-explainer-kit/SKILL.md +1 -1
- package/assets/skills/oat-explainer-kit/references/lifecycle-contract.md +6 -3
- package/assets/skills/oat-pjm-review-backlog/SKILL.md +2 -2
- package/assets/skills/oat-pjm-update-repo-reference/SKILL.md +28 -3
- package/assets/skills/oat-project-autonomous/SKILL.md +60 -5
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +210 -165
- package/assets/skills/oat-project-capture/SKILL.md +7 -3
- package/assets/skills/oat-project-complete/SKILL.md +39 -34
- package/assets/skills/oat-project-complete/scripts/execute-synced-archive-entry.mjs +106 -28
- package/assets/skills/oat-project-complete/scripts/parse-synced-archive-resume-fields.mjs +30 -3
- package/assets/skills/oat-project-complete-auto/SKILL.md +388 -0
- package/assets/skills/oat-project-design/SKILL.md +12 -9
- package/assets/skills/oat-project-discover/SKILL.md +8 -4
- package/assets/skills/oat-project-document/SKILL.md +14 -5
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +210 -165
- package/assets/skills/oat-project-implement/SKILL.md +6 -1
- package/assets/skills/oat-project-implement/references/completion-and-closeout.md +34 -7
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +210 -165
- package/assets/skills/oat-project-implement/references/docs/complexity-review-fallback.md +262 -0
- package/assets/skills/oat-project-implement/references/docs/gate-approval-record.md +80 -0
- package/assets/skills/oat-project-implement/references/phase-execution.md +38 -6
- package/assets/skills/oat-project-import-plan/SKILL.md +20 -6
- package/assets/skills/oat-project-lite/SKILL.md +7 -5
- package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +210 -165
- package/assets/skills/oat-project-new/SKILL.md +6 -2
- package/assets/skills/oat-project-next/SKILL.md +19 -2
- package/assets/skills/oat-project-next/references/docs/gate-approval-record.md +80 -0
- package/assets/skills/oat-project-plan/SKILL.md +14 -6
- package/assets/skills/oat-project-pr-final/SKILL.md +4 -3
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +210 -165
- package/assets/skills/oat-project-progress/SKILL.md +27 -1
- package/assets/skills/oat-project-progress/references/docs/gate-approval-record.md +80 -0
- package/assets/skills/oat-project-promote-spec-driven/SKILL.md +7 -3
- package/assets/skills/oat-project-quick-start/SKILL.md +47 -14
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +210 -165
- package/assets/skills/oat-project-quick-start/references/docs/complexity-review-fallback.md +262 -0
- package/assets/skills/oat-project-quick-start/references/docs/gate-approval-record.md +80 -0
- package/assets/skills/oat-project-reconcile/SKILL.md +8 -4
- package/assets/skills/oat-project-retro/SKILL.md +1 -1
- package/assets/skills/oat-project-retro/references/apply-procedure.md +6 -6
- package/assets/skills/oat-project-retro-file/SKILL.md +7 -3
- package/assets/skills/oat-project-review-provide/SKILL.md +23 -4
- package/assets/skills/oat-project-review-provide-remote/SKILL.md +19 -1
- package/assets/skills/oat-project-review-receive/SKILL.md +57 -14
- package/assets/skills/oat-project-review-receive/references/docs/complexity-review-fallback.md +262 -0
- package/assets/skills/oat-project-review-receive-remote/SKILL.md +7 -3
- package/assets/skills/oat-project-revise/SKILL.md +13 -5
- package/assets/skills/oat-project-spec/SKILL.md +8 -4
- package/assets/skills/oat-project-summary/SKILL.md +11 -7
- package/assets/skills/oat-repo-knowledge-index/SKILL.md +54 -20
- package/assets/skills/oat-repo-knowledge-index/scripts/refresh-owned.mjs +118 -0
- package/assets/skills/oat-review-provide/SKILL.md +7 -3
- package/assets/skills/oat-review-receive-remote/SKILL.md +14 -4
- package/assets/skills/oat-wave-execute/SKILL.md +72 -38
- package/assets/skills/oat-wave-execute/assets/wrapper-plan-template.md +16 -2
- package/assets/skills/oat-wave-program/SKILL.md +15 -6
- package/assets/skills/oat-worktree-bootstrap-auto/SKILL.md +45 -17
- package/assets/skills/oat-wrap-up/SKILL.md +9 -3
- package/assets/skills/oat-wrap-up/references/report-template.md +1 -1
- package/assets/skills/recon/SKILL.md +1 -1
- package/assets/skills/recon/references/packet-contract.md +18 -3
- package/assets/skills/recon/scripts/lib/contracts.mjs +16 -2
- package/assets/skills/recon/scripts/reconcile-ledger.mjs +20 -10
- package/assets/skills/recon/scripts/render-packet.mjs +31 -3
- package/assets/skills/recon/scripts/validate-packet.mjs +5 -5
- package/assets/templates/pjm-agents.md +38 -8
- package/assets/templates/repo-agents.md +5 -0
- package/assets/templates/repo-readme.md +5 -0
- package/assets/templates/state.md +7 -0
- package/dist/commands/backlog/archive.d.ts +3 -0
- package/dist/commands/backlog/archive.d.ts.map +1 -1
- package/dist/commands/backlog/archive.js +63 -26
- package/dist/commands/backlog/index.d.ts.map +1 -1
- package/dist/commands/backlog/index.js +3 -0
- package/dist/commands/backlog/rewrite-references.d.ts +5 -0
- package/dist/commands/backlog/rewrite-references.d.ts.map +1 -1
- package/dist/commands/backlog/rewrite-references.js +39 -1
- package/dist/commands/config/index.d.ts.map +1 -1
- package/dist/commands/config/index.js +13 -0
- package/dist/commands/gate/index.d.ts +5 -0
- package/dist/commands/gate/index.d.ts.map +1 -1
- package/dist/commands/gate/index.js +270 -9
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +1 -0
- package/dist/commands/internal/commit-paths.d.ts +3 -0
- package/dist/commands/internal/commit-paths.d.ts.map +1 -0
- package/dist/commands/internal/commit-paths.js +31 -0
- package/dist/commands/internal/index.d.ts.map +1 -1
- package/dist/commands/internal/index.js +2 -0
- package/dist/commands/pjm/init.d.ts.map +1 -1
- package/dist/commands/pjm/init.js +37 -8
- package/dist/commands/project/archive/archive-utils.d.ts +6 -3
- package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
- package/dist/commands/project/archive/archive-utils.js +510 -104
- package/dist/commands/project/archive/push-runner.d.ts.map +1 -1
- package/dist/commands/project/archive/push-runner.js +1 -0
- package/dist/commands/project/log/append.d.ts +2 -3
- package/dist/commands/project/log/append.d.ts.map +1 -1
- package/dist/commands/project/log/append.js +55 -101
- package/dist/commands/project/migrate/index.d.ts +1 -2
- package/dist/commands/project/migrate/index.d.ts.map +1 -1
- package/dist/commands/project/migrate/index.js +8 -2
- package/dist/commands/project/new/scaffold.d.ts.map +1 -1
- package/dist/commands/project/new/scaffold.js +4 -4
- package/dist/commands/project/promote/promote.d.ts +8 -0
- package/dist/commands/project/promote/promote.d.ts.map +1 -1
- package/dist/commands/project/promote/promote.js +37 -6
- package/dist/commands/project/status.d.ts.map +1 -1
- package/dist/commands/project/status.js +3 -0
- package/dist/commands/project/sync/ref-sync.d.ts +12 -1
- package/dist/commands/project/sync/ref-sync.d.ts.map +1 -1
- package/dist/commands/project/sync/ref-sync.js +347 -23
- package/dist/commands/shared/exact-path-commit.d.ts +32 -0
- package/dist/commands/shared/exact-path-commit.d.ts.map +1 -0
- package/dist/commands/shared/exact-path-commit.js +691 -0
- package/dist/commands/shared/frontmatter.d.ts +1 -1
- package/dist/commands/shared/frontmatter.d.ts.map +1 -1
- package/dist/commands/shared/frontmatter.js +1 -0
- package/dist/commands/state/generate.d.ts +1 -1
- package/dist/commands/state/generate.d.ts.map +1 -1
- package/dist/commands/state/generate.js +87 -8
- package/dist/commands/sync/apply.d.ts.map +1 -1
- package/dist/commands/sync/apply.js +31 -5
- package/dist/commands/sync/dry-run.d.ts.map +1 -1
- package/dist/commands/sync/dry-run.js +28 -11
- package/dist/commands/sync/sync.utils.d.ts +13 -0
- package/dist/commands/sync/sync.utils.d.ts.map +1 -1
- package/dist/commands/sync/sync.utils.js +21 -1
- package/dist/commands/tools/shared/pack-manifest.d.ts.map +1 -1
- package/dist/commands/tools/shared/pack-manifest.js +1 -0
- package/dist/config/oat-config.d.ts +1 -0
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +3 -0
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resolve.js +1 -0
- package/dist/drift/detector.js +6 -6
- package/dist/engine/compute-plan.d.ts.map +1 -1
- package/dist/engine/compute-plan.js +87 -2
- package/dist/engine/engine.types.d.ts +10 -1
- package/dist/engine/engine.types.d.ts.map +1 -1
- package/dist/engine/engine.types.js +4 -0
- package/dist/engine/execute-plan.d.ts.map +1 -1
- package/dist/engine/execute-plan.js +42 -5
- package/dist/engine/managed-copy-hash.d.ts +4 -3
- package/dist/engine/managed-copy-hash.d.ts.map +1 -1
- package/dist/engine/managed-copy-hash.js +4 -3
- package/dist/fs/assets.d.ts.map +1 -1
- package/dist/fs/assets.js +7 -1
- package/dist/manifest/hash.d.ts +8 -10
- package/dist/manifest/hash.d.ts.map +1 -1
- package/dist/ui/output.js +1 -1
- package/dist/validation/skills.d.ts.map +1 -1
- package/dist/validation/skills.js +151 -11
- package/package.json +3 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { access, lstat, readFile, readlink, stat } from 'node:fs/promises';
|
|
2
2
|
import { basename, dirname, join, normalize, relative, resolve, } from 'node:path';
|
|
3
3
|
import { CliError } from '../errors/index.js';
|
|
4
|
-
import { computeContentHash, computeStringHash } from '../manifest/hash.js';
|
|
4
|
+
import { computeContentHash, computeDirectoryDigests, computeStringHash, } from '../manifest/hash.js';
|
|
5
5
|
import { findEntry } from '../manifest/manager.js';
|
|
6
6
|
import { getSyncMappings } from '../providers/shared/adapter.utils.js';
|
|
7
7
|
import { proveCollectionIdentity } from './collection-sync.js';
|
|
@@ -200,6 +200,23 @@ export async function classifyObsoleteMappingRetirement(manifestEntry, scopeRoot
|
|
|
200
200
|
if (managedHash === manifestEntry.contentHash) {
|
|
201
201
|
return createRetirementEntry(manifestEntry, scopeRoot, 'remove', 'obsolete mapping has verified clean managed copy');
|
|
202
202
|
}
|
|
203
|
+
// Pre-framing manifest bridge, mirroring `drift/detector.ts`: a manifest
|
|
204
|
+
// written before length framing records the legacy digest, so the framed
|
|
205
|
+
// comparison above cannot match it and a faithful obsolete copy would be
|
|
206
|
+
// detached and left behind as a stale unmanaged tree. Accept the legacy
|
|
207
|
+
// value only when it is the legacy digest of the canonical tree *and*
|
|
208
|
+
// the copy's framed managed digest equals that same capture's framed
|
|
209
|
+
// digest, so acceptance still rests entirely on the framed digests (a
|
|
210
|
+
// tampered body or a forged recorded hash still detaches). Any failure
|
|
211
|
+
// to read the canonical tree is "cannot verify" and detaches below.
|
|
212
|
+
if (managedHash !== null) {
|
|
213
|
+
const canonicalDigests = await computeDirectoryDigests(canonicalPath).catch(() => null);
|
|
214
|
+
if (canonicalDigests !== null &&
|
|
215
|
+
manifestEntry.contentHash === canonicalDigests.legacy &&
|
|
216
|
+
managedHash === canonicalDigests.framed) {
|
|
217
|
+
return createRetirementEntry(manifestEntry, scopeRoot, 'remove', 'obsolete mapping has verified clean managed copy');
|
|
218
|
+
}
|
|
219
|
+
}
|
|
203
220
|
}
|
|
204
221
|
}
|
|
205
222
|
return createRetirementEntry(manifestEntry, scopeRoot, 'detach', 'obsolete mapping provider path is changed or unverified; preserve and detach manifest ownership');
|
|
@@ -264,6 +281,7 @@ async function classifyOperation(canonicalEntry, providerPath, strategy, rendere
|
|
|
264
281
|
return {
|
|
265
282
|
operation: 'skip',
|
|
266
283
|
reason: 'already in sync',
|
|
284
|
+
verifiedContentHash: canonicalHash,
|
|
267
285
|
};
|
|
268
286
|
}
|
|
269
287
|
// A directory copy is decorated by the writer: `applyCopyMarker` adds the
|
|
@@ -283,6 +301,7 @@ async function classifyOperation(canonicalEntry, providerPath, strategy, rendere
|
|
|
283
301
|
return {
|
|
284
302
|
operation: 'skip',
|
|
285
303
|
reason: 'already in sync',
|
|
304
|
+
verifiedContentHash: canonicalHash,
|
|
286
305
|
};
|
|
287
306
|
}
|
|
288
307
|
}
|
|
@@ -291,6 +310,34 @@ async function classifyOperation(canonicalEntry, providerPath, strategy, rendere
|
|
|
291
310
|
reason: 'copied content differs from canonical content',
|
|
292
311
|
};
|
|
293
312
|
}
|
|
313
|
+
/**
|
|
314
|
+
* The marker file a copy-strategy directory needs and lacks, or `null`.
|
|
315
|
+
*
|
|
316
|
+
* `applyCopyMarker` prepends the banner to `SKILL.md` / `AGENT.md`, and the
|
|
317
|
+
* managed-copy digest requires that banner. A canonical skill or agent
|
|
318
|
+
* directory without its marker therefore produced a copy that never verified:
|
|
319
|
+
* `computeManagedDirectoryCopyHash` returned `null`, so every `oat sync`
|
|
320
|
+
* planned another `update_copy` while the manifest hash never moved.
|
|
321
|
+
*/
|
|
322
|
+
async function missingCopyMarker(canonicalEntry) {
|
|
323
|
+
if (canonicalEntry.isFile || canonicalEntry.type === 'rule') {
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
const markerFileName = canonicalEntry.type === 'agent' ? 'AGENT.md' : 'SKILL.md';
|
|
327
|
+
try {
|
|
328
|
+
const markerStat = await stat(join(canonicalEntry.canonicalPath, markerFileName));
|
|
329
|
+
return markerStat.isFile() ? null : markerFileName;
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
if (typeof error === 'object' &&
|
|
333
|
+
error !== null &&
|
|
334
|
+
'code' in error &&
|
|
335
|
+
(error.code === 'ENOENT' || error.code === 'ENOTDIR')) {
|
|
336
|
+
return markerFileName;
|
|
337
|
+
}
|
|
338
|
+
throw error;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
294
341
|
function resolveScopeRoot(canonical, explicitScopeRoot) {
|
|
295
342
|
if (explicitScopeRoot) {
|
|
296
343
|
return resolve(explicitScopeRoot);
|
|
@@ -572,6 +619,24 @@ export async function computeSyncPlan({ canonical, adapters, manifest, scope, co
|
|
|
572
619
|
manifestEntry?.strategy === 'copy'
|
|
573
620
|
? manifestEntry.strategy
|
|
574
621
|
: mappingStrategy;
|
|
622
|
+
const missingMarker = entryStrategy === 'copy'
|
|
623
|
+
? await missingCopyMarker(canonicalEntry)
|
|
624
|
+
: null;
|
|
625
|
+
if (missingMarker !== null) {
|
|
626
|
+
const displayPath = relativeCanonicalPath.replaceAll('\\', '/');
|
|
627
|
+
entries.push({
|
|
628
|
+
canonical: canonicalEntry,
|
|
629
|
+
provider: adapter.name,
|
|
630
|
+
providerPath,
|
|
631
|
+
operation: 'error',
|
|
632
|
+
strategy: entryStrategy,
|
|
633
|
+
reason: `canonical ${canonicalEntry.type} directory ${displayPath} has no ${missingMarker}; add ${missingMarker} or remove the directory, then re-run oat sync`,
|
|
634
|
+
});
|
|
635
|
+
// Seen, so an owned row is neither removed nor detached: the entry
|
|
636
|
+
// still exists canonically and only its configuration is wrong.
|
|
637
|
+
seenCanonicalKeys.add(`${normalize(relativeCanonicalPath)}::${adapter.name}`);
|
|
638
|
+
continue;
|
|
639
|
+
}
|
|
575
640
|
const operation = deferredCollectionTransition
|
|
576
641
|
? {
|
|
577
642
|
operation: entryStrategy === 'copy'
|
|
@@ -583,17 +648,37 @@ export async function computeSyncPlan({ canonical, adapters, manifest, scope, co
|
|
|
583
648
|
await assertSafeProviderMutationPath(entryScopeRoot, providerPath);
|
|
584
649
|
return classifyOperation(canonicalEntry, providerPath, entryStrategy, renderedContent);
|
|
585
650
|
})();
|
|
651
|
+
// A faithful copy whose owning manifest entry records a different
|
|
652
|
+
// digest (a pre-framing legacy value or a tampered one) is restamped on
|
|
653
|
+
// skip. Without this `ensureSkipEntryManaged` kept the stale value
|
|
654
|
+
// forever: `oat status` reported drift that no `oat sync` repaired.
|
|
655
|
+
// The row must track the path that was verified: a row keyed by
|
|
656
|
+
// `(canonicalPath, provider)` can still name an older provider path
|
|
657
|
+
// (after a `providerDir` change), and stamping it with the digest of a
|
|
658
|
+
// different tree would turn its `in_sync` into permanent drift.
|
|
659
|
+
const { verifiedContentHash } = operation;
|
|
660
|
+
const restampContentHash = operation.operation === 'skip' &&
|
|
661
|
+
verifiedContentHash !== undefined &&
|
|
662
|
+
manifestEntry?.strategy === 'copy' &&
|
|
663
|
+
normalize(manifestEntry.providerPath).replaceAll('\\', '/') ===
|
|
664
|
+
relativeManifestPath(entryScopeRoot, providerPath) &&
|
|
665
|
+
manifestEntry.contentHash !== verifiedContentHash
|
|
666
|
+
? verifiedContentHash
|
|
667
|
+
: undefined;
|
|
586
668
|
entries.push({
|
|
587
669
|
canonical: canonicalEntry,
|
|
588
670
|
provider: adapter.name,
|
|
589
671
|
providerPath,
|
|
590
672
|
operation: operation.operation,
|
|
591
673
|
strategy: entryStrategy,
|
|
592
|
-
reason:
|
|
674
|
+
reason: restampContentHash === undefined
|
|
675
|
+
? operation.reason
|
|
676
|
+
: `${operation.reason}; restamp stale manifest content hash`,
|
|
593
677
|
renderedContent,
|
|
594
678
|
...(deferredCollectionTransition
|
|
595
679
|
? { deferredUntilCollectionDetached: true }
|
|
596
680
|
: {}),
|
|
681
|
+
...(restampContentHash === undefined ? {} : { restampContentHash }),
|
|
597
682
|
});
|
|
598
683
|
seenCanonicalKeys.add(`${normalize(relativeCanonicalPath)}::${adapter.name}`);
|
|
599
684
|
}
|
|
@@ -48,7 +48,7 @@ export interface CollectionProjectionPlan {
|
|
|
48
48
|
reason: string;
|
|
49
49
|
}
|
|
50
50
|
export type EngineScope = Exclude<Scope, 'all'>;
|
|
51
|
-
export declare const SYNC_OPERATION_TYPES: readonly ['create_symlink', 'create_copy', 'update_symlink', 'update_copy', 'remove', 'detach', 'skip'];
|
|
51
|
+
export declare const SYNC_OPERATION_TYPES: readonly ['create_symlink', 'create_copy', 'update_symlink', 'update_copy', 'remove', 'detach', 'skip', 'error'];
|
|
52
52
|
export type SyncOperationType = (typeof SYNC_OPERATION_TYPES)[number];
|
|
53
53
|
export interface SyncPlanEntry {
|
|
54
54
|
canonical: CanonicalEntry;
|
|
@@ -59,6 +59,15 @@ export interface SyncPlanEntry {
|
|
|
59
59
|
reason: string;
|
|
60
60
|
renderedContent?: string;
|
|
61
61
|
deferredUntilCollectionDetached?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Set only on a copy-strategy `skip` whose provider content was verified
|
|
64
|
+
* against canonical while the manifest entry that already owns it, and that
|
|
65
|
+
* tracks this same provider path, records a different `contentHash` (a
|
|
66
|
+
* pre-framing legacy digest or a tampered value).
|
|
67
|
+
* The value is the framed digest the planner verified; `executeSyncPlan`
|
|
68
|
+
* writes exactly it, so the next plan carries no restamp.
|
|
69
|
+
*/
|
|
70
|
+
restampContentHash?: string;
|
|
62
71
|
}
|
|
63
72
|
export type RemovalSyncPlanEntry = SyncPlanEntry & {
|
|
64
73
|
operation: 'remove' | 'detach';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.types.d.ts","sourceRoot":"","sources":["../../src/engine/engine.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,WAAW,GAAG,SAAS,CAAC;IAC9B,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,uBAAuB,GAC/B;IACE,MAAM,EAAE,QAAQ,CAAC;IACjB,kBAAkB,EAAE,sBAAsB,CAAC;IAC3C,cAAc,EAAE,sBAAsB,CAAC;IACvC,SAAS,EAAE,MAAM,CAAC;CACnB,GACD;IACE,MAAM,EAAE,YAAY,CAAC;IACrB,YAAY,EAAE,sBAAsB,CAAC;IACrC,kBAAkB,EAAE,sBAAsB,CAAC;IAC3C,YAAY,EAAE,UAAU,GAAG,UAAU,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB,GACD;IACE,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EACF,gBAAgB,GAChB,aAAa,GACb,gBAAgB,GAChB,mBAAmB,GACnB,iBAAiB,GACjB,sBAAsB,CAAC;IAC3B,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEN,MAAM,MAAM,oBAAoB,GAC5B,wBAAwB,GACxB,uBAAuB,GACvB,oBAAoB,GACpB,oBAAoB,GACpB,mBAAmB,GACnB,mBAAmB,CAAC;AAExB,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,WAAW,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,SAAS,EAAE,aAAa,GAAG,eAAe,GAAG,MAAM,CAAC;IACpD,kBAAkB,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;IAChD,WAAW,CAAC,EAAE,sBAAsB,CAAC;IACrC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,KAAK,EAAE,uBAAuB,CAAC;IAC/B,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAEhD,eAAO,MAAM,oBAAoB,YAC/B,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,MAAM,
|
|
1
|
+
{"version":3,"file":"engine.types.d.ts","sourceRoot":"","sources":["../../src/engine/engine.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,4 +6,8 @@ export const SYNC_OPERATION_TYPES = [
|
|
|
6
6
|
'remove',
|
|
7
7
|
'detach',
|
|
8
8
|
'skip',
|
|
9
|
+
// A configuration error found while planning (for example a copy-strategy
|
|
10
|
+
// skill or agent directory with no marker file). It mutates nothing and
|
|
11
|
+
// reports as a failed operation, so it cannot loop as a repeated copy.
|
|
12
|
+
'error',
|
|
9
13
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-plan.d.ts","sourceRoot":"","sources":["../../src/engine/execute-plan.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,aAAa,EAGb,gCAAgC,EAEhC,sBAAsB,EACtB,kCAAkC,EAGnC,MAAM,QAAQ,CAAC;AAEhB,OAAO,EAAE,YAAY,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EACV,QAAQ,EAGT,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAGL,uBAAuB,EACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,wBAAwB,EAExB,QAAQ,EAER,UAAU,EACX,MAAM,gBAAgB,CAAC;AAIxB,UAAU,2BAA2B;IACnC,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,YAAY,CAAC,EAAE,OAAO,eAAe,CAAC;IACtC,aAAa,CAAC,EAAE,OAAO,aAAa,CAAC;IACrC,sBAAsB,CAAC,EAAE,OAAO,sBAAsB,CAAC;IACvD,gCAAgC,CAAC,EAAE,OAAO,gCAAgC,CAAC;IAC3E,kCAAkC,CAAC,EAAE,OAAO,kCAAkC,CAAC;IAC/E,uBAAuB,CAAC,EAAE,OAAO,uBAAuB,CAAC;CAC1D;AAID,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,wBAAwB,CAAC,aAAa,CAAC,CAAC;IACrD,MAAM,EAAE,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IAC3C,SAAS,EAAE,wBAAwB,CAAC,WAAW,CAAC,CAAC;IACjD,MAAM,EACF,SAAS,GACT,SAAS,GACT,UAAU,GACV,UAAU,GACV,QAAQ,GACR,SAAS,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG;IAC9C,iBAAiB,EAAE,yBAAyB,EAAE,CAAC;CAChD,CAAC;
|
|
1
|
+
{"version":3,"file":"execute-plan.d.ts","sourceRoot":"","sources":["../../src/engine/execute-plan.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,aAAa,EAGb,gCAAgC,EAEhC,sBAAsB,EACtB,kCAAkC,EAGnC,MAAM,QAAQ,CAAC;AAEhB,OAAO,EAAE,YAAY,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EACV,QAAQ,EAGT,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAGL,uBAAuB,EACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,wBAAwB,EAExB,QAAQ,EAER,UAAU,EACX,MAAM,gBAAgB,CAAC;AAIxB,UAAU,2BAA2B;IACnC,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,YAAY,CAAC,EAAE,OAAO,eAAe,CAAC;IACtC,aAAa,CAAC,EAAE,OAAO,aAAa,CAAC;IACrC,sBAAsB,CAAC,EAAE,OAAO,sBAAsB,CAAC;IACvD,gCAAgC,CAAC,EAAE,OAAO,gCAAgC,CAAC;IAC3E,kCAAkC,CAAC,EAAE,OAAO,kCAAkC,CAAC;IAC/E,uBAAuB,CAAC,EAAE,OAAO,uBAAuB,CAAC;CAC1D;AAID,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,wBAAwB,CAAC,aAAa,CAAC,CAAC;IACrD,MAAM,EAAE,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IAC3C,SAAS,EAAE,wBAAwB,CAAC,WAAW,CAAC,CAAC;IACjD,MAAM,EACF,SAAS,GACT,SAAS,GACT,UAAU,GACV,UAAU,GACV,QAAQ,GACR,SAAS,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG;IAC9C,iBAAiB,EAAE,yBAAyB,EAAE,CAAC;CAChD,CAAC;AAqFF,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAW5D;AAusBD,wBAAsB,eAAe,CACnC,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,MAAM,EACpB,YAAY,GAAE,2BAAoE,GACjF,OAAO,CAAC,oBAAoB,CAAC,CAyK/B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { mkdir, rm, writeFile } from 'node:fs/promises';
|
|
2
|
-
import { dirname, join, relative, resolve } from 'node:path';
|
|
2
|
+
import { dirname, join, normalize, relative, resolve } from 'node:path';
|
|
3
3
|
import { copyDirectory, copySingleFile, copySingleFileNoClobber, createCollectionSymlinkNoClobber, createSymlink, createSymlinkNoClobber, removeCollectionSymlinkIfUnchanged, writeFileNoClobber, } from '../fs/io.js';
|
|
4
4
|
import { computeContentHash, computeStringHash } from '../manifest/hash.js';
|
|
5
5
|
import { saveManifest as persistManifest } from '../manifest/manager.js';
|
|
@@ -8,7 +8,9 @@ import { insertMarker, writeDirectorySentinel } from './markers.js';
|
|
|
8
8
|
import { assertSafeProviderMutationPath } from './provider-path-safety.js';
|
|
9
9
|
const DEFAULT_EXECUTE_SYNC_PLAN_DEPENDENCIES = {};
|
|
10
10
|
function mutatesProviderPath(entry) {
|
|
11
|
-
return entry.operation !== 'skip' &&
|
|
11
|
+
return (entry.operation !== 'skip' &&
|
|
12
|
+
entry.operation !== 'detach' &&
|
|
13
|
+
entry.operation !== 'error');
|
|
12
14
|
}
|
|
13
15
|
function operationEvidence(scope, entry, status, failure) {
|
|
14
16
|
return {
|
|
@@ -111,7 +113,9 @@ async function applyCopyMarker(entry) {
|
|
|
111
113
|
error !== null &&
|
|
112
114
|
'code' in error &&
|
|
113
115
|
error.code === 'ENOENT') {
|
|
114
|
-
// Marker insertion
|
|
116
|
+
// Marker insertion stays best-effort here. The planner already reports a
|
|
117
|
+
// canonical directory without its marker as an `error` entry, so this
|
|
118
|
+
// path is reached only if the marker disappears between plan and apply.
|
|
115
119
|
return;
|
|
116
120
|
}
|
|
117
121
|
throw error;
|
|
@@ -203,12 +207,40 @@ function removeManifestEntry(manifest, canonicalPath, provider) {
|
|
|
203
207
|
? manifest
|
|
204
208
|
: { ...manifest, entries, lastUpdated: new Date().toISOString() };
|
|
205
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Whether two scope-relative manifest paths name the same location. A stored
|
|
212
|
+
* row may spell its path differently (`./.claude/skills/x`) from the form
|
|
213
|
+
* `resolveManifestPaths` produces; the planner compares normalized paths, so
|
|
214
|
+
* the restamp guard must too, or a planned restamp is silently dropped. The
|
|
215
|
+
* stored spelling itself is left unchanged.
|
|
216
|
+
*/
|
|
217
|
+
function sameManifestPath(left, right) {
|
|
218
|
+
return (normalize(left).replaceAll('\\', '/') ===
|
|
219
|
+
normalize(right).replaceAll('\\', '/'));
|
|
220
|
+
}
|
|
206
221
|
async function ensureSkipEntryManaged(planEntry, manifest) {
|
|
207
|
-
const { canonicalPath } = resolveManifestPaths(planEntry);
|
|
222
|
+
const { canonicalPath, providerPath } = resolveManifestPaths(planEntry);
|
|
208
223
|
const existing = manifest.entries.find((entry) => entry.canonicalPath === canonicalPath &&
|
|
209
224
|
entry.provider === planEntry.provider);
|
|
210
225
|
if (existing) {
|
|
211
|
-
|
|
226
|
+
// An owned entry is rewritten only when the planner verified the provider
|
|
227
|
+
// content and found the recorded digest stale; it then writes exactly the
|
|
228
|
+
// digest it verified. The row must track that same provider path, or the
|
|
229
|
+
// digest would describe a tree the row does not point at. Every other
|
|
230
|
+
// owned skip leaves the manifest as is, so a settled sync stays a no-op.
|
|
231
|
+
const restampContentHash = planEntry.restampContentHash;
|
|
232
|
+
if (restampContentHash === undefined ||
|
|
233
|
+
existing.strategy === 'collection' ||
|
|
234
|
+
!sameManifestPath(existing.providerPath, providerPath) ||
|
|
235
|
+
existing.contentHash === restampContentHash) {
|
|
236
|
+
return manifest;
|
|
237
|
+
}
|
|
238
|
+
return addManifestEntry(manifest, {
|
|
239
|
+
...existing,
|
|
240
|
+
strategy: existing.strategy,
|
|
241
|
+
contentHash: restampContentHash,
|
|
242
|
+
lastSynced: new Date().toISOString(),
|
|
243
|
+
});
|
|
212
244
|
}
|
|
213
245
|
const manifestEntry = await toManifestEntry(planEntry, planEntry.strategy);
|
|
214
246
|
return addManifestEntry(manifest, manifestEntry);
|
|
@@ -561,6 +593,11 @@ export async function executeSyncPlan(plan, manifest, manifestPath, dependencies
|
|
|
561
593
|
'Collection alias could not be safely cleared; resolve the reported collection conflict and retry.'));
|
|
562
594
|
continue;
|
|
563
595
|
}
|
|
596
|
+
if (operation.operation === 'error') {
|
|
597
|
+
// A planning-time configuration error: report it, change nothing.
|
|
598
|
+
operationResults.push(operationEvidence(plan.scope, operation, 'failed', operation.reason));
|
|
599
|
+
continue;
|
|
600
|
+
}
|
|
564
601
|
if (operation.operation === 'skip') {
|
|
565
602
|
nextManifest = await ensureSkipEntryManaged(operation, nextManifest);
|
|
566
603
|
operationResults.push(operationEvidence(plan.scope, operation, 'current'));
|
|
@@ -42,9 +42,10 @@ import type { ManifestEntry } from '../manifest/manifest.types.js';
|
|
|
42
42
|
* skipped it. Combined with the unframed digest that let a view drop
|
|
43
43
|
* `SKILL.md`, fuse its bytes into a surviving file, and read `in_sync`. The
|
|
44
44
|
* requirement is unconditional, so a skill directory that genuinely has no
|
|
45
|
-
* `SKILL.md`
|
|
46
|
-
*
|
|
47
|
-
*
|
|
45
|
+
* `SKILL.md` reads `drifted` rather than `in_sync`: the safe direction, and
|
|
46
|
+
* the direction the review asked for. The planner does not loop on it:
|
|
47
|
+
* `computeSyncPlan` reports a canonical directory without its marker as a
|
|
48
|
+
* configuration `error` entry instead of planning `update_copy`.
|
|
48
49
|
*
|
|
49
50
|
* These claims describe a quiescent tree. Every check here is path-based, so
|
|
50
51
|
* none of them survives an adversary swapping an entry between the check and
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managed-copy-hash.d.ts","sourceRoot":"","sources":["../../src/engine/managed-copy-hash.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAI9D
|
|
1
|
+
{"version":3,"file":"managed-copy-hash.d.ts","sourceRoot":"","sources":["../../src/engine/managed-copy-hash.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAI9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,wBAAsB,+BAA+B,CACnD,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,aAAa,CAAC,aAAa,CAAC,GACxC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyHxB"}
|
|
@@ -45,9 +45,10 @@ import { OAT_DIRECTORY_SENTINEL, OAT_MARKER_PREFIX } from './markers.js';
|
|
|
45
45
|
* skipped it. Combined with the unframed digest that let a view drop
|
|
46
46
|
* `SKILL.md`, fuse its bytes into a surviving file, and read `in_sync`. The
|
|
47
47
|
* requirement is unconditional, so a skill directory that genuinely has no
|
|
48
|
-
* `SKILL.md`
|
|
49
|
-
*
|
|
50
|
-
*
|
|
48
|
+
* `SKILL.md` reads `drifted` rather than `in_sync`: the safe direction, and
|
|
49
|
+
* the direction the review asked for. The planner does not loop on it:
|
|
50
|
+
* `computeSyncPlan` reports a canonical directory without its marker as a
|
|
51
|
+
* configuration `error` entry instead of planning `update_copy`.
|
|
51
52
|
*
|
|
52
53
|
* These claims describe a quiescent tree. Every check here is path-based, so
|
|
53
54
|
* none of them survives an adversary swapping an entry between the check and
|
package/dist/fs/assets.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/fs/assets.ts"],"names":[],"mappings":"AAeA;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,UAAU,CAAC;AA0CvD;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,YACtC,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,SAAS,EACT,MAAM,EACN,WAAW,EACX,QAAQ,CACA,CAAC;AAgFX;;;;;;;;;;;GAWG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,eAAe,SAAc,EAC7B,MAAM,GAAE,gBAA6B,GACpC,OAAO,CAAC,IAAI,CAAC,CAsCf;AAQD;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/fs/assets.ts"],"names":[],"mappings":"AAeA;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,UAAU,CAAC;AA0CvD;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,YACtC,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,SAAS,EACT,MAAM,EACN,WAAW,EACX,QAAQ,CACA,CAAC;AAgFX;;;;;;;;;;;GAWG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,eAAe,SAAc,EAC7B,MAAM,GAAE,gBAA6B,GACpC,OAAO,CAAC,IAAI,CAAC,CAsCf;AAQD;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAAC,MAAM,CAAC,CAwCjB"}
|
package/dist/fs/assets.js
CHANGED
|
@@ -179,7 +179,13 @@ export async function resolveAssetsRoot(env = process.env) {
|
|
|
179
179
|
if (error instanceof CliError) {
|
|
180
180
|
throw error;
|
|
181
181
|
}
|
|
182
|
-
|
|
182
|
+
// Only an absent root is "not found". EACCES, ELOOP, and EIO on a root
|
|
183
|
+
// that exists need a different response, so name the errno, as
|
|
184
|
+
// `validateBundleStructure` does for the directories inside it.
|
|
185
|
+
if (isMissingPathError(error)) {
|
|
186
|
+
throw new CliError(`Assets directory not found: ${assetsRoot}. ${assetsRemedy(source, PACKAGED_ROOT_REMEDY)}`, 2);
|
|
187
|
+
}
|
|
188
|
+
throw new CliError(`Assets directory could not be read (${errorCode(error)}): ${assetsRoot}. ${assetsRemedy(source, PACKAGED_ROOT_REMEDY)}`, 2);
|
|
183
189
|
}
|
|
184
190
|
await validateAssetsBundle(assetsRoot, OAT_VERSION, source);
|
|
185
191
|
return assetsRoot;
|
package/dist/manifest/hash.d.ts
CHANGED
|
@@ -45,16 +45,14 @@ export declare function computeContentHash(contentPath: string, isFile: boolean)
|
|
|
45
45
|
* framed digest equals a legacy digest under SHA-256 collision resistance —
|
|
46
46
|
* the same assumption every other comparison here already rests on.
|
|
47
47
|
*
|
|
48
|
-
* `legacy` is retained for exactly one purpose:
|
|
49
|
-
*
|
|
50
|
-
* `
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* longer matches reports `drifted/modified` from `oat status`, `oat sync`
|
|
57
|
-
* answers `skip` / "already in sync", and the manifest keeps the old value.
|
|
48
|
+
* `legacy` is retained for exactly one purpose: recognizing a manifest written
|
|
49
|
+
* before the framing change and re-deciding with `framed`, in
|
|
50
|
+
* `drift/detector.ts` and in the obsolete-mapping retirement classifier
|
|
51
|
+
* (`classifyObsoleteMappingRetirement` in `engine/compute-plan.ts`). It is
|
|
52
|
+
* never an acceptance basis for provider content on its own. The migration is
|
|
53
|
+
* needed because framing changes every recorded `contentHash`; `oat sync` now
|
|
54
|
+
* restamps a stale value when it plans `skip` for a faithful tree, so the
|
|
55
|
+
* bridge only covers installs that have not run such a sync yet.
|
|
58
56
|
*
|
|
59
57
|
* ## Bounds this digest still does not cover
|
|
60
58
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/manifest/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAMpD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIzD;AAqBD,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBvE;AAED,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,MAAM,CAAC,CAIjB;AAID
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/manifest/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAMpD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIzD;AAqBD,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBvE;AAED,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,MAAM,CAAC,CAIjB;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,IAAI,IAAI,CAIlD;AAED,gEAAgE;AAChE,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd,IAAI,CAMN;AAgFD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,gBAAgB,CAAC,CAe3B;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiB3E"}
|
package/dist/ui/output.js
CHANGED
|
@@ -90,7 +90,7 @@ function colorSyncOperation(operation) {
|
|
|
90
90
|
if (operation === 'update_symlink' || operation === 'update_copy') {
|
|
91
91
|
return chalk.yellow(operation);
|
|
92
92
|
}
|
|
93
|
-
if (operation === 'remove') {
|
|
93
|
+
if (operation === 'remove' || operation === 'error') {
|
|
94
94
|
return chalk.red(operation);
|
|
95
95
|
}
|
|
96
96
|
return chalk.gray(operation);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/validation/skills.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,uCAAuC;IACtD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sCAAsC;IACrD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,KAChD,OAAO,CAAC,cAAc,CAAC,CAAC;AAE7B,UAAU,6BAA6B;IACrC,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/validation/skills.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,uCAAuC;IACtD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sCAAsC;IACrD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,KAChD,OAAO,CAAC,cAAc,CAAC,CAAC;AAE7B,UAAU,6BAA6B;IACrC,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAqgDD,wBAAsB,gCAAgC,CACpD,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,uCAAuC,EAChD,YAAY,GAAE,6BAAkC,GAC/C,OAAO,CAAC,sCAAsC,CAAC,CAsBjD;AAsGD,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,wBAA6B,EACtC,YAAY,GAAE,6BAAkC,GAC/C,OAAO,CAAC,uBAAuB,CAAC,CAoKlC"}
|