@runcofactor/cli 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +125 -0
- package/dist/api-catalog-GFGCLVS4.js +401 -0
- package/dist/api-catalog-GFGCLVS4.js.map +1 -0
- package/dist/attachment-SJC7D7FY.js +276 -0
- package/dist/attachment-SJC7D7FY.js.map +1 -0
- package/dist/auth-EN6NQCJY.js +31 -0
- package/dist/auth-EN6NQCJY.js.map +1 -0
- package/dist/bin.js +7 -0
- package/dist/bin.js.map +1 -0
- package/dist/chunk-3CZU7XCS.js +272 -0
- package/dist/chunk-3CZU7XCS.js.map +1 -0
- package/dist/chunk-4NRDONSC.js +1048 -0
- package/dist/chunk-4NRDONSC.js.map +1 -0
- package/dist/chunk-4PNOV7OV.js +51980 -0
- package/dist/chunk-4PNOV7OV.js.map +1 -0
- package/dist/chunk-52IO7ACJ.js +2941 -0
- package/dist/chunk-52IO7ACJ.js.map +1 -0
- package/dist/chunk-6LEZCKKV.js +663 -0
- package/dist/chunk-6LEZCKKV.js.map +1 -0
- package/dist/chunk-A4OFTUVV.js +170 -0
- package/dist/chunk-A4OFTUVV.js.map +1 -0
- package/dist/chunk-B2VISN2V.js +2459 -0
- package/dist/chunk-B2VISN2V.js.map +1 -0
- package/dist/chunk-CLAWT7BJ.js +271 -0
- package/dist/chunk-CLAWT7BJ.js.map +1 -0
- package/dist/chunk-GKY2KXO5.js +281 -0
- package/dist/chunk-GKY2KXO5.js.map +1 -0
- package/dist/chunk-I4QLI3JO.js +413 -0
- package/dist/chunk-I4QLI3JO.js.map +1 -0
- package/dist/chunk-IMPZAX6L.js +180 -0
- package/dist/chunk-IMPZAX6L.js.map +1 -0
- package/dist/chunk-J6SH7GQT.js +241 -0
- package/dist/chunk-J6SH7GQT.js.map +1 -0
- package/dist/chunk-JDBCZ3Z2.js +298 -0
- package/dist/chunk-JDBCZ3Z2.js.map +1 -0
- package/dist/chunk-JICSYFRJ.js +46 -0
- package/dist/chunk-JICSYFRJ.js.map +1 -0
- package/dist/chunk-JWHYXEA2.js +32 -0
- package/dist/chunk-JWHYXEA2.js.map +1 -0
- package/dist/chunk-N7HFALX3.js +88 -0
- package/dist/chunk-N7HFALX3.js.map +1 -0
- package/dist/chunk-Q4BO4Z5V.js +178 -0
- package/dist/chunk-Q4BO4Z5V.js.map +1 -0
- package/dist/chunk-QFDOWABX.js +195 -0
- package/dist/chunk-QFDOWABX.js.map +1 -0
- package/dist/chunk-SJJW77WN.js +605 -0
- package/dist/chunk-SJJW77WN.js.map +1 -0
- package/dist/chunk-VKVL7WBN.js +50 -0
- package/dist/chunk-VKVL7WBN.js.map +1 -0
- package/dist/chunk-WOHL4FTB.js +353 -0
- package/dist/chunk-WOHL4FTB.js.map +1 -0
- package/dist/chunk-XQXVG7RA.js +426 -0
- package/dist/chunk-XQXVG7RA.js.map +1 -0
- package/dist/chunk-ZD3KHESI.js +94 -0
- package/dist/chunk-ZD3KHESI.js.map +1 -0
- package/dist/credential-COLTBV6D.js +450 -0
- package/dist/credential-COLTBV6D.js.map +1 -0
- package/dist/credential-template-EEPYFG7R.js +291 -0
- package/dist/credential-template-EEPYFG7R.js.map +1 -0
- package/dist/debug-workflow-KOVH5GOP.js +259 -0
- package/dist/debug-workflow-KOVH5GOP.js.map +1 -0
- package/dist/dist-44PZR7BQ.js +423 -0
- package/dist/dist-44PZR7BQ.js.map +1 -0
- package/dist/docs-3SSORHB5.js +366 -0
- package/dist/docs-3SSORHB5.js.map +1 -0
- package/dist/doctor-OTSIWV6G.js +132 -0
- package/dist/doctor-OTSIWV6G.js.map +1 -0
- package/dist/feature-flag-T2LRZME3.js +283 -0
- package/dist/feature-flag-T2LRZME3.js.map +1 -0
- package/dist/file-type-S3UUBVCT.js +4205 -0
- package/dist/file-type-S3UUBVCT.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +982 -0
- package/dist/index.js.map +1 -0
- package/dist/init-TGWRECT2.js +208 -0
- package/dist/init-TGWRECT2.js.map +1 -0
- package/dist/install-DXSNWZKO.js +295 -0
- package/dist/install-DXSNWZKO.js.map +1 -0
- package/dist/issues-XIZOPX6T.js +564 -0
- package/dist/issues-XIZOPX6T.js.map +1 -0
- package/dist/knobs-NBINZIUB.js +295 -0
- package/dist/knobs-NBINZIUB.js.map +1 -0
- package/dist/list-3TDHK637.js +59 -0
- package/dist/list-3TDHK637.js.map +1 -0
- package/dist/local-HICVD6PU.js +100 -0
- package/dist/local-HICVD6PU.js.map +1 -0
- package/dist/login-UOIUXVUK.js +315 -0
- package/dist/login-UOIUXVUK.js.map +1 -0
- package/dist/mcp-54IJEOUA.js +1956 -0
- package/dist/mcp-54IJEOUA.js.map +1 -0
- package/dist/pdf-extract-ABWV3L5X.js +13 -0
- package/dist/pdf-extract-ABWV3L5X.js.map +1 -0
- package/dist/pdfjs-DQ2YA5S3.js +41561 -0
- package/dist/pdfjs-DQ2YA5S3.js.map +1 -0
- package/dist/property-UXLOLPTD.js +701 -0
- package/dist/property-UXLOLPTD.js.map +1 -0
- package/dist/property-skill-guide.md +189 -0
- package/dist/psql-BYUUNLGG.js +115 -0
- package/dist/psql-BYUUNLGG.js.map +1 -0
- package/dist/record-4TR2UIIS.js +233 -0
- package/dist/record-4TR2UIIS.js.map +1 -0
- package/dist/redis-35VBUYW7.js +116 -0
- package/dist/redis-35VBUYW7.js.map +1 -0
- package/dist/release-OOLTUBUT.js +354 -0
- package/dist/release-OOLTUBUT.js.map +1 -0
- package/dist/sandbox-XGSUU6G7.js +2046 -0
- package/dist/sandbox-XGSUU6G7.js.map +1 -0
- package/dist/scenarios-GWLJEGHA.js +280 -0
- package/dist/scenarios-GWLJEGHA.js.map +1 -0
- package/dist/session-MYFNZPRP.js +2414 -0
- package/dist/session-MYFNZPRP.js.map +1 -0
- package/dist/skill-KM34LDMO.js +1839 -0
- package/dist/skill-KM34LDMO.js.map +1 -0
- package/dist/skills/debug-run/SKILL.md +262 -0
- package/dist/skills/debug-run/history/1.0.0.md +244 -0
- package/dist/skills/debug-run/history/1.0.1.md +245 -0
- package/dist/skills/debug-run/history/1.0.2.md +254 -0
- package/dist/skills/debug-run/history/1.1.0.md +262 -0
- package/dist/skills/debug-run/version.json +3 -0
- package/dist/spec-RA3CFEKG.js +951 -0
- package/dist/spec-RA3CFEKG.js.map +1 -0
- package/dist/src-LB4HBTJQ.js +1516 -0
- package/dist/src-LB4HBTJQ.js.map +1 -0
- package/dist/src-N3TPKGTY.js +244 -0
- package/dist/src-N3TPKGTY.js.map +1 -0
- package/dist/src-UVDX5UP6.js +17 -0
- package/dist/src-UVDX5UP6.js.map +1 -0
- package/dist/start-PSEQSQA3.js +151 -0
- package/dist/start-PSEQSQA3.js.map +1 -0
- package/dist/tag-YY6YAABQ.js +22 -0
- package/dist/tag-YY6YAABQ.js.map +1 -0
- package/dist/task-IQC3YR5K.js +922 -0
- package/dist/task-IQC3YR5K.js.map +1 -0
- package/dist/test-suite-DZNJFXDW.js +394 -0
- package/dist/test-suite-DZNJFXDW.js.map +1 -0
- package/dist/trace-HXIW7U2D.js +14 -0
- package/dist/trace-HXIW7U2D.js.map +1 -0
- package/dist/triage-ORG45R5W.js +16 -0
- package/dist/triage-ORG45R5W.js.map +1 -0
- package/dist/upgrade-L2VYMP2V.js +61 -0
- package/dist/upgrade-L2VYMP2V.js.map +1 -0
- package/dist/workflow-XYFH5LTP.js +3708 -0
- package/dist/workflow-XYFH5LTP.js.map +1 -0
- package/dist/workflow-cache-NQJQFWMV.js +253 -0
- package/dist/workflow-cache-NQJQFWMV.js.map +1 -0
- package/dist/workflow-debug-BGD4UIXU.js +927 -0
- package/dist/workflow-debug-BGD4UIXU.js.map +1 -0
- package/dist/workflow-proposals-MTUDX46O.js +382 -0
- package/dist/workflow-proposals-MTUDX46O.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,701 @@
|
|
|
1
|
+
import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
apiRequest,
|
|
4
|
+
fetchProperties,
|
|
5
|
+
getApplicationArg
|
|
6
|
+
} from "./chunk-WOHL4FTB.js";
|
|
7
|
+
import "./chunk-SJJW77WN.js";
|
|
8
|
+
import "./chunk-3CZU7XCS.js";
|
|
9
|
+
import {
|
|
10
|
+
getArgValue,
|
|
11
|
+
hasFlag,
|
|
12
|
+
resolveConfig
|
|
13
|
+
} from "./chunk-A4OFTUVV.js";
|
|
14
|
+
import "./chunk-JWHYXEA2.js";
|
|
15
|
+
import "./chunk-VKVL7WBN.js";
|
|
16
|
+
|
|
17
|
+
// src/property.ts
|
|
18
|
+
import process2 from "process";
|
|
19
|
+
|
|
20
|
+
// src/property-skill.ts
|
|
21
|
+
import { readFileSync } from "fs";
|
|
22
|
+
import { dirname, join } from "path";
|
|
23
|
+
import { fileURLToPath } from "url";
|
|
24
|
+
import process from "process";
|
|
25
|
+
var HERE = dirname(fileURLToPath(import.meta.url));
|
|
26
|
+
var GUIDE_PATH = join(HERE, "property-skill-guide.md");
|
|
27
|
+
var SECTIONS = [
|
|
28
|
+
"general",
|
|
29
|
+
"technology",
|
|
30
|
+
"product",
|
|
31
|
+
"ui",
|
|
32
|
+
"tenancy",
|
|
33
|
+
"auth",
|
|
34
|
+
"roles_permissions",
|
|
35
|
+
"navigation",
|
|
36
|
+
"feature_gating",
|
|
37
|
+
"environments",
|
|
38
|
+
"data_lifecycle",
|
|
39
|
+
"async_realtime",
|
|
40
|
+
"localization",
|
|
41
|
+
"feedback_errors",
|
|
42
|
+
"idiosyncrasies"
|
|
43
|
+
];
|
|
44
|
+
function printSkillHelp() {
|
|
45
|
+
console.log(
|
|
46
|
+
[
|
|
47
|
+
"canary application skill: Manage an application's app skill (per-application knowledge for QA browser agents). Alias: canary property skill. (--property accepted as an alias for --application.)",
|
|
48
|
+
"",
|
|
49
|
+
"Sub-commands:",
|
|
50
|
+
" guide Print the full authoring methodology (start here)",
|
|
51
|
+
" list [--application <id>] [--section S] [--format json|table]",
|
|
52
|
+
" get --application <id> --section S --key K [--version N] [--format json|md]",
|
|
53
|
+
' set --application <id> --section S --key K --label L --content @file|"text" [--source-id <repo@sha>]',
|
|
54
|
+
" delete --application <id> --section S --key K",
|
|
55
|
+
" history --application <id> --section S --key K [--format json|table]",
|
|
56
|
+
" export --application <id> [--format md|json]",
|
|
57
|
+
" import --application <id> --file <bundle.json> [--source-id <repo@sha>]",
|
|
58
|
+
"",
|
|
59
|
+
"New to app skills? Run `canary application skill guide` for the authoring methodology.",
|
|
60
|
+
"",
|
|
61
|
+
"Sections:",
|
|
62
|
+
" " + SECTIONS.join(", "),
|
|
63
|
+
"",
|
|
64
|
+
"Notes:",
|
|
65
|
+
" --content @path reads content from a file (preferred for multi-line markdown)",
|
|
66
|
+
' --content "text" literal content string',
|
|
67
|
+
' Source defaults to "cli". Provide --source-id <repo@sha> for provenance.',
|
|
68
|
+
"",
|
|
69
|
+
"Bundle.json shape for import:",
|
|
70
|
+
' { "items": [ { "section": S, "itemKey": K, "itemLabel": L, "content": "..." }, ... ] }'
|
|
71
|
+
].join("\n")
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
function readContent(value) {
|
|
75
|
+
if (value.startsWith("@")) {
|
|
76
|
+
const path = value.slice(1);
|
|
77
|
+
return readFileSync(path, "utf8");
|
|
78
|
+
}
|
|
79
|
+
return value;
|
|
80
|
+
}
|
|
81
|
+
function isSection(s) {
|
|
82
|
+
return !!s && SECTIONS.includes(s);
|
|
83
|
+
}
|
|
84
|
+
async function handleList(argv, apiUrl, token) {
|
|
85
|
+
const propertyId = getApplicationArg(argv);
|
|
86
|
+
const section = getArgValue(argv, "--section");
|
|
87
|
+
const format = getArgValue(argv, "--format") ?? (hasFlag(argv, "--json") ? "json" : "table");
|
|
88
|
+
if (!propertyId) {
|
|
89
|
+
console.error("Error: --application is required (alias: --property).");
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
const result = await apiRequest(
|
|
93
|
+
apiUrl,
|
|
94
|
+
token,
|
|
95
|
+
"GET",
|
|
96
|
+
`/org/properties/${propertyId}/context`
|
|
97
|
+
);
|
|
98
|
+
if (!result.ok) {
|
|
99
|
+
console.error(`Error: ${result.error ?? "Unknown error"}`);
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
let items = result.data?.items ?? [];
|
|
103
|
+
if (section) items = items.filter((i) => i.section === section);
|
|
104
|
+
if (format === "json") {
|
|
105
|
+
console.log(JSON.stringify(items, null, 2));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (items.length === 0) {
|
|
109
|
+
console.log("(no items)");
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
113
|
+
for (const item of items) {
|
|
114
|
+
const arr = grouped.get(item.section) ?? [];
|
|
115
|
+
arr.push(item);
|
|
116
|
+
grouped.set(item.section, arr);
|
|
117
|
+
}
|
|
118
|
+
for (const sec of SECTIONS) {
|
|
119
|
+
const arr = grouped.get(sec);
|
|
120
|
+
if (!arr || arr.length === 0) continue;
|
|
121
|
+
console.log(`
|
|
122
|
+
[${sec}]`);
|
|
123
|
+
for (const item of arr) {
|
|
124
|
+
const provenance = item.source === "cli" && item.sourceId ? ` (${item.sourceId})` : item.source !== "cli" ? ` (${item.source})` : "";
|
|
125
|
+
console.log(` ${item.itemKey} \u2014 ${item.itemLabel}${provenance}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async function handleGet(argv, apiUrl, token) {
|
|
130
|
+
const propertyId = getApplicationArg(argv);
|
|
131
|
+
const section = getArgValue(argv, "--section");
|
|
132
|
+
const itemKey = getArgValue(argv, "--key");
|
|
133
|
+
const versionArg = getArgValue(argv, "--version");
|
|
134
|
+
const format = getArgValue(argv, "--format") ?? "md";
|
|
135
|
+
if (!propertyId || !section || !itemKey) {
|
|
136
|
+
console.error("Error: --application, --section, --key are required.");
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
if (!isSection(section)) {
|
|
140
|
+
console.error(`Error: invalid section "${section}". One of: ${SECTIONS.join(", ")}`);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
if (versionArg) {
|
|
144
|
+
const v = Number(versionArg);
|
|
145
|
+
const result2 = await apiRequest(
|
|
146
|
+
apiUrl,
|
|
147
|
+
token,
|
|
148
|
+
"GET",
|
|
149
|
+
`/org/properties/${propertyId}/context/history?section=${section}&itemKey=${encodeURIComponent(itemKey)}`
|
|
150
|
+
);
|
|
151
|
+
if (!result2.ok) {
|
|
152
|
+
console.error(`Error: ${result2.error ?? "Unknown error"}`);
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
const item2 = (result2.data ?? []).find((i) => i.version === v);
|
|
156
|
+
if (!item2) {
|
|
157
|
+
console.error(`Error: no version ${v} for ${section}/${itemKey}`);
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
printItem(item2, format);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const result = await apiRequest(
|
|
164
|
+
apiUrl,
|
|
165
|
+
token,
|
|
166
|
+
"GET",
|
|
167
|
+
`/org/properties/${propertyId}/context`
|
|
168
|
+
);
|
|
169
|
+
if (!result.ok) {
|
|
170
|
+
console.error(`Error: ${result.error ?? "Unknown error"}`);
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
const item = (result.data?.items ?? []).find(
|
|
174
|
+
(i) => i.section === section && i.itemKey === itemKey
|
|
175
|
+
);
|
|
176
|
+
if (!item) {
|
|
177
|
+
console.error(`Error: no item ${section}/${itemKey}`);
|
|
178
|
+
process.exit(1);
|
|
179
|
+
}
|
|
180
|
+
printItem(item, format);
|
|
181
|
+
}
|
|
182
|
+
function printItem(item, format) {
|
|
183
|
+
if (format === "json") {
|
|
184
|
+
console.log(JSON.stringify(item, null, 2));
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
console.log(`# ${item.itemLabel}`);
|
|
188
|
+
console.log(`section: ${item.section}`);
|
|
189
|
+
console.log(`key: ${item.itemKey}`);
|
|
190
|
+
console.log(`version: ${item.version}`);
|
|
191
|
+
console.log(`source: ${item.source}${item.sourceId ? ` (${item.sourceId})` : ""}`);
|
|
192
|
+
console.log("");
|
|
193
|
+
console.log(item.content);
|
|
194
|
+
}
|
|
195
|
+
async function handleSet(argv, apiUrl, token) {
|
|
196
|
+
const propertyId = getApplicationArg(argv);
|
|
197
|
+
const section = getArgValue(argv, "--section");
|
|
198
|
+
const itemKey = getArgValue(argv, "--key");
|
|
199
|
+
const itemLabel = getArgValue(argv, "--label");
|
|
200
|
+
const contentArg = getArgValue(argv, "--content");
|
|
201
|
+
const sourceId = getArgValue(argv, "--source-id");
|
|
202
|
+
if (!propertyId || !section || !itemKey || !itemLabel || contentArg === void 0) {
|
|
203
|
+
console.error("Error: --application, --section, --key, --label, --content are required.");
|
|
204
|
+
process.exit(1);
|
|
205
|
+
}
|
|
206
|
+
if (!isSection(section)) {
|
|
207
|
+
console.error(`Error: invalid section "${section}". One of: ${SECTIONS.join(", ")}`);
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
const content = readContent(contentArg);
|
|
211
|
+
const body = {
|
|
212
|
+
section,
|
|
213
|
+
itemKey,
|
|
214
|
+
itemLabel,
|
|
215
|
+
content,
|
|
216
|
+
source: "cli"
|
|
217
|
+
};
|
|
218
|
+
if (sourceId !== void 0) body.sourceId = sourceId;
|
|
219
|
+
const result = await apiRequest(
|
|
220
|
+
apiUrl,
|
|
221
|
+
token,
|
|
222
|
+
"PUT",
|
|
223
|
+
`/org/properties/${propertyId}/context/items`,
|
|
224
|
+
body
|
|
225
|
+
);
|
|
226
|
+
if (!result.ok) {
|
|
227
|
+
console.error(`Error: ${result.error ?? "Unknown error"}`);
|
|
228
|
+
process.exit(1);
|
|
229
|
+
}
|
|
230
|
+
console.log(`Set [${section}] ${itemKey} (v${result.data?.version ?? "?"})`);
|
|
231
|
+
}
|
|
232
|
+
async function handleDelete(argv, apiUrl, token) {
|
|
233
|
+
const propertyId = getApplicationArg(argv);
|
|
234
|
+
const section = getArgValue(argv, "--section");
|
|
235
|
+
const itemKey = getArgValue(argv, "--key");
|
|
236
|
+
if (!propertyId || !section || !itemKey) {
|
|
237
|
+
console.error("Error: --application, --section, --key are required.");
|
|
238
|
+
process.exit(1);
|
|
239
|
+
}
|
|
240
|
+
if (!isSection(section)) {
|
|
241
|
+
console.error(`Error: invalid section "${section}". One of: ${SECTIONS.join(", ")}`);
|
|
242
|
+
process.exit(1);
|
|
243
|
+
}
|
|
244
|
+
const result = await apiRequest(
|
|
245
|
+
apiUrl,
|
|
246
|
+
token,
|
|
247
|
+
"DELETE",
|
|
248
|
+
`/org/properties/${propertyId}/context/items`,
|
|
249
|
+
{ section, itemKey }
|
|
250
|
+
);
|
|
251
|
+
if (!result.ok) {
|
|
252
|
+
console.error(`Error: ${result.error ?? "Unknown error"}`);
|
|
253
|
+
process.exit(1);
|
|
254
|
+
}
|
|
255
|
+
console.log(`Deleted [${section}] ${itemKey}`);
|
|
256
|
+
}
|
|
257
|
+
async function handleHistory(argv, apiUrl, token) {
|
|
258
|
+
const propertyId = getApplicationArg(argv);
|
|
259
|
+
const section = getArgValue(argv, "--section");
|
|
260
|
+
const itemKey = getArgValue(argv, "--key");
|
|
261
|
+
const format = getArgValue(argv, "--format") ?? "table";
|
|
262
|
+
if (!propertyId || !section || !itemKey) {
|
|
263
|
+
console.error("Error: --application, --section, --key are required.");
|
|
264
|
+
process.exit(1);
|
|
265
|
+
}
|
|
266
|
+
if (!isSection(section)) {
|
|
267
|
+
console.error(`Error: invalid section "${section}". One of: ${SECTIONS.join(", ")}`);
|
|
268
|
+
process.exit(1);
|
|
269
|
+
}
|
|
270
|
+
const result = await apiRequest(
|
|
271
|
+
apiUrl,
|
|
272
|
+
token,
|
|
273
|
+
"GET",
|
|
274
|
+
`/org/properties/${propertyId}/context/history?section=${section}&itemKey=${encodeURIComponent(itemKey)}`
|
|
275
|
+
);
|
|
276
|
+
if (!result.ok) {
|
|
277
|
+
console.error(`Error: ${result.error ?? "Unknown error"}`);
|
|
278
|
+
process.exit(1);
|
|
279
|
+
}
|
|
280
|
+
const versions = result.data ?? [];
|
|
281
|
+
if (format === "json") {
|
|
282
|
+
console.log(JSON.stringify(versions, null, 2));
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
if (versions.length === 0) {
|
|
286
|
+
console.log("(no history)");
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
for (const v of versions) {
|
|
290
|
+
const provenance = v.sourceId ? ` (${v.sourceId})` : "";
|
|
291
|
+
console.log(`v${v.version} ${v.source}${provenance} ${v.createdAt}`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
async function handleExport(argv, apiUrl, token) {
|
|
295
|
+
const propertyId = getApplicationArg(argv);
|
|
296
|
+
const format = getArgValue(argv, "--format") ?? "md";
|
|
297
|
+
if (!propertyId) {
|
|
298
|
+
console.error("Error: --application is required (alias: --property).");
|
|
299
|
+
process.exit(1);
|
|
300
|
+
}
|
|
301
|
+
const result = await apiRequest(
|
|
302
|
+
apiUrl,
|
|
303
|
+
token,
|
|
304
|
+
"GET",
|
|
305
|
+
`/org/properties/${propertyId}/context`
|
|
306
|
+
);
|
|
307
|
+
if (!result.ok) {
|
|
308
|
+
console.error(`Error: ${result.error ?? "Unknown error"}`);
|
|
309
|
+
process.exit(1);
|
|
310
|
+
}
|
|
311
|
+
const items = result.data?.items ?? [];
|
|
312
|
+
if (format === "json") {
|
|
313
|
+
console.log(JSON.stringify({ items }, null, 2));
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
317
|
+
for (const item of items) {
|
|
318
|
+
const arr = grouped.get(item.section) ?? [];
|
|
319
|
+
arr.push(item);
|
|
320
|
+
grouped.set(item.section, arr);
|
|
321
|
+
}
|
|
322
|
+
for (const sec of SECTIONS) {
|
|
323
|
+
const arr = grouped.get(sec);
|
|
324
|
+
if (!arr || arr.length === 0) continue;
|
|
325
|
+
console.log(`## ${sec}`);
|
|
326
|
+
console.log("");
|
|
327
|
+
for (const item of arr) {
|
|
328
|
+
console.log(`### ${item.itemLabel} (\`${item.itemKey}\`)`);
|
|
329
|
+
console.log("");
|
|
330
|
+
console.log(item.content);
|
|
331
|
+
console.log("");
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
async function handleImport(argv, apiUrl, token) {
|
|
336
|
+
const propertyId = getApplicationArg(argv);
|
|
337
|
+
const file = getArgValue(argv, "--file");
|
|
338
|
+
const sourceId = getArgValue(argv, "--source-id");
|
|
339
|
+
if (!propertyId || !file) {
|
|
340
|
+
console.error("Error: --application and --file are required.");
|
|
341
|
+
process.exit(1);
|
|
342
|
+
}
|
|
343
|
+
let bundle;
|
|
344
|
+
try {
|
|
345
|
+
bundle = JSON.parse(readFileSync(file, "utf8"));
|
|
346
|
+
} catch (err) {
|
|
347
|
+
console.error(`Error parsing ${file}: ${err.message}`);
|
|
348
|
+
process.exit(1);
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
if (!bundle.items || !Array.isArray(bundle.items)) {
|
|
352
|
+
console.error('Error: bundle.json must have an "items" array.');
|
|
353
|
+
process.exit(1);
|
|
354
|
+
}
|
|
355
|
+
let ok = 0;
|
|
356
|
+
let fail = 0;
|
|
357
|
+
for (const item of bundle.items) {
|
|
358
|
+
if (!isSection(item.section)) {
|
|
359
|
+
console.error(` \u2717 [${item.section}] ${item.itemKey}: invalid section`);
|
|
360
|
+
fail++;
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
const body = {
|
|
364
|
+
section: item.section,
|
|
365
|
+
itemKey: item.itemKey,
|
|
366
|
+
itemLabel: item.itemLabel,
|
|
367
|
+
content: item.content,
|
|
368
|
+
source: "cli"
|
|
369
|
+
};
|
|
370
|
+
if (sourceId) body.sourceId = sourceId;
|
|
371
|
+
const result = await apiRequest(
|
|
372
|
+
apiUrl,
|
|
373
|
+
token,
|
|
374
|
+
"PUT",
|
|
375
|
+
`/org/properties/${propertyId}/context/items`,
|
|
376
|
+
body
|
|
377
|
+
);
|
|
378
|
+
if (result.ok) {
|
|
379
|
+
console.log(` \u2713 [${item.section}] ${item.itemKey} (v${result.data?.version ?? "?"})`);
|
|
380
|
+
ok++;
|
|
381
|
+
} else {
|
|
382
|
+
console.error(` \u2717 [${item.section}] ${item.itemKey}: ${result.error ?? "Unknown error"}`);
|
|
383
|
+
fail++;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
console.log(`
|
|
387
|
+
Imported ${ok}/${ok + fail} items${fail ? ` (${fail} failed)` : ""}.`);
|
|
388
|
+
if (fail > 0) process.exit(1);
|
|
389
|
+
}
|
|
390
|
+
function handleGuide() {
|
|
391
|
+
try {
|
|
392
|
+
const guide = readFileSync(GUIDE_PATH, "utf8");
|
|
393
|
+
process.stdout.write(guide);
|
|
394
|
+
if (!guide.endsWith("\n")) process.stdout.write("\n");
|
|
395
|
+
} catch (err) {
|
|
396
|
+
console.error(`Error: could not read authoring guide at ${GUIDE_PATH}`);
|
|
397
|
+
console.error(err.message);
|
|
398
|
+
process.exit(1);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
async function runPropertySkill(argv, apiUrl, token) {
|
|
402
|
+
const [action, ...rest] = argv;
|
|
403
|
+
if (!action || action === "help" || hasFlag(argv, "--help", "-h")) {
|
|
404
|
+
printSkillHelp();
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
switch (action) {
|
|
408
|
+
case "guide":
|
|
409
|
+
handleGuide();
|
|
410
|
+
return;
|
|
411
|
+
case "list":
|
|
412
|
+
await handleList(rest, apiUrl, token);
|
|
413
|
+
break;
|
|
414
|
+
case "get":
|
|
415
|
+
await handleGet(rest, apiUrl, token);
|
|
416
|
+
break;
|
|
417
|
+
case "set":
|
|
418
|
+
await handleSet(rest, apiUrl, token);
|
|
419
|
+
break;
|
|
420
|
+
case "delete":
|
|
421
|
+
await handleDelete(rest, apiUrl, token);
|
|
422
|
+
break;
|
|
423
|
+
case "history":
|
|
424
|
+
await handleHistory(rest, apiUrl, token);
|
|
425
|
+
break;
|
|
426
|
+
case "export":
|
|
427
|
+
await handleExport(rest, apiUrl, token);
|
|
428
|
+
break;
|
|
429
|
+
case "import":
|
|
430
|
+
await handleImport(rest, apiUrl, token);
|
|
431
|
+
break;
|
|
432
|
+
default:
|
|
433
|
+
console.error(`Unknown skill action: ${action}`);
|
|
434
|
+
printSkillHelp();
|
|
435
|
+
process.exit(1);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// src/property.ts
|
|
440
|
+
function pad(s, n) {
|
|
441
|
+
return s.padEnd(n);
|
|
442
|
+
}
|
|
443
|
+
function printHelp() {
|
|
444
|
+
console.log(
|
|
445
|
+
[
|
|
446
|
+
"canary application: Manage applications (alias: canary property)",
|
|
447
|
+
"",
|
|
448
|
+
"Sub-commands:",
|
|
449
|
+
" list List all applications",
|
|
450
|
+
" create [options] Create a new application",
|
|
451
|
+
" repo link [options] Link a GitHub repo to an application",
|
|
452
|
+
" repo update [options] Update an existing repo link",
|
|
453
|
+
" repo unlink [options] Unlink a GitHub repo from an application",
|
|
454
|
+
" skill <action> [options] Manage the application's app skill (run `canary application skill help` for details)",
|
|
455
|
+
"",
|
|
456
|
+
"Create options:",
|
|
457
|
+
" --name <name> Application name (required)",
|
|
458
|
+
" --base-url <url> Application base URL (required)",
|
|
459
|
+
" --description <text> Optional description",
|
|
460
|
+
" --agent-context <text> Optional agent context (max 8000 chars)",
|
|
461
|
+
" --env-var <NAME[:sensitive]> Declare a per-environment variable (repeatable); values set per-environment, injected as $var.ENV.<NAME>",
|
|
462
|
+
"",
|
|
463
|
+
"Repo link/update/unlink options:",
|
|
464
|
+
" --application <app_xxx|uuid> Application ID (required; alias: --property)",
|
|
465
|
+
" --repo <owner/name> Repo full name (required for link/unlink)",
|
|
466
|
+
" --repo-id <uuid> Repo link UUID (required for update)",
|
|
467
|
+
" --role <frontend|backend|...> Conventional role (free-form)",
|
|
468
|
+
" --root-dir <path> Monorepo subdirectory hint",
|
|
469
|
+
" --agent-hint <text> Free-form hint for the planner agent",
|
|
470
|
+
"",
|
|
471
|
+
"Common options:",
|
|
472
|
+
" --json Output as JSON"
|
|
473
|
+
].join("\n")
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
async function handleList2(argv, apiUrl, token) {
|
|
477
|
+
const json = hasFlag(argv, "--json");
|
|
478
|
+
const properties = await fetchProperties(apiUrl, token);
|
|
479
|
+
if (json) {
|
|
480
|
+
console.log(JSON.stringify(properties, null, 2));
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
if (properties.length === 0) {
|
|
484
|
+
console.log("No applications found.");
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
console.log(`${pad("Name", 30)} ${pad("Base URL", 40)} ID`);
|
|
488
|
+
for (const p of properties) {
|
|
489
|
+
console.log(`${pad(p.name, 30)} ${pad(p.baseUrl, 40)} ${p.id}`);
|
|
490
|
+
}
|
|
491
|
+
console.log("");
|
|
492
|
+
for (const p of properties) {
|
|
493
|
+
const reposRes = await apiRequest(
|
|
494
|
+
apiUrl,
|
|
495
|
+
token,
|
|
496
|
+
"GET",
|
|
497
|
+
`/org/properties/${p.id}/github-repos`
|
|
498
|
+
);
|
|
499
|
+
const repos = reposRes.ok ? reposRes.items ?? [] : [];
|
|
500
|
+
if (repos.length > 0) {
|
|
501
|
+
console.log(`${p.name} repos:`);
|
|
502
|
+
for (const r of repos) {
|
|
503
|
+
const dir = r.rootDir && r.rootDir !== "/" ? ` (${r.rootDir})` : "";
|
|
504
|
+
const role = r.role ? ` [${r.role}]` : "";
|
|
505
|
+
console.log(` ${r.repoFullName}:${r.defaultBranch}${role}${dir}`);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
function parseEnvVarDefinitions(argv) {
|
|
511
|
+
const defs = [];
|
|
512
|
+
for (let i = 0; i < argv.length; i++) {
|
|
513
|
+
if (argv[i] !== "--env-var") continue;
|
|
514
|
+
const raw = argv[i + 1];
|
|
515
|
+
if (!raw || raw.startsWith("-")) continue;
|
|
516
|
+
const [name, modifier] = raw.split(":");
|
|
517
|
+
if (!name) continue;
|
|
518
|
+
defs.push({ name, ...modifier === "sensitive" ? { sensitive: true } : {} });
|
|
519
|
+
}
|
|
520
|
+
return defs;
|
|
521
|
+
}
|
|
522
|
+
async function handleCreate(argv, apiUrl, token) {
|
|
523
|
+
const json = hasFlag(argv, "--json");
|
|
524
|
+
const name = getArgValue(argv, "--name");
|
|
525
|
+
const baseUrl = getArgValue(argv, "--base-url");
|
|
526
|
+
const description = getArgValue(argv, "--description");
|
|
527
|
+
const agentContext = getArgValue(argv, "--agent-context");
|
|
528
|
+
const envVarDefinitions = parseEnvVarDefinitions(argv);
|
|
529
|
+
if (!name || !baseUrl) {
|
|
530
|
+
console.error("Error: --name and --base-url are required.");
|
|
531
|
+
console.error("Usage: canary application create --name <name> --base-url <url>");
|
|
532
|
+
process2.exit(1);
|
|
533
|
+
}
|
|
534
|
+
const body = { name, baseUrl };
|
|
535
|
+
if (description !== void 0) body.description = description;
|
|
536
|
+
if (agentContext !== void 0) body.agentContext = agentContext;
|
|
537
|
+
if (envVarDefinitions.length > 0) body.envVarDefinitions = envVarDefinitions;
|
|
538
|
+
const result = await apiRequest(
|
|
539
|
+
apiUrl,
|
|
540
|
+
token,
|
|
541
|
+
"POST",
|
|
542
|
+
"/org/properties",
|
|
543
|
+
body
|
|
544
|
+
);
|
|
545
|
+
if (!result.ok) {
|
|
546
|
+
if (json) {
|
|
547
|
+
console.log(JSON.stringify(result, null, 2));
|
|
548
|
+
} else {
|
|
549
|
+
console.error(`Error: ${result.error ?? "Unknown error"}`);
|
|
550
|
+
}
|
|
551
|
+
process2.exit(1);
|
|
552
|
+
}
|
|
553
|
+
if (json) {
|
|
554
|
+
console.log(JSON.stringify(result, null, 2));
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
console.log(`Created application "${name}" (${result.id})`);
|
|
558
|
+
}
|
|
559
|
+
async function handleRepoLink(argv, apiUrl, token) {
|
|
560
|
+
const json = hasFlag(argv, "--json");
|
|
561
|
+
const propertyId = getApplicationArg(argv);
|
|
562
|
+
const repo = getArgValue(argv, "--repo");
|
|
563
|
+
const role = getArgValue(argv, "--role");
|
|
564
|
+
const rootDir = getArgValue(argv, "--root-dir");
|
|
565
|
+
const agentHint = getArgValue(argv, "--agent-hint");
|
|
566
|
+
if (!propertyId || !repo) {
|
|
567
|
+
console.error("Error: --application and --repo are required.");
|
|
568
|
+
process2.exit(1);
|
|
569
|
+
}
|
|
570
|
+
const body = { repoFullName: repo };
|
|
571
|
+
if (role !== void 0) body.role = role;
|
|
572
|
+
if (rootDir !== void 0) body.rootDir = rootDir;
|
|
573
|
+
if (agentHint !== void 0) body.agentHint = agentHint;
|
|
574
|
+
const result = await apiRequest(
|
|
575
|
+
apiUrl,
|
|
576
|
+
token,
|
|
577
|
+
"POST",
|
|
578
|
+
`/org/properties/${propertyId}/github-repos`,
|
|
579
|
+
body
|
|
580
|
+
);
|
|
581
|
+
if (!result.ok) {
|
|
582
|
+
if (json) console.log(JSON.stringify(result, null, 2));
|
|
583
|
+
else console.error(`Error: ${result.error ?? "Unknown error"}`);
|
|
584
|
+
process2.exit(1);
|
|
585
|
+
}
|
|
586
|
+
if (json) console.log(JSON.stringify(result, null, 2));
|
|
587
|
+
else console.log(`Linked ${repo} to application ${propertyId} (${result.id})`);
|
|
588
|
+
}
|
|
589
|
+
async function handleRepoUpdate(argv, apiUrl, token) {
|
|
590
|
+
const json = hasFlag(argv, "--json");
|
|
591
|
+
const propertyId = getApplicationArg(argv);
|
|
592
|
+
const repoId = getArgValue(argv, "--repo-id");
|
|
593
|
+
const role = getArgValue(argv, "--role");
|
|
594
|
+
const rootDir = getArgValue(argv, "--root-dir");
|
|
595
|
+
const agentHint = getArgValue(argv, "--agent-hint");
|
|
596
|
+
if (!propertyId || !repoId) {
|
|
597
|
+
console.error("Error: --application and --repo-id are required.");
|
|
598
|
+
process2.exit(1);
|
|
599
|
+
}
|
|
600
|
+
const body = {};
|
|
601
|
+
if (role !== void 0) body.role = role;
|
|
602
|
+
if (rootDir !== void 0) body.rootDir = rootDir;
|
|
603
|
+
if (agentHint !== void 0) body.agentHint = agentHint;
|
|
604
|
+
const result = await apiRequest(
|
|
605
|
+
apiUrl,
|
|
606
|
+
token,
|
|
607
|
+
"PATCH",
|
|
608
|
+
`/org/properties/${propertyId}/github-repos/${repoId}`,
|
|
609
|
+
body
|
|
610
|
+
);
|
|
611
|
+
if (!result.ok) {
|
|
612
|
+
if (json) console.log(JSON.stringify(result, null, 2));
|
|
613
|
+
else console.error(`Error: ${result.error ?? "Unknown error"}`);
|
|
614
|
+
process2.exit(1);
|
|
615
|
+
}
|
|
616
|
+
if (json) console.log(JSON.stringify(result, null, 2));
|
|
617
|
+
else console.log(`Updated repo link ${repoId}`);
|
|
618
|
+
}
|
|
619
|
+
async function handleRepoUnlink(argv, apiUrl, token) {
|
|
620
|
+
const json = hasFlag(argv, "--json");
|
|
621
|
+
const propertyId = getApplicationArg(argv);
|
|
622
|
+
const repo = getArgValue(argv, "--repo");
|
|
623
|
+
if (!propertyId || !repo) {
|
|
624
|
+
console.error("Error: --application and --repo are required.");
|
|
625
|
+
process2.exit(1);
|
|
626
|
+
}
|
|
627
|
+
const result = await apiRequest(
|
|
628
|
+
apiUrl,
|
|
629
|
+
token,
|
|
630
|
+
"DELETE",
|
|
631
|
+
`/org/properties/${propertyId}/github-repos/${encodeURIComponent(repo)}`
|
|
632
|
+
);
|
|
633
|
+
if (!result.ok) {
|
|
634
|
+
if (json) console.log(JSON.stringify(result, null, 2));
|
|
635
|
+
else console.error(`Error: ${result.error ?? "Unknown error"}`);
|
|
636
|
+
process2.exit(1);
|
|
637
|
+
}
|
|
638
|
+
if (json) console.log(JSON.stringify(result, null, 2));
|
|
639
|
+
else console.log(`Unlinked ${repo} from application ${propertyId}`);
|
|
640
|
+
}
|
|
641
|
+
async function handleRepo(argv, apiUrl, token) {
|
|
642
|
+
const [action, ...rest] = argv;
|
|
643
|
+
switch (action) {
|
|
644
|
+
case "link":
|
|
645
|
+
await handleRepoLink(rest, apiUrl, token);
|
|
646
|
+
break;
|
|
647
|
+
case "update":
|
|
648
|
+
await handleRepoUpdate(rest, apiUrl, token);
|
|
649
|
+
break;
|
|
650
|
+
case "unlink":
|
|
651
|
+
await handleRepoUnlink(rest, apiUrl, token);
|
|
652
|
+
break;
|
|
653
|
+
default:
|
|
654
|
+
console.error(`Unknown repo action: ${action ?? "(none)"}`);
|
|
655
|
+
printHelp();
|
|
656
|
+
process2.exit(1);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
async function runProperty(argv) {
|
|
660
|
+
const [subCommand, ...rest] = argv;
|
|
661
|
+
if (!subCommand || subCommand === "help" || hasFlag(argv, "--help", "-h")) {
|
|
662
|
+
printHelp();
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
if (subCommand === "skill") {
|
|
666
|
+
const skillAction = rest[0];
|
|
667
|
+
if (!skillAction || skillAction === "help" || skillAction === "guide") {
|
|
668
|
+
await runPropertySkill(rest, "", "");
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
const { apiUrl, token } = await resolveConfig(argv);
|
|
673
|
+
const globalFlags = /* @__PURE__ */ new Set(["--env", "--api-url", "--token"]);
|
|
674
|
+
const args = rest.filter((arg, i) => {
|
|
675
|
+
if (globalFlags.has(arg)) return false;
|
|
676
|
+
if (i > 0 && globalFlags.has(rest[i - 1])) return false;
|
|
677
|
+
return true;
|
|
678
|
+
});
|
|
679
|
+
switch (subCommand) {
|
|
680
|
+
case "list":
|
|
681
|
+
await handleList2(args, apiUrl, token);
|
|
682
|
+
break;
|
|
683
|
+
case "create":
|
|
684
|
+
await handleCreate(args, apiUrl, token);
|
|
685
|
+
break;
|
|
686
|
+
case "repo":
|
|
687
|
+
await handleRepo(args, apiUrl, token);
|
|
688
|
+
break;
|
|
689
|
+
case "skill":
|
|
690
|
+
await runPropertySkill(args, apiUrl, token);
|
|
691
|
+
break;
|
|
692
|
+
default:
|
|
693
|
+
console.error(`Unknown sub-command: ${subCommand}`);
|
|
694
|
+
printHelp();
|
|
695
|
+
process2.exit(1);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
export {
|
|
699
|
+
runProperty
|
|
700
|
+
};
|
|
701
|
+
//# sourceMappingURL=property-UXLOLPTD.js.map
|