@litfamily/litopencode 1.0.1 → 1.0.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.
Files changed (62) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README-Ko-KR.md +8 -7
  3. package/README.md +8 -7
  4. package/dist/activation-prompt-utils.d.ts +1 -1
  5. package/dist/activation-routing.d.ts +1 -1
  6. package/dist/activation-routing.js +1 -8
  7. package/dist/activation-workflow-prompts.d.ts +0 -1
  8. package/dist/activation-workflow-prompts.js +0 -8
  9. package/dist/activation.d.ts +1 -1
  10. package/dist/activation.js +1 -1
  11. package/dist/cli/args.d.ts +1 -1
  12. package/dist/cli/args.js +1 -31
  13. package/dist/cli/loop.js +0 -19
  14. package/dist/cli/managed-skill-assets.d.ts +1 -1
  15. package/dist/cli/managed-skill-assets.js +0 -2
  16. package/dist/cli/types.d.ts +0 -4
  17. package/dist/cli.js +0 -14
  18. package/dist/commands.d.ts +1 -10
  19. package/dist/commands.js +1 -11
  20. package/dist/features.d.ts +1 -22
  21. package/dist/features.js +0 -43
  22. package/dist/hooks.js +0 -13
  23. package/dist/index.d.ts +0 -5
  24. package/dist/index.js +0 -5
  25. package/dist/skills.d.ts +1 -8
  26. package/dist/skills.js +0 -13
  27. package/docs/assets/cover-motion.webp +0 -0
  28. package/docs/assets/readme/badge-version.svg +1 -1
  29. package/docs/privacy.md +2 -2
  30. package/docs/reference.md +5 -48
  31. package/package.json +2 -1
  32. package/skills/frontend-ui-ux/references/complete-contract.md +1 -1
  33. package/skills/lit-plan/SKILL.md +1 -1
  34. package/skills/managed-skill-manifest.json +2 -9
  35. package/skills/visual-qa/references/complete-contract.md +1 -1
  36. package/tools/check-payload-substance.mjs +74 -27
  37. package/tools/payload-substance-parity.json +10 -25
  38. package/tools/version-manifests.json +2 -2
  39. package/dist/cli/skill-loop.d.ts +0 -3
  40. package/dist/cli/skill-loop.js +0 -649
  41. package/dist/skill-loop/apply.d.ts +0 -19
  42. package/dist/skill-loop/apply.js +0 -483
  43. package/dist/skill-loop/config.d.ts +0 -50
  44. package/dist/skill-loop/config.js +0 -215
  45. package/dist/skill-loop/curator.d.ts +0 -18
  46. package/dist/skill-loop/curator.js +0 -232
  47. package/dist/skill-loop/ledger.d.ts +0 -39
  48. package/dist/skill-loop/ledger.js +0 -344
  49. package/dist/skill-loop/proposals.d.ts +0 -48
  50. package/dist/skill-loop/proposals.js +0 -290
  51. package/dist/skill-loop/storage.d.ts +0 -72
  52. package/dist/skill-loop/storage.js +0 -817
  53. package/dist/skill-loop/time.d.ts +0 -2
  54. package/dist/skill-loop/time.js +0 -23
  55. package/dist/skill-loop/transaction.d.ts +0 -62
  56. package/dist/skill-loop/transaction.js +0 -836
  57. package/dist/skill-loop/usage.d.ts +0 -31
  58. package/dist/skill-loop/usage.js +0 -146
  59. package/dist/skill-observer.d.ts +0 -22
  60. package/dist/skill-observer.js +0 -1154
  61. package/skills/skill-observer/SKILL.md +0 -148
  62. package/skills/skill-observer/references/review-contract.md +0 -95
@@ -1,31 +0,0 @@
1
- import { type SkillLoopLockCapability } from "./storage.ts";
2
- export type SkillUsageState = "active" | "stale" | "archived";
3
- export type SkillUsageEntry = {
4
- readonly state: SkillUsageState;
5
- readonly use_count: number;
6
- readonly view_count: number;
7
- readonly patch_count: number;
8
- readonly created_at: string;
9
- readonly created_by: "agent" | "user" | "installed" | "curator" | null;
10
- readonly last_used_at: string | null;
11
- readonly last_viewed_at: string | null;
12
- readonly last_patched_at: string | null;
13
- readonly archived_at: string | null;
14
- readonly pinned: boolean;
15
- };
16
- export type SkillUsageSidecar = {
17
- readonly schema: "litfamily.skill-usage/v1";
18
- readonly updatedAt: string;
19
- readonly skills: Readonly<Record<string, SkillUsageEntry>>;
20
- };
21
- export declare function parseUsageSidecar(value: unknown): SkillUsageSidecar;
22
- export declare function readUsageSidecar(projectRoot: string, now?: string): Promise<SkillUsageSidecar>;
23
- export declare function writeUsageSidecar(projectRoot: string, value: unknown, options?: {
24
- readonly capability?: SkillLoopLockCapability;
25
- }): Promise<SkillUsageSidecar>;
26
- export declare function bumpSkillUsage(projectRoot: string, skillId: string, field: "use" | "view" | "patch", now?: string, options?: {
27
- readonly capability?: SkillLoopLockCapability;
28
- }): Promise<SkillUsageSidecar>;
29
- export declare function setSkillUsageLifecycle(projectRoot: string, skillId: string, state: SkillUsageState, now?: string, options?: {
30
- readonly capability?: SkillLoopLockCapability;
31
- }): Promise<SkillUsageSidecar>;
@@ -1,146 +0,0 @@
1
- import { parseStrictJson } from "../strict-json.js";
2
- import { skillLoopPaths, writeJsonAtomically } from "./config.js";
3
- import { assertPortableRelativeFile, canonicalRelativeIdentity } from "./proposals.js";
4
- import { assertSkillLoopLockCapability, readSafeRuntimeFile, withSkillLoopMutationLock } from "./storage.js";
5
- import { isStrictRfc3339 } from "./time.js";
6
- function isRecord(value) {
7
- return typeof value === "object" && value !== null && !Array.isArray(value);
8
- }
9
- function timestamp(value, nullable = false) {
10
- if (value === null && nullable)
11
- return null;
12
- if (!isStrictRfc3339(value))
13
- throw new Error("SKILL_USAGE_INVALID");
14
- return value;
15
- }
16
- function count(value) {
17
- if (!Number.isInteger(value) || Number(value) < 0)
18
- throw new Error("SKILL_USAGE_INVALID");
19
- return Number(value);
20
- }
21
- export function parseUsageSidecar(value) {
22
- if (!isRecord(value) || value.schema !== "litfamily.skill-usage/v1" || typeof value.updatedAt !== "string" || !isRecord(value.skills) ||
23
- Object.keys(value).some((key) => key !== "schema" && key !== "updatedAt" && key !== "skills")) {
24
- throw new Error("SKILL_USAGE_INVALID");
25
- }
26
- const updatedAt = timestamp(value.updatedAt);
27
- const updatedMs = Date.parse(updatedAt);
28
- const skills = {};
29
- const identities = new Set();
30
- for (const [id, raw] of Object.entries(value.skills)) {
31
- if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(id) || !isRecord(raw))
32
- throw new Error("SKILL_USAGE_INVALID");
33
- try {
34
- if (assertPortableRelativeFile(id) !== id)
35
- throw new Error("invalid");
36
- }
37
- catch {
38
- throw new Error("SKILL_USAGE_INVALID");
39
- }
40
- const identity = canonicalRelativeIdentity(id);
41
- if (identities.has(identity))
42
- throw new Error("SKILL_USAGE_INVALID");
43
- identities.add(identity);
44
- const expected = ["state", "use_count", "view_count", "patch_count", "created_at", "created_by", "last_used_at", "last_viewed_at", "last_patched_at", "archived_at", "pinned"];
45
- if (Object.keys(raw).length !== expected.length || Object.keys(raw).some((key) => !expected.includes(key)))
46
- throw new Error("SKILL_USAGE_INVALID");
47
- if (raw.state !== "active" && raw.state !== "stale" && raw.state !== "archived")
48
- throw new Error("SKILL_USAGE_INVALID");
49
- if (raw.created_by !== "agent" && raw.created_by !== "user" && raw.created_by !== "installed" && raw.created_by !== "curator" && raw.created_by !== null)
50
- throw new Error("SKILL_USAGE_INVALID");
51
- if (typeof raw.pinned !== "boolean")
52
- throw new Error("SKILL_USAGE_INVALID");
53
- const entry = {
54
- state: raw.state,
55
- use_count: count(raw.use_count),
56
- view_count: count(raw.view_count),
57
- patch_count: count(raw.patch_count),
58
- created_at: timestamp(raw.created_at),
59
- created_by: raw.created_by,
60
- last_used_at: timestamp(raw.last_used_at, true),
61
- last_viewed_at: timestamp(raw.last_viewed_at, true),
62
- last_patched_at: timestamp(raw.last_patched_at, true),
63
- archived_at: timestamp(raw.archived_at, true),
64
- pinned: raw.pinned
65
- };
66
- if ((entry.use_count > 0) !== (entry.last_used_at !== null) || (entry.view_count > 0) !== (entry.last_viewed_at !== null) ||
67
- (entry.patch_count > 0) !== (entry.last_patched_at !== null) || (entry.state === "archived") !== (entry.archived_at !== null)) {
68
- throw new Error("SKILL_USAGE_INVALID");
69
- }
70
- const createdMs = Date.parse(entry.created_at);
71
- for (const date of [entry.last_used_at, entry.last_viewed_at, entry.last_patched_at, entry.archived_at]) {
72
- if (date !== null && (Date.parse(date) < createdMs || Date.parse(date) > updatedMs))
73
- throw new Error("SKILL_USAGE_INVALID");
74
- }
75
- if (createdMs > updatedMs)
76
- throw new Error("SKILL_USAGE_INVALID");
77
- skills[id] = Object.freeze(entry);
78
- }
79
- return Object.freeze({ schema: "litfamily.skill-usage/v1", updatedAt, skills: Object.freeze(skills) });
80
- }
81
- export async function readUsageSidecar(projectRoot, now = new Date().toISOString()) {
82
- if (!isStrictRfc3339(now))
83
- throw new Error("SKILL_USAGE_INVALID");
84
- const bytes = await readSafeRuntimeFile(projectRoot, skillLoopPaths(projectRoot).usageFile, { maxBytes: 2 * 1024 * 1024 });
85
- return bytes === undefined
86
- ? { schema: "litfamily.skill-usage/v1", updatedAt: now, skills: {} }
87
- : parseUsageSidecar(parseStrictJson(bytes.toString("utf8")));
88
- }
89
- export async function writeUsageSidecar(projectRoot, value, options = {}) {
90
- if (options.capability === undefined) {
91
- return withSkillLoopMutationLock(projectRoot, (capability) => writeUsageSidecar(projectRoot, value, { capability }));
92
- }
93
- assertSkillLoopLockCapability(options.capability, projectRoot);
94
- const parsed = parseUsageSidecar(value);
95
- await writeJsonAtomically(projectRoot, skillLoopPaths(projectRoot).usageFile, parsed, options.capability);
96
- return parsed;
97
- }
98
- export async function bumpSkillUsage(projectRoot, skillId, field, now = new Date().toISOString(), options = {}) {
99
- if (options.capability === undefined) {
100
- return withSkillLoopMutationLock(projectRoot, (capability) => bumpSkillUsage(projectRoot, skillId, field, now, { capability }));
101
- }
102
- assertSkillLoopLockCapability(options.capability, projectRoot);
103
- if (!isStrictRfc3339(now))
104
- throw new Error("SKILL_USAGE_INVALID");
105
- const sidecar = await readUsageSidecar(projectRoot, now);
106
- const current = sidecar.skills[skillId] ?? {
107
- state: "active",
108
- use_count: 0, view_count: 0, patch_count: 0,
109
- created_at: now, created_by: "agent",
110
- last_used_at: null, last_viewed_at: null, last_patched_at: null,
111
- archived_at: null, pinned: false
112
- };
113
- const next = {
114
- ...current,
115
- state: current.state === "archived" ? "archived" : "active",
116
- use_count: current.use_count + (field === "use" ? 1 : 0),
117
- view_count: current.view_count + (field === "view" ? 1 : 0),
118
- patch_count: current.patch_count + (field === "patch" ? 1 : 0),
119
- last_used_at: field === "use" ? now : current.last_used_at,
120
- last_viewed_at: field === "view" ? now : current.last_viewed_at,
121
- last_patched_at: field === "patch" ? now : current.last_patched_at
122
- };
123
- return writeUsageSidecar(projectRoot, { ...sidecar, updatedAt: now, skills: { ...sidecar.skills, [skillId]: next } }, { capability: options.capability });
124
- }
125
- export async function setSkillUsageLifecycle(projectRoot, skillId, state, now = new Date().toISOString(), options = {}) {
126
- if (options.capability === undefined) {
127
- return withSkillLoopMutationLock(projectRoot, (capability) => setSkillUsageLifecycle(projectRoot, skillId, state, now, { capability }));
128
- }
129
- assertSkillLoopLockCapability(options.capability, projectRoot);
130
- if (!isStrictRfc3339(now))
131
- throw new Error("SKILL_USAGE_INVALID");
132
- const sidecar = await readUsageSidecar(projectRoot, now);
133
- const current = sidecar.skills[skillId] ?? {
134
- state: "active",
135
- use_count: 0, view_count: 0, patch_count: 0,
136
- created_at: now, created_by: "agent",
137
- last_used_at: null, last_viewed_at: null, last_patched_at: null,
138
- archived_at: null, pinned: false
139
- };
140
- const next = {
141
- ...current,
142
- state,
143
- archived_at: state === "archived" ? now : null
144
- };
145
- return writeUsageSidecar(projectRoot, { ...sidecar, updatedAt: now, skills: { ...sidecar.skills, [skillId]: next } }, { capability: options.capability });
146
- }
@@ -1,22 +0,0 @@
1
- /** The three signals worth capturing. A fourth needs a contract revision, not a free-text value. */
2
- export declare const OBSERVER_SIGNALS: readonly ["correction", "repetition", "coverage-gap"];
3
- export type ObserverSignal = (typeof OBSERVER_SIGNALS)[number];
4
- export type SkillObservation = {
5
- readonly signal: ObserverSignal;
6
- readonly skillId: string;
7
- readonly observed: string;
8
- readonly proposal: string;
9
- readonly applied: false;
10
- };
11
- export declare const OBSERVER_RECORD_COMMITTED_CLEANUP_FAILED: "OBSERVER_RECORD_COMMITTED_CLEANUP_FAILED";
12
- export declare const OBSERVER_RECORD_STATE_UNKNOWN: "OBSERVER_RECORD_STATE_UNKNOWN";
13
- export type SkillObserverErrorCode = "OBSERVER_PATH_UNSAFE" | "OBSERVER_LOG_UNSAFE" | "OBSERVER_LOG_PERMISSIONS_UNSAFE" | "OBSERVER_LOG_MALFORMED" | "OBSERVER_SHAPE_INVALID" | "OBSERVER_FIELD_UNKNOWN" | "OBSERVER_FIELD_MISSING" | "OBSERVER_SIGNAL_UNKNOWN" | "OBSERVER_SKILL_ID_INVALID" | "OBSERVER_TEXT_MISSING" | "OBSERVER_SECRET_REFUSED" | "OBSERVER_TEXT_INVALID" | "OBSERVER_APPLIED_INVALID" | "OBSERVER_LOG_SIZE_EXCEEDED" | "OBSERVER_WRITE_FAILED" | "OBSERVER_RECORD_TOO_LARGE" | "OBSERVER_LOCK_TIMEOUT" | "OBSERVER_LOCK_UNSAFE" | typeof OBSERVER_RECORD_STATE_UNKNOWN | typeof OBSERVER_RECORD_COMMITTED_CLEANUP_FAILED;
14
- export declare const OBSERVER_LOG_MAX_BYTES = 1048576;
15
- export declare class SkillObserverError extends Error {
16
- readonly code: SkillObserverErrorCode;
17
- constructor(code: SkillObserverErrorCode, message: string);
18
- }
19
- export declare function observationLogPath(root: string): string;
20
- export declare function observerLockPath(root: string): string;
21
- export declare function recordObservation(root: string, observation: unknown): SkillObservation;
22
- export declare function readObservations(root: string): readonly SkillObservation[];