@hasna/skills 0.2.0 → 0.2.1

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.
@@ -38,23 +38,7 @@ export declare const runAdmissionSchema: z.ZodObject<{
38
38
  skill: z.ZodString;
39
39
  status: z.ZodLiteral<"admitted">;
40
40
  createdAt: z.ZodString;
41
- }, "strip", z.ZodTypeAny, {
42
- status: "admitted";
43
- createdAt: string;
44
- skill: string;
45
- contractVersion: 1;
46
- runId: string;
47
- leaseGeneration: number;
48
- attemptId: string;
49
- }, {
50
- status: "admitted";
51
- createdAt: string;
52
- skill: string;
53
- contractVersion: 1;
54
- runId: string;
55
- leaseGeneration: number;
56
- attemptId: string;
57
- }>;
41
+ }, z.core.$strip>;
58
42
  export type RunAdmission = z.infer<typeof runAdmissionSchema>;
59
43
  /** Lease: a worker has claimed the run. */
60
44
  export declare const runLeaseSchema: z.ZodObject<{
@@ -64,21 +48,7 @@ export declare const runLeaseSchema: z.ZodObject<{
64
48
  leaseGeneration: z.ZodNumber;
65
49
  workerId: z.ZodString;
66
50
  status: z.ZodLiteral<"leased">;
67
- }, "strip", z.ZodTypeAny, {
68
- status: "leased";
69
- contractVersion: 1;
70
- runId: string;
71
- leaseGeneration: number;
72
- attemptId: string;
73
- workerId: string;
74
- }, {
75
- status: "leased";
76
- contractVersion: 1;
77
- runId: string;
78
- leaseGeneration: number;
79
- attemptId: string;
80
- workerId: string;
81
- }>;
51
+ }, z.core.$strip>;
82
52
  export type RunLease = z.infer<typeof runLeaseSchema>;
83
53
  /** Terminal: the run reached a final state. */
84
54
  export declare const runTerminalSchema: z.ZodObject<{
@@ -87,28 +57,17 @@ export declare const runTerminalSchema: z.ZodObject<{
87
57
  attemptId: z.ZodString;
88
58
  leaseGeneration: z.ZodNumber;
89
59
  skill: z.ZodString;
90
- status: z.ZodEnum<["succeeded", "failed", "cancelled", "expired"]>;
60
+ status: z.ZodEnum<{
61
+ cancelled: "cancelled";
62
+ failed: "failed";
63
+ succeeded: "succeeded";
64
+ expired: "expired";
65
+ }>;
91
66
  completedAt: z.ZodString;
92
- }, "strip", z.ZodTypeAny, {
93
- status: "cancelled" | "failed" | "succeeded" | "expired";
94
- skill: string;
95
- completedAt: string;
96
- contractVersion: 1;
97
- runId: string;
98
- leaseGeneration: number;
99
- attemptId: string;
100
- }, {
101
- status: "cancelled" | "failed" | "succeeded" | "expired";
102
- skill: string;
103
- completedAt: string;
104
- contractVersion: 1;
105
- runId: string;
106
- leaseGeneration: number;
107
- attemptId: string;
108
- }>;
67
+ }, z.core.$strip>;
109
68
  export type RunTerminal = z.infer<typeof runTerminalSchema>;
110
69
  /** Any single protocol message, discriminated by `status`. */
111
- export declare const runProtocolSchema: z.ZodDiscriminatedUnion<"status", [z.ZodObject<{
70
+ export declare const runProtocolSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
112
71
  contractVersion: z.ZodLiteral<1>;
113
72
  runId: z.ZodString;
114
73
  attemptId: z.ZodString;
@@ -116,68 +75,27 @@ export declare const runProtocolSchema: z.ZodDiscriminatedUnion<"status", [z.Zod
116
75
  skill: z.ZodString;
117
76
  status: z.ZodLiteral<"admitted">;
118
77
  createdAt: z.ZodString;
119
- }, "strip", z.ZodTypeAny, {
120
- status: "admitted";
121
- createdAt: string;
122
- skill: string;
123
- contractVersion: 1;
124
- runId: string;
125
- leaseGeneration: number;
126
- attemptId: string;
127
- }, {
128
- status: "admitted";
129
- createdAt: string;
130
- skill: string;
131
- contractVersion: 1;
132
- runId: string;
133
- leaseGeneration: number;
134
- attemptId: string;
135
- }>, z.ZodObject<{
78
+ }, z.core.$strip>, z.ZodObject<{
136
79
  contractVersion: z.ZodLiteral<1>;
137
80
  runId: z.ZodString;
138
81
  attemptId: z.ZodString;
139
82
  leaseGeneration: z.ZodNumber;
140
83
  workerId: z.ZodString;
141
84
  status: z.ZodLiteral<"leased">;
142
- }, "strip", z.ZodTypeAny, {
143
- status: "leased";
144
- contractVersion: 1;
145
- runId: string;
146
- leaseGeneration: number;
147
- attemptId: string;
148
- workerId: string;
149
- }, {
150
- status: "leased";
151
- contractVersion: 1;
152
- runId: string;
153
- leaseGeneration: number;
154
- attemptId: string;
155
- workerId: string;
156
- }>, z.ZodObject<{
85
+ }, z.core.$strip>, z.ZodObject<{
157
86
  contractVersion: z.ZodLiteral<1>;
158
87
  runId: z.ZodString;
159
88
  attemptId: z.ZodString;
160
89
  leaseGeneration: z.ZodNumber;
161
90
  skill: z.ZodString;
162
- status: z.ZodEnum<["succeeded", "failed", "cancelled", "expired"]>;
91
+ status: z.ZodEnum<{
92
+ cancelled: "cancelled";
93
+ failed: "failed";
94
+ succeeded: "succeeded";
95
+ expired: "expired";
96
+ }>;
163
97
  completedAt: z.ZodString;
164
- }, "strip", z.ZodTypeAny, {
165
- status: "cancelled" | "failed" | "succeeded" | "expired";
166
- skill: string;
167
- completedAt: string;
168
- contractVersion: 1;
169
- runId: string;
170
- leaseGeneration: number;
171
- attemptId: string;
172
- }, {
173
- status: "cancelled" | "failed" | "succeeded" | "expired";
174
- skill: string;
175
- completedAt: string;
176
- contractVersion: 1;
177
- runId: string;
178
- leaseGeneration: number;
179
- attemptId: string;
180
- }>]>;
98
+ }, z.core.$strip>], "status">;
181
99
  export type RunProtocolMessage = z.infer<typeof runProtocolSchema>;
182
100
  /** Map the store's status vocabulary onto the protocol lifecycle. */
183
101
  export declare function protocolStateOf(status: ServerRunStatus): RunProtocolState;
@@ -113,6 +113,17 @@ export declare class ArtifactStorage {
113
113
  * <prefix>/skills/<org>/<slug>/<version>/manifest.json
114
114
  * The content-addressed object under bundles/ stays the read path (dedupe); these keys
115
115
  * are the durable, browsable history and are never deleted by orphan collection.
116
+ *
117
+ * RETENTION (hasna/apps#1671): these objects accumulate without bound by design — every
118
+ * version keeps a full copy — so the bucket lifecycle is the retention story, not the
119
+ * store. The intended rule (operated in the bucket's lifecycle config, outside this
120
+ * repository): expire `<prefix>/skills/` objects older than N days per the slot policy,
121
+ * while `<prefix>/bundles/` (content-addressed, deduped across versions and slugs) is
122
+ * NEVER expired by lifecycle — only the reference-guarded delete path removes those,
123
+ * because one object can serve many versions. A busy org that pushes thousands of
124
+ * versions should pair the lifecycle rule with a documented cap on retained versions
125
+ * per slug (e.g. the newest K, pruned by a maintenance job that deletes the version row
126
+ * and its two objects together); row deletion alone would strand the objects.
116
127
  * Returns the placement recorded on the version row; in db mode nothing is written.
117
128
  */
118
129
  putVersionObjects(orgId: string, slug: string, version: string, bytes: OwnedBytes, manifest: Record<string, unknown>, contentType?: string): Promise<{
@@ -22,7 +22,15 @@ export declare class SkillRequestError extends Error {
22
22
  }
23
23
  /** SkillMeta shape for a published row, so a client can treat both kinds alike. */
24
24
  export declare function publishedSkillMeta(record: ServerSkillRecord): SkillMeta;
25
- export declare function publishedPayload(record: ServerSkillRecord): Record<string, unknown>;
25
+ /**
26
+ * SkillMeta shape for a published row, plus a payload-level "alreadyPublished" flag:
27
+ * true when the accepted publish found the version already recorded with the same
28
+ * digest (an idempotent re-push), so the CLI can distinguish "published as X" from
29
+ * "already published as X" (hasna/apps#1671).
30
+ */
31
+ export declare function publishedPayload(record: ServerSkillRecord, opts?: {
32
+ alreadyPublished?: boolean;
33
+ }): Record<string, unknown>;
26
34
  /**
27
35
  * The HTTP ETag for a published row: the revision id, quoted exactly as RFC 9110 wants.
28
36
  * The quotes are load-bearing — a client that echoes the whole header value back as
@@ -143,7 +151,10 @@ interface ParsedPublish {
143
151
  * measured.
144
152
  */
145
153
  export declare function parsePublishRequest(request: Request, config: SkillsServerConfig): Promise<ParsedPublish>;
146
- export declare function storePublishedSkill(store: SkillsProductStore, artifactStorage: ArtifactStorage, principal: ApiPrincipal, parsed: ParsedPublish, expectedRevisionId?: string): Promise<ServerSkillRecord>;
154
+ export declare function storePublishedSkill(store: SkillsProductStore, artifactStorage: ArtifactStorage, principal: ApiPrincipal, parsed: ParsedPublish, expectedRevisionId?: string): Promise<{
155
+ record: ServerSkillRecord;
156
+ alreadyPublished: boolean;
157
+ }>;
147
158
  /**
148
159
  * Tombstone a published skill (todos d061fcda): the row survives with a tombstone
149
160
  * marker for `tombstoneWindowMs`, so reads answer 410 and a pulling client can
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/skills",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Skills library for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {