@skrr-ai/cli 0.1.60 → 0.1.62

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 (194) hide show
  1. package/dist/base-command.js +16 -0
  2. package/dist/commands/agents/create.d.ts +1 -0
  3. package/dist/commands/agents/create.js +8 -1
  4. package/dist/commands/agents/delete.d.ts +14 -0
  5. package/dist/commands/agents/delete.js +52 -4
  6. package/dist/commands/agents/eval/index.d.ts +38 -0
  7. package/dist/commands/agents/eval/index.js +157 -0
  8. package/dist/commands/agents/eval/list.d.ts +13 -0
  9. package/dist/commands/agents/eval/list.js +53 -0
  10. package/dist/commands/agents/eval/show.d.ts +13 -0
  11. package/dist/commands/agents/eval/show.js +36 -0
  12. package/dist/commands/agents/import.d.ts +37 -0
  13. package/dist/commands/agents/import.js +233 -0
  14. package/dist/commands/agents/pull.d.ts +27 -0
  15. package/dist/commands/agents/pull.js +82 -0
  16. package/dist/commands/agents/push.d.ts +28 -0
  17. package/dist/commands/agents/push.js +112 -0
  18. package/dist/commands/agents/releases/ci-publish.d.ts +32 -0
  19. package/dist/commands/agents/releases/ci-publish.js +99 -0
  20. package/dist/commands/agents/releases/create.d.ts +3 -0
  21. package/dist/commands/agents/releases/create.js +27 -6
  22. package/dist/commands/agents/releases/known-issues/add.d.ts +19 -0
  23. package/dist/commands/agents/releases/known-issues/add.js +43 -0
  24. package/dist/commands/agents/releases/known-issues/list.d.ts +17 -0
  25. package/dist/commands/agents/releases/known-issues/list.js +55 -0
  26. package/dist/commands/agents/releases/known-issues/update.d.ts +18 -0
  27. package/dist/commands/agents/releases/known-issues/update.js +47 -0
  28. package/dist/commands/agents/releases/list.js +25 -3
  29. package/dist/commands/agents/releases/rollback.js +12 -4
  30. package/dist/commands/agents/releases/test-install.d.ts +22 -0
  31. package/dist/commands/agents/releases/test-install.js +70 -0
  32. package/dist/commands/agents/releases/trusted-publishers/list.d.ts +17 -0
  33. package/dist/commands/agents/releases/trusted-publishers/list.js +55 -0
  34. package/dist/commands/agents/releases/trusted-publishers/remove.d.ts +17 -0
  35. package/dist/commands/agents/releases/trusted-publishers/remove.js +45 -0
  36. package/dist/commands/agents/releases/trusted-publishers/set.d.ts +27 -0
  37. package/dist/commands/agents/releases/trusted-publishers/set.js +82 -0
  38. package/dist/commands/agents/update.d.ts +1 -0
  39. package/dist/commands/agents/update.js +8 -1
  40. package/dist/commands/agents/usage-cap.d.ts +20 -0
  41. package/dist/commands/agents/usage-cap.js +76 -0
  42. package/dist/commands/agents/validate.d.ts +22 -0
  43. package/dist/commands/agents/validate.js +66 -0
  44. package/dist/commands/agents/visibility.d.ts +13 -0
  45. package/dist/commands/agents/visibility.js +84 -2
  46. package/dist/commands/commerce/fees/show.d.ts +19 -0
  47. package/dist/commands/commerce/fees/show.js +75 -0
  48. package/dist/commands/earnings/index.d.ts +15 -0
  49. package/dist/commands/earnings/index.js +46 -0
  50. package/dist/commands/earnings/payouts.d.ts +12 -0
  51. package/dist/commands/earnings/payouts.js +39 -0
  52. package/dist/commands/earnings/statements.d.ts +19 -0
  53. package/dist/commands/earnings/statements.js +70 -0
  54. package/dist/commands/goals/key-results/create.d.ts +1 -1
  55. package/dist/commands/goals/key-results/create.js +5 -1
  56. package/dist/commands/harnesses/show.js +11 -1
  57. package/dist/commands/logout.js +31 -0
  58. package/dist/commands/machines/show.js +10 -1
  59. package/dist/commands/managed-execution/show.d.ts +10 -0
  60. package/dist/commands/managed-execution/show.js +60 -0
  61. package/dist/commands/spaces/show.js +35 -1
  62. package/dist/commands/step-up.d.ts +23 -0
  63. package/dist/commands/step-up.js +96 -0
  64. package/dist/commands/store/acquisitions/approve.d.ts +30 -0
  65. package/dist/commands/store/acquisitions/approve.js +100 -0
  66. package/dist/commands/store/acquisitions/decline.d.ts +17 -0
  67. package/dist/commands/store/acquisitions/decline.js +47 -0
  68. package/dist/commands/store/acquisitions/show.d.ts +16 -0
  69. package/dist/commands/store/acquisitions/show.js +49 -0
  70. package/dist/commands/store/admissions/approve.d.ts +19 -0
  71. package/dist/commands/store/admissions/approve.js +50 -0
  72. package/dist/commands/store/admissions/list.d.ts +15 -0
  73. package/dist/commands/store/admissions/list.js +60 -0
  74. package/dist/commands/store/admissions/refuse.d.ts +18 -0
  75. package/dist/commands/store/admissions/refuse.js +49 -0
  76. package/dist/commands/store/advisories/artifact.d.ts +15 -0
  77. package/dist/commands/store/advisories/artifact.js +25 -0
  78. package/dist/commands/store/advisories/cancel.d.ts +13 -0
  79. package/dist/commands/store/advisories/cancel.js +34 -0
  80. package/dist/commands/store/advisories/close.d.ts +18 -0
  81. package/dist/commands/store/advisories/close.js +51 -0
  82. package/dist/commands/store/advisories/confirm.d.ts +17 -0
  83. package/dist/commands/store/advisories/confirm.js +40 -0
  84. package/dist/commands/store/advisories/issue.d.ts +20 -0
  85. package/dist/commands/store/advisories/issue.js +59 -0
  86. package/dist/commands/store/advisories/list.d.ts +15 -0
  87. package/dist/commands/store/advisories/list.js +49 -0
  88. package/dist/commands/store/advisories/show.d.ts +13 -0
  89. package/dist/commands/store/advisories/show.js +34 -0
  90. package/dist/commands/store/artifacts/release.d.ts +16 -0
  91. package/dist/commands/store/artifacts/release.js +31 -0
  92. package/dist/commands/store/artifacts/used-by.d.ts +12 -0
  93. package/dist/commands/store/artifacts/used-by.js +20 -0
  94. package/dist/commands/store/browse.d.ts +5 -0
  95. package/dist/commands/store/browse.js +28 -1
  96. package/dist/commands/store/channel.d.ts +21 -0
  97. package/dist/commands/store/channel.js +62 -0
  98. package/dist/commands/store/follow.d.ts +14 -0
  99. package/dist/commands/store/follow.js +45 -0
  100. package/dist/commands/store/governance/policy.d.ts +18 -5
  101. package/dist/commands/store/governance/policy.js +80 -12
  102. package/dist/commands/store/governance/requests.d.ts +28 -0
  103. package/dist/commands/store/governance/requests.js +116 -0
  104. package/dist/commands/store/install.d.ts +3 -0
  105. package/dist/commands/store/install.js +101 -2
  106. package/dist/commands/store/issues.d.ts +26 -0
  107. package/dist/commands/store/issues.js +118 -0
  108. package/dist/commands/store/maintainers/add.d.ts +13 -0
  109. package/dist/commands/store/maintainers/add.js +23 -0
  110. package/dist/commands/store/maintainers/remove.d.ts +13 -0
  111. package/dist/commands/store/maintainers/remove.js +22 -0
  112. package/dist/commands/store/publishers/approve.d.ts +11 -0
  113. package/dist/commands/store/publishers/approve.js +25 -0
  114. package/dist/commands/store/publishers/claim.d.ts +12 -0
  115. package/dist/commands/store/publishers/claim.js +20 -0
  116. package/dist/commands/store/publishers/confirm.d.ts +11 -0
  117. package/dist/commands/store/publishers/confirm.js +17 -0
  118. package/dist/commands/store/publishers/domains/begin.d.ts +12 -0
  119. package/dist/commands/store/publishers/domains/begin.js +20 -0
  120. package/dist/commands/store/publishers/domains/list.d.ts +9 -0
  121. package/dist/commands/store/publishers/domains/list.js +19 -0
  122. package/dist/commands/store/publishers/domains/verify.d.ts +12 -0
  123. package/dist/commands/store/publishers/domains/verify.js +20 -0
  124. package/dist/commands/store/publishers/namespaces.d.ts +8 -0
  125. package/dist/commands/store/publishers/namespaces.js +16 -0
  126. package/dist/commands/store/publishers/verified.d.ts +11 -0
  127. package/dist/commands/store/publishers/verified.js +34 -0
  128. package/dist/commands/store/refund.d.ts +22 -0
  129. package/dist/commands/store/refund.js +80 -0
  130. package/dist/commands/store/report.d.ts +20 -0
  131. package/dist/commands/store/report.js +59 -0
  132. package/dist/commands/store/reports.d.ts +11 -0
  133. package/dist/commands/store/reports.js +52 -0
  134. package/dist/commands/store/signals.d.ts +18 -0
  135. package/dist/commands/store/signals.js +43 -0
  136. package/dist/commands/store/star.d.ts +17 -0
  137. package/dist/commands/store/star.js +41 -0
  138. package/dist/commands/store/stars.d.ts +10 -0
  139. package/dist/commands/store/stars.js +33 -0
  140. package/dist/commands/store/trial.d.ts +11 -0
  141. package/dist/commands/store/trial.js +17 -0
  142. package/dist/commands/store/uninstall.d.ts +19 -0
  143. package/dist/commands/store/uninstall.js +118 -0
  144. package/dist/commands/store/update.d.ts +2 -0
  145. package/dist/commands/store/update.js +60 -2
  146. package/dist/commands/store/updates.d.ts +10 -4
  147. package/dist/commands/store/updates.js +60 -39
  148. package/dist/commands/store/watch.d.ts +18 -0
  149. package/dist/commands/store/watch.js +44 -0
  150. package/dist/commands/subscriptions/health.d.ts +12 -0
  151. package/dist/commands/subscriptions/health.js +39 -0
  152. package/dist/commands/subscriptions/list.js +3 -2
  153. package/dist/commands/subscriptions/status.js +7 -1
  154. package/dist/commands/subscriptions/subscribe.d.ts +9 -2
  155. package/dist/commands/subscriptions/subscribe.js +141 -12
  156. package/dist/commands/tasks/comments/list.js +9 -1
  157. package/dist/commands/tasks/labels/attach.js +15 -2
  158. package/dist/commands/tasks/show.js +17 -3
  159. package/dist/commands/tasks/update.js +15 -4
  160. package/dist/commands/tasks/updates/add.js +5 -1
  161. package/dist/lib/agent-config.js +1 -0
  162. package/dist/lib/agent-evals.d.ts +71 -0
  163. package/dist/lib/agent-evals.js +359 -0
  164. package/dist/lib/agent-spec.d.ts +28 -0
  165. package/dist/lib/agent-spec.js +58 -0
  166. package/dist/lib/auth-storage.d.ts +12 -0
  167. package/dist/lib/auth-storage.js +0 -33
  168. package/dist/lib/commerce.d.ts +8 -0
  169. package/dist/lib/commerce.js +10 -0
  170. package/dist/lib/earnings.d.ts +36 -0
  171. package/dist/lib/earnings.js +164 -0
  172. package/dist/lib/github-oidc.d.ts +13 -0
  173. package/dist/lib/github-oidc.js +41 -0
  174. package/dist/lib/governed-store.d.ts +43 -2
  175. package/dist/lib/governed-store.js +25 -1
  176. package/dist/lib/label-ref.js +16 -0
  177. package/dist/lib/managed-execution.d.ts +10 -0
  178. package/dist/lib/managed-execution.js +43 -0
  179. package/dist/lib/principal-display.d.ts +20 -0
  180. package/dist/lib/principal-display.js +64 -0
  181. package/dist/lib/space-template-source.d.ts +14 -0
  182. package/dist/lib/space-template-source.js +41 -0
  183. package/dist/lib/step-up.d.ts +21 -0
  184. package/dist/lib/step-up.js +44 -0
  185. package/dist/lib/store-acquisition.d.ts +11 -0
  186. package/dist/lib/store-acquisition.js +40 -0
  187. package/dist/lib/store-advisories.d.ts +50 -0
  188. package/dist/lib/store-advisories.js +62 -0
  189. package/dist/lib/task-closure.js +1 -1
  190. package/dist/lib/web-url.d.ts +11 -0
  191. package/dist/lib/web-url.js +14 -0
  192. package/dist/node_modules/@skrr-ai/data-provider/index.js +25471 -24177
  193. package/oclif.manifest.json +38931 -34119
  194. package/package.json +21 -3
@@ -0,0 +1,233 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const promises_1 = require("node:fs/promises");
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const core_1 = require("@oclif/core");
9
+ const data_provider_1 = require("@skrr-ai/data-provider");
10
+ const base_command_1 = require("../../base-command");
11
+ const agent_spec_1 = require("../../lib/agent-spec");
12
+ /**
13
+ * Bring a Claude Code asset in: a subagent (`.claude/agents/<name>.md`) or a
14
+ * skill (`SKILL.md`, or the directory holding one).
15
+ *
16
+ * A subagent becomes an agent spec document — printed or written with
17
+ * `--output`, or pushed onto an existing agent with `--agent` (the same push
18
+ * as `agents push`). A skill becomes a skill in your library, attached to
19
+ * `--agent` when given.
20
+ *
21
+ * Either way, `hooks` and MCP server commands are NEVER carried: they run on
22
+ * the machine that loads the file, and a portable spec is read on machines
23
+ * that are not yours. What was left out is printed, one line per key, so the
24
+ * import says what it did not do.
25
+ */
26
+ class AgentsImport extends base_command_1.BaseCommand {
27
+ static description = 'Import a Claude Code subagent (.claude/agents/*.md) or SKILL.md; hooks and MCP commands are never imported';
28
+ static examples = [
29
+ '<%= config.bin %> agents import .claude/agents/reviewer.md --output reviewer.agent.json',
30
+ '<%= config.bin %> agents import .claude/agents/reviewer.md --agent <agent-id>',
31
+ '<%= config.bin %> agents import .claude/skills/release-notes --agent <agent-id>',
32
+ '<%= config.bin %> agents import .claude/skills/release-notes/SKILL.md',
33
+ 'cat reviewer.md | <%= config.bin %> agents import - --output reviewer.agent.json',
34
+ ];
35
+ static args = {
36
+ path: core_1.Args.string({
37
+ description: 'A .claude/agents/*.md file, a SKILL.md, a directory containing SKILL.md, or "-" to read a subagent file from stdin',
38
+ required: true,
39
+ ignoreStdin: true,
40
+ }),
41
+ };
42
+ static flags = {
43
+ agent: core_1.Flags.string({
44
+ description: 'Subagent: push the converted spec onto this agent. Skill: attach the new skill to it.',
45
+ }),
46
+ output: core_1.Flags.string({
47
+ char: 'o',
48
+ description: 'Subagent only: write the converted spec document here (omit for stdout)',
49
+ }),
50
+ json: core_1.Flags.boolean({ description: 'Output the result as JSON' }),
51
+ };
52
+ async run() {
53
+ const { args, flags } = await this.parse(AgentsImport);
54
+ // stdin has no file name to route on, so it is read as a subagent file;
55
+ // a SKILL.md is imported by path, where its directory names it.
56
+ const fromStdin = args.path === '-';
57
+ let sourcePath = args.path;
58
+ if (!fromStdin) {
59
+ try {
60
+ if ((await (0, promises_1.stat)(sourcePath)).isDirectory()) {
61
+ sourcePath = node_path_1.default.join(sourcePath, 'SKILL.md');
62
+ }
63
+ }
64
+ catch (err) {
65
+ this.failWithCliError({
66
+ message: `Could not read ${args.path}: ${err.message}`,
67
+ code: 'IMPORT_SOURCE_UNREADABLE',
68
+ exit: 1,
69
+ retryable: false,
70
+ details: { path: args.path },
71
+ });
72
+ }
73
+ }
74
+ let text;
75
+ try {
76
+ text = await (0, agent_spec_1.readSpecSource)(sourcePath);
77
+ }
78
+ catch (err) {
79
+ this.failWithCliError({
80
+ message: `Could not read ${sourcePath}: ${err.message}`,
81
+ code: 'IMPORT_SOURCE_UNREADABLE',
82
+ exit: 1,
83
+ retryable: false,
84
+ details: { path: sourcePath },
85
+ });
86
+ }
87
+ if (fromStdin) {
88
+ await this.importAgent(text, 'stdin', flags);
89
+ return;
90
+ }
91
+ if ((0, data_provider_1.claudeCodeImportKind)(sourcePath) === 'skill') {
92
+ await this.importSkill(text, sourcePath, flags);
93
+ return;
94
+ }
95
+ await this.importAgent(text, sourcePath, flags, sourcePath);
96
+ }
97
+ convert(fn) {
98
+ try {
99
+ return fn();
100
+ }
101
+ catch (err) {
102
+ if (err instanceof data_provider_1.ClaudeCodeImportError) {
103
+ this.failWithCliError({ message: err.message, code: err.code, exit: 1, retryable: false });
104
+ }
105
+ throw err;
106
+ }
107
+ }
108
+ printDropped(dropped) {
109
+ for (const drop of dropped) {
110
+ this.log(`Not imported: ${drop.key} — ${data_provider_1.CLAUDE_CODE_IMPORT_DROP_REASONS[drop.reason]}`);
111
+ }
112
+ }
113
+ /**
114
+ * @param sourceLabel - how messages name the source
115
+ * @param filePath - the file, when there is one; its name is the fallback
116
+ * agent name. stdin has none, so its frontmatter must carry `name`.
117
+ */
118
+ async importAgent(text, sourceLabel, flags, filePath) {
119
+ const { document, dropped } = this.convert(() => (0, data_provider_1.agentSpecFromClaudeCodeAgent)(text, { sourcePath: filePath }));
120
+ // The importer builds only portable fields; checking its output with the
121
+ // same validator as push keeps that a property rather than a promise.
122
+ const validation = (0, data_provider_1.validateAgentSpecDocument)(document);
123
+ if (!validation.ok) {
124
+ this.failWithCliError({
125
+ message: (0, agent_spec_1.issueBlock)(`${sourceLabel} did not convert to a valid agent spec:`, validation.issues),
126
+ code: 'IMPORT_PRODUCED_INVALID_SPEC',
127
+ exit: 1,
128
+ retryable: false,
129
+ details: { issues: validation.issues },
130
+ });
131
+ }
132
+ if (!flags.agent) {
133
+ const content = (0, agent_spec_1.serializeAgentSpecDocument)(document);
134
+ if (!flags.output || flags.output === '-') {
135
+ process.stdout.write(content);
136
+ }
137
+ else {
138
+ try {
139
+ await (0, promises_1.writeFile)(flags.output, content, 'utf8');
140
+ }
141
+ catch (err) {
142
+ this.failWithCliError({
143
+ message: `Could not write ${flags.output}: ${err.message}`,
144
+ code: 'AGENT_SPEC_WRITE_FAILED',
145
+ exit: 1,
146
+ retryable: true,
147
+ details: { path: flags.output },
148
+ });
149
+ }
150
+ if (flags.json) {
151
+ this.log(JSON.stringify({ output: flags.output, document, dropped }, null, 2));
152
+ return;
153
+ }
154
+ this.log(`Wrote ${Object.keys(document.spec).length} field(s) to ${flags.output}.`);
155
+ }
156
+ // stdout carries the document, so the report goes to stderr.
157
+ for (const drop of dropped) {
158
+ process.stderr.write(`Not imported: ${drop.key} — ${data_provider_1.CLAUDE_CODE_IMPORT_DROP_REASONS[drop.reason]}\n`);
159
+ }
160
+ return;
161
+ }
162
+ this.requireAuth();
163
+ let result;
164
+ try {
165
+ result = await data_provider_1.dataService.pushAgentSpec(flags.agent, document);
166
+ }
167
+ catch (err) {
168
+ const refusal = (0, agent_spec_1.refusalIssues)(err);
169
+ if (refusal) {
170
+ this.failWithCliError({
171
+ message: (0, agent_spec_1.issueBlock)(`The server refused the import into agent ${flags.agent}. Nothing was changed.`, refusal.issues),
172
+ code: refusal.code ?? 'AGENT_SPEC_REFUSED',
173
+ exit: 1,
174
+ retryable: false,
175
+ details: { issues: refusal.issues },
176
+ });
177
+ }
178
+ this.handleApiError(err, { subject: `agent ${flags.agent}` });
179
+ }
180
+ if (flags.json) {
181
+ this.log(this.agentJson(flags.agent, { ...result, dropped }));
182
+ return;
183
+ }
184
+ this.log(result.applied.length > 0
185
+ ? `Imported ${sourceLabel} into agent ${flags.agent}: ${result.applied.join(', ')}.`
186
+ : `Agent ${flags.agent} already matches ${sourceLabel}; nothing to change.`);
187
+ this.printDropped(dropped);
188
+ this.printAgentUrl(flags.agent);
189
+ }
190
+ async importSkill(text, sourcePath, flags) {
191
+ if (flags.output) {
192
+ this.failWithCliError({
193
+ message: '--output applies to a subagent file; a SKILL.md is imported as a skill.',
194
+ code: 'IMPORT_FLAG_NOT_APPLICABLE',
195
+ exit: 2,
196
+ retryable: false,
197
+ });
198
+ }
199
+ const { skill, dropped } = this.convert(() => (0, data_provider_1.skillFromSkillMarkdown)(text, { sourcePath }));
200
+ this.requireAuth();
201
+ let created;
202
+ try {
203
+ created = await data_provider_1.dataService.createSkill({
204
+ agentId: flags.agent ?? null,
205
+ name: skill.name,
206
+ description: skill.description,
207
+ content: skill.content,
208
+ frontmatter: skill.frontmatter,
209
+ });
210
+ }
211
+ catch (err) {
212
+ this.handleApiError(err, { subject: `skill ${skill.name}` });
213
+ }
214
+ const skillId = created.id;
215
+ if (flags.agent && skillId) {
216
+ try {
217
+ await data_provider_1.dataService.addAgentSkill({ agentId: flags.agent, skillId });
218
+ }
219
+ catch (err) {
220
+ this.handleApiError(err, { subject: `agent ${flags.agent}` });
221
+ }
222
+ }
223
+ if (flags.json) {
224
+ this.log(JSON.stringify({ skill: created, attachedTo: flags.agent ?? null, dropped }, null, 2));
225
+ return;
226
+ }
227
+ this.log(flags.agent
228
+ ? `Imported skill ${skill.name} (${skillId ?? 'no id returned'}) and attached it to agent ${flags.agent}.`
229
+ : `Imported skill ${skill.name} (${skillId ?? 'no id returned'}) into your library.`);
230
+ this.printDropped(dropped);
231
+ }
232
+ }
233
+ exports.default = AgentsImport;
@@ -0,0 +1,27 @@
1
+ import { BaseCommand } from '../../base-command';
2
+ /**
3
+ * Write an agent out as an agent-as-code document.
4
+ *
5
+ * What comes back is always the AUDIENCE document — the fields another person
6
+ * would receive — never the owner's full row, because a git repository is an
7
+ * audience: it is cloned, forked and pasted into issues by people who could
8
+ * not open the agent. Where the agent runs, who owns it, what it has learned
9
+ * and every credential stay behind; a reference whose target holds a
10
+ * credential (OpenAPI actions) is WITHHELD and named in `withheld`, so an
11
+ * empty list and "not exported" never look alike.
12
+ *
13
+ * Unlike `tones export`, this overwrites `--output`: pull refreshes a tracked
14
+ * file, and the point is that `git diff` then shows what changed.
15
+ */
16
+ export default class AgentsPull extends BaseCommand {
17
+ static description: string;
18
+ static examples: string[];
19
+ static args: {
20
+ id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
21
+ };
22
+ static flags: {
23
+ output: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
24
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
25
+ };
26
+ run(): Promise<void>;
27
+ }
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const promises_1 = require("node:fs/promises");
4
+ const core_1 = require("@oclif/core");
5
+ const data_provider_1 = require("@skrr-ai/data-provider");
6
+ const base_command_1 = require("../../base-command");
7
+ const agent_spec_1 = require("../../lib/agent-spec");
8
+ /**
9
+ * Write an agent out as an agent-as-code document.
10
+ *
11
+ * What comes back is always the AUDIENCE document — the fields another person
12
+ * would receive — never the owner's full row, because a git repository is an
13
+ * audience: it is cloned, forked and pasted into issues by people who could
14
+ * not open the agent. Where the agent runs, who owns it, what it has learned
15
+ * and every credential stay behind; a reference whose target holds a
16
+ * credential (OpenAPI actions) is WITHHELD and named in `withheld`, so an
17
+ * empty list and "not exported" never look alike.
18
+ *
19
+ * Unlike `tones export`, this overwrites `--output`: pull refreshes a tracked
20
+ * file, and the point is that `git diff` then shows what changed.
21
+ */
22
+ class AgentsPull extends base_command_1.BaseCommand {
23
+ static description = 'Write an agent as a portable spec document (agent-as-code); round-trips with `agents push`';
24
+ static examples = [
25
+ '<%= config.bin %> agents pull <agent-id> --output agents/research.agent.json',
26
+ '<%= config.bin %> agents pull <agent-id> | jq .spec.instructions',
27
+ ];
28
+ static args = {
29
+ id: core_1.Args.string({ description: 'Agent ID', required: true, ignoreStdin: true }),
30
+ };
31
+ static flags = {
32
+ output: core_1.Flags.string({
33
+ char: 'o',
34
+ description: 'Write the document to this path (overwrites it). Omit for stdout.',
35
+ }),
36
+ json: core_1.Flags.boolean({ description: 'With --output, print a JSON receipt instead of a line' }),
37
+ };
38
+ async run() {
39
+ this.requireAuth();
40
+ const { args, flags } = await this.parse(AgentsPull);
41
+ let document;
42
+ try {
43
+ document = await data_provider_1.dataService.getAgentSpec(args.id);
44
+ }
45
+ catch (err) {
46
+ this.handleApiError(err, { subject: `agent ${args.id}` });
47
+ }
48
+ const content = (0, agent_spec_1.serializeAgentSpecDocument)(document);
49
+ if (!flags.output || flags.output === '-') {
50
+ process.stdout.write(content);
51
+ return;
52
+ }
53
+ try {
54
+ await (0, promises_1.writeFile)(flags.output, content, 'utf8');
55
+ }
56
+ catch (err) {
57
+ this.failWithCliError({
58
+ message: `Could not write ${flags.output}: ${err.message}`,
59
+ code: 'AGENT_SPEC_WRITE_FAILED',
60
+ exit: 1,
61
+ retryable: true,
62
+ details: { path: flags.output },
63
+ });
64
+ }
65
+ const fields = Object.keys(document.spec ?? {});
66
+ const withheld = document.withheld ?? [];
67
+ if (flags.json) {
68
+ this.log(this.agentJson(args.id, {
69
+ output: flags.output,
70
+ fields,
71
+ withheld,
72
+ }));
73
+ return;
74
+ }
75
+ this.log(`Wrote ${fields.length} portable field(s) of agent ${args.id} to ${flags.output}.`);
76
+ for (const entry of withheld) {
77
+ const count = typeof entry.count === 'number' ? ` (${entry.count})` : '';
78
+ this.log(`Not exported: ${entry.field}${count} — ${entry.reason}`);
79
+ }
80
+ }
81
+ }
82
+ exports.default = AgentsPull;
@@ -0,0 +1,28 @@
1
+ import { BaseCommand } from '../../base-command';
2
+ /**
3
+ * Apply an agent-as-code document to an agent.
4
+ *
5
+ * Refuse-or-apply: a document carrying any field that may not travel is
6
+ * refused WHOLE, first here with no network (the same rules as
7
+ * `agents validate`) and again by the server, which also refuses a change to
8
+ * a field push cannot set. Nothing is ever applied partially, because a push
9
+ * that quietly skipped a field would leave git and the agent disagreeing while
10
+ * both looked right.
11
+ *
12
+ * A field missing from the file is left as it is on the agent and listed, so
13
+ * deleting a line is never mistaken for clearing a field. A field the server
14
+ * derives (`network_agent_release_pins`) is listed when the file's copy is
15
+ * stale, and the server's value kept, so pushing the same file twice works.
16
+ */
17
+ export default class AgentsPush extends BaseCommand {
18
+ static description: string;
19
+ static examples: string[];
20
+ static args: {
21
+ id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
22
+ };
23
+ static flags: {
24
+ file: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
25
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
26
+ };
27
+ run(): Promise<void>;
28
+ }
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const data_provider_1 = require("@skrr-ai/data-provider");
5
+ const base_command_1 = require("../../base-command");
6
+ const agent_spec_1 = require("../../lib/agent-spec");
7
+ /**
8
+ * Apply an agent-as-code document to an agent.
9
+ *
10
+ * Refuse-or-apply: a document carrying any field that may not travel is
11
+ * refused WHOLE, first here with no network (the same rules as
12
+ * `agents validate`) and again by the server, which also refuses a change to
13
+ * a field push cannot set. Nothing is ever applied partially, because a push
14
+ * that quietly skipped a field would leave git and the agent disagreeing while
15
+ * both looked right.
16
+ *
17
+ * A field missing from the file is left as it is on the agent and listed, so
18
+ * deleting a line is never mistaken for clearing a field. A field the server
19
+ * derives (`network_agent_release_pins`) is listed when the file's copy is
20
+ * stale, and the server's value kept, so pushing the same file twice works.
21
+ */
22
+ class AgentsPush extends base_command_1.BaseCommand {
23
+ static description = 'Apply a portable agent spec document to an agent; refuses any field that may not travel';
24
+ static examples = [
25
+ '<%= config.bin %> agents push <agent-id> --file agents/research.agent.json',
26
+ 'cat agent.json | <%= config.bin %> agents push <agent-id> --file -',
27
+ ];
28
+ static args = {
29
+ id: core_1.Args.string({ description: 'Agent ID', required: true, ignoreStdin: true }),
30
+ };
31
+ static flags = {
32
+ file: core_1.Flags.string({
33
+ char: 'f',
34
+ description: 'Agent spec document ("-" for stdin)',
35
+ required: true,
36
+ }),
37
+ json: core_1.Flags.boolean({ description: 'Output the push result as JSON' }),
38
+ };
39
+ async run() {
40
+ this.requireAuth();
41
+ const { args, flags } = await this.parse(AgentsPush);
42
+ let raw;
43
+ try {
44
+ raw = await (0, agent_spec_1.readSpecSource)(flags.file);
45
+ }
46
+ catch (err) {
47
+ this.failWithCliError({
48
+ message: `Could not read ${flags.file}: ${err.message}`,
49
+ code: 'AGENT_SPEC_READ_FAILED',
50
+ exit: 1,
51
+ retryable: true,
52
+ details: { path: flags.file },
53
+ });
54
+ }
55
+ const parsed = (0, agent_spec_1.parseAndValidateAgentSpec)(raw, flags.file);
56
+ if (!parsed.ok) {
57
+ this.failWithCliError({
58
+ message: parsed.message,
59
+ code: 'AGENT_SPEC_NOT_JSON',
60
+ exit: 1,
61
+ retryable: false,
62
+ });
63
+ }
64
+ if (!parsed.validation.ok) {
65
+ this.failWithCliError({
66
+ message: (0, agent_spec_1.issueBlock)(`Refused before sending: ${flags.file} carries fields that may not be pushed. Nothing was changed.`, parsed.validation.issues),
67
+ code: 'AGENT_SPEC_INVALID',
68
+ exit: 1,
69
+ retryable: false,
70
+ details: { issues: parsed.validation.issues },
71
+ });
72
+ }
73
+ let result;
74
+ try {
75
+ result = await data_provider_1.dataService.pushAgentSpec(args.id, parsed.validation.document);
76
+ }
77
+ catch (err) {
78
+ const refusal = (0, agent_spec_1.refusalIssues)(err);
79
+ if (refusal) {
80
+ this.failWithCliError({
81
+ message: (0, agent_spec_1.issueBlock)(`The server refused the push to agent ${args.id}. Nothing was changed.`, refusal.issues),
82
+ code: refusal.code ?? 'AGENT_SPEC_REFUSED',
83
+ status: err.status,
84
+ exit: 1,
85
+ retryable: false,
86
+ details: { issues: refusal.issues },
87
+ });
88
+ }
89
+ this.handleApiError(err, { subject: `agent ${args.id}` });
90
+ }
91
+ if (flags.json) {
92
+ this.log(this.agentJson(args.id, result));
93
+ return;
94
+ }
95
+ if (result.applied.length === 0) {
96
+ this.log(`Agent ${args.id} already matches ${flags.file}; nothing to change.`);
97
+ }
98
+ else {
99
+ this.log(`Updated agent ${args.id}: ${result.applied.join(', ')}.`);
100
+ }
101
+ const derived = result.derived ?? [];
102
+ if (derived.length > 0) {
103
+ this.log(`Not taken from the file, because the server derives it from other fields: ` +
104
+ `${derived.join(', ')}. Run \`skrr agents pull\` to refresh the file.`);
105
+ }
106
+ if (result.untouched.length > 0) {
107
+ this.log(`Left unchanged (not in the file): ${result.untouched.join(', ')}.`);
108
+ }
109
+ this.printAgentUrl(args.id);
110
+ }
111
+ }
112
+ exports.default = AgentsPush;
@@ -0,0 +1,32 @@
1
+ import { BaseCommand } from '../../../base-command';
2
+ /**
3
+ * Publish a release from CI using GitHub OIDC trusted publishing (OSK-12311).
4
+ *
5
+ * The OIDC token IS the credential — no `requireAuth`, no `OVERSKY_TOKEN`. The
6
+ * server verifies the token's issuer, signature and claims, then checks them
7
+ * against the agent's trusted-publisher binding (`releases trusted-publishers
8
+ * set`). Default channel is `private`; `beta` publishes to the beta update
9
+ * channel; `public` is refused until capability-tiered admission ships.
10
+ *
11
+ * The release carries the token's {repo, sha, workflow} as system-observed
12
+ * provenance — an origin record, not a safety badge.
13
+ */
14
+ export default class AgentsReleasesCiPublish extends BaseCommand {
15
+ static description: string;
16
+ static examples: string[];
17
+ static args: {
18
+ agentId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
19
+ };
20
+ static flags: {
21
+ channel: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
22
+ changelog: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
23
+ 'version-major': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
24
+ 'version-minor': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
25
+ 'release-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
26
+ 'offer-version-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
27
+ 'oidc-token': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
28
+ audience: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
29
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
30
+ };
31
+ run(): Promise<void>;
32
+ }
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const data_provider_1 = require("@skrr-ai/data-provider");
5
+ const base_command_1 = require("../../../base-command");
6
+ const github_oidc_1 = require("../../../lib/github-oidc");
7
+ /**
8
+ * Publish a release from CI using GitHub OIDC trusted publishing (OSK-12311).
9
+ *
10
+ * The OIDC token IS the credential — no `requireAuth`, no `OVERSKY_TOKEN`. The
11
+ * server verifies the token's issuer, signature and claims, then checks them
12
+ * against the agent's trusted-publisher binding (`releases trusted-publishers
13
+ * set`). Default channel is `private`; `beta` publishes to the beta update
14
+ * channel; `public` is refused until capability-tiered admission ships.
15
+ *
16
+ * The release carries the token's {repo, sha, workflow} as system-observed
17
+ * provenance — an origin record, not a safety badge.
18
+ */
19
+ class AgentsReleasesCiPublish extends base_command_1.BaseCommand {
20
+ static description = 'Publish a release from GitHub Actions with an OIDC token (no session token needed)';
21
+ static examples = [
22
+ '# In a workflow with `permissions: id-token: write`:\n' +
23
+ '<%= config.bin %> agents releases ci-publish agent_abc123',
24
+ '<%= config.bin %> agents releases ci-publish agent_abc123 --channel beta --release-id ar_xyz',
25
+ '<%= config.bin %> agents releases ci-publish agent_abc123 --oidc-token "$TOKEN" --json',
26
+ ];
27
+ static args = {
28
+ agentId: core_1.Args.string({
29
+ required: true,
30
+ ignoreStdin: true,
31
+ description: 'The agent with a matching trusted-publisher binding',
32
+ }),
33
+ };
34
+ static flags = {
35
+ channel: core_1.Flags.string({
36
+ description: 'Release channel: private (default) or beta. public is refused until ' +
37
+ 'capability-tiered admission ships — promote through the web publish flow',
38
+ options: ['private', 'beta', 'public'],
39
+ default: 'private',
40
+ }),
41
+ changelog: core_1.Flags.string({ description: 'Release changelog' }),
42
+ 'version-major': core_1.Flags.integer(),
43
+ 'version-minor': core_1.Flags.integer(),
44
+ 'release-id': core_1.Flags.string({
45
+ description: 'Immutable release id (required for --channel beta)',
46
+ }),
47
+ 'offer-version-id': core_1.Flags.string({
48
+ description: "Offer to bind for --channel beta (defaults to the listing's current offer)",
49
+ }),
50
+ 'oidc-token': core_1.Flags.string({
51
+ description: 'A GitHub Actions OIDC token. Without it the command requests one from ' +
52
+ 'ACTIONS_ID_TOKEN_REQUEST_* — present only when the workflow sets ' +
53
+ '`permissions: id-token: write`',
54
+ }),
55
+ audience: core_1.Flags.string({
56
+ description: "Audience to request the OIDC token with (default: the job's default; " +
57
+ 'the API checks it against GITHUB_ACTIONS_OIDC_AUDIENCE or DOMAIN_SERVER)',
58
+ }),
59
+ json: core_1.Flags.boolean({ description: 'Output JSON' }),
60
+ };
61
+ async run() {
62
+ // Deliberately NOT requireAuth(): the OIDC token is the credential.
63
+ const { args, flags } = await this.parse(AgentsReleasesCiPublish);
64
+ let idToken = flags['oidc-token'];
65
+ if (!idToken) {
66
+ try {
67
+ idToken = await (0, github_oidc_1.fetchGitHubActionsOidcToken)(flags.audience);
68
+ }
69
+ catch (err) {
70
+ this.error(err.message, { exit: 2 });
71
+ }
72
+ }
73
+ let result;
74
+ try {
75
+ result = await data_provider_1.dataService.publishAgentReleaseFromCi({
76
+ agentId: args.agentId,
77
+ idToken,
78
+ channel: flags.channel,
79
+ changelog: flags.changelog,
80
+ versionMajor: flags['version-major'],
81
+ versionMinor: flags['version-minor'],
82
+ releaseId: flags['release-id'],
83
+ offerVersionId: flags['offer-version-id'],
84
+ });
85
+ }
86
+ catch (err) {
87
+ this.handleApiError(err);
88
+ }
89
+ if (flags.json) {
90
+ this.log(JSON.stringify(result, null, 2));
91
+ return;
92
+ }
93
+ const source = result.provenance?.source;
94
+ this.log(`${result.replayed ? 'Replayed' : 'Published'} ${result.visibility} release ` +
95
+ `${result.versionLabel} (${result.id}) for agent ${args.agentId}` +
96
+ (source?.repository ? ` from ${source.repository}@${source.sha}` : ''));
97
+ }
98
+ }
99
+ exports.default = AgentsReleasesCiPublish;
@@ -9,6 +9,9 @@ export default class AgentsReleasesCreate extends BaseCommand {
9
9
  'version-major': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
10
10
  'version-minor': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
11
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
12
+ beta: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
13
+ 'release-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
14
+ 'offer-version-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
12
15
  };
13
16
  run(): Promise<void>;
14
17
  }
@@ -11,16 +11,37 @@ class AgentsReleasesCreate extends base_command_1.BaseCommand {
11
11
  'version-major': core_1.Flags.integer(),
12
12
  'version-minor': core_1.Flags.integer(),
13
13
  json: core_1.Flags.boolean({ description: 'Output JSON' }),
14
+ beta: core_1.Flags.boolean({
15
+ description: 'Publish on the beta update channel (OSK-12288): reaches only copies whose channel is `beta` — needs a predeclared release id and binds the listing offer',
16
+ }),
17
+ 'release-id': core_1.Flags.string({ description: 'Immutable release id (required for --beta)' }),
18
+ 'offer-version-id': core_1.Flags.string({
19
+ description: "Offer to bind (defaults to the listing's current offer)",
20
+ }),
14
21
  };
15
22
  async run() {
16
23
  this.requireAuth();
17
24
  const { args, flags } = await this.parse(AgentsReleasesCreate);
18
- const result = await data_provider_1.dataService.createPrivateAgentRelease({
19
- agentId: args.agentId,
20
- changelog: flags.changelog,
21
- versionMajor: flags['version-major'],
22
- versionMinor: flags['version-minor'],
23
- });
25
+ if (flags.beta && !flags['release-id']) {
26
+ this.error('--beta requires --release-id, a predeclared immutable release id (ar_…)', {
27
+ exit: 2,
28
+ });
29
+ }
30
+ const result = flags.beta
31
+ ? await data_provider_1.dataService.createBetaAgentRelease({
32
+ agentId: args.agentId,
33
+ changelog: flags.changelog,
34
+ versionMajor: flags['version-major'],
35
+ versionMinor: flags['version-minor'],
36
+ releaseId: flags['release-id'],
37
+ offerVersionId: flags['offer-version-id'],
38
+ })
39
+ : await data_provider_1.dataService.createPrivateAgentRelease({
40
+ agentId: args.agentId,
41
+ changelog: flags.changelog,
42
+ versionMajor: flags['version-major'],
43
+ versionMinor: flags['version-minor'],
44
+ });
24
45
  this.log(flags.json
25
46
  ? this.agentJson(args.agentId, result)
26
47
  : `Created release for agent ${args.agentId}`);