@hasna/instructions 0.7.0 → 0.7.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 (74) hide show
  1. package/README.md +52 -11
  2. package/dist/chunks/{apply-7svah2qm.js → apply-ps6jjt6k.js} +3 -3
  3. package/dist/chunks/{apply-jp13sa1e.js → apply-wj7wh5km.js} +3 -3
  4. package/dist/chunks/{index-1cnyjnd7.js → index-18j7x3xw.js} +2 -2
  5. package/dist/chunks/{index-3djthcm6.js → index-27az1qb1.js} +28 -1
  6. package/dist/chunks/{index-fwbs6tma.js → index-ape24zc0.js} +2 -2
  7. package/dist/chunks/{index-bzyxvwcd.js → index-ek15201v.js} +2 -2
  8. package/dist/chunks/{index-arrrx0ed.js → index-mvckkf15.js} +39 -20
  9. package/dist/chunks/{index-7m4j8a33.js → index-n6nh6f5r.js} +235 -20
  10. package/dist/chunks/{index-4pfq42t5.js → index-pq18fdbj.js} +146 -32
  11. package/dist/chunks/{index-n3fjspr0.js → index-preyvj8n.js} +28 -1
  12. package/dist/chunks/{index-z3ma4aqk.js → index-y8410ve0.js} +3 -3
  13. package/dist/chunks/{local-5wvv5xv3.js → local-1c1qxzvx.js} +155 -4
  14. package/dist/chunks/{local-zxa5dpf4.js → local-hc67bynj.js} +155 -4
  15. package/dist/chunks/{s3-backup-n2z4fwyh.js → s3-backup-hxe3zpfz.js} +1 -1
  16. package/dist/chunks/{s3-object-store-90tgbh6k.js → s3-object-store-n0s82swt.js} +1 -1
  17. package/dist/chunks/{sync-r8t7zsp3.js → sync-12m3vs6g.js} +4 -4
  18. package/dist/chunks/{sync-2075deve.js → sync-azd9t4p8.js} +4 -4
  19. package/dist/chunks/{template-wgnzdn7h.js → template-e4qrxs8p.js} +1 -1
  20. package/dist/chunks/{template-fsfxpe4p.js → template-nhn124zd.js} +1 -1
  21. package/dist/cli/index.js +860 -181
  22. package/dist/data/config-store.d.ts +22 -6
  23. package/dist/data/config-store.d.ts.map +1 -1
  24. package/dist/db/configs.d.ts +4 -1
  25. package/dist/db/configs.d.ts.map +1 -1
  26. package/dist/db/local.d.ts +1 -1
  27. package/dist/db/local.d.ts.map +1 -1
  28. package/dist/index.d.ts +5 -3
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +940 -134
  31. package/dist/lib/asset-plan.d.ts.map +1 -1
  32. package/dist/lib/codewith-shared-todos-storage-standard.d.ts.map +1 -1
  33. package/dist/lib/compact-output.d.ts +2 -18
  34. package/dist/lib/compact-output.d.ts.map +1 -1
  35. package/dist/lib/dangerous-operation-guard-standard.d.ts.map +1 -1
  36. package/dist/lib/export.d.ts.map +1 -1
  37. package/dist/lib/global-agent-rules-standard.d.ts.map +1 -1
  38. package/dist/lib/global-source-coverage.d.ts +12 -7
  39. package/dist/lib/global-source-coverage.d.ts.map +1 -1
  40. package/dist/lib/import.d.ts.map +1 -1
  41. package/dist/lib/instruction-graph.d.ts +1 -1
  42. package/dist/lib/instruction-graph.d.ts.map +1 -1
  43. package/dist/lib/instruction-source-policy.d.ts +6 -0
  44. package/dist/lib/instruction-source-policy.d.ts.map +1 -0
  45. package/dist/lib/platform-profiles.d.ts.map +1 -1
  46. package/dist/lib/project-dashboard-standard.d.ts.map +1 -1
  47. package/dist/lib/session-apply.d.ts +24 -0
  48. package/dist/lib/session-apply.d.ts.map +1 -1
  49. package/dist/lib/session-refresh.d.ts +30 -0
  50. package/dist/lib/session-refresh.d.ts.map +1 -0
  51. package/dist/lib/session-render.d.ts +34 -1
  52. package/dist/lib/session-render.d.ts.map +1 -1
  53. package/dist/lib/transforms.d.ts +1 -0
  54. package/dist/lib/transforms.d.ts.map +1 -1
  55. package/dist/mcp/index.js +23 -22
  56. package/dist/mcp/server.d.ts.map +1 -1
  57. package/dist/sdk/index.js +46 -3
  58. package/dist/sdk/v1-client.d.ts +10 -3
  59. package/dist/sdk/v1-client.d.ts.map +1 -1
  60. package/dist/sdk/v1.generated.d.ts +52 -2
  61. package/dist/sdk/v1.generated.d.ts.map +1 -1
  62. package/dist/server/index.d.ts +1 -1
  63. package/dist/server/index.d.ts.map +1 -1
  64. package/dist/server/index.js +215 -15
  65. package/dist/server/openapi.d.ts +240 -3
  66. package/dist/server/openapi.d.ts.map +1 -1
  67. package/dist/server/v1.d.ts.map +1 -1
  68. package/dist/storage/cloud-store.d.ts +2 -15
  69. package/dist/storage/cloud-store.d.ts.map +1 -1
  70. package/dist/storage/index.js +39 -20
  71. package/dist/storage/s3-object-store.d.ts.map +1 -1
  72. package/dist/types/index.d.ts +49 -2
  73. package/dist/types/index.d.ts.map +1 -1
  74. package/package.json +3 -3
@@ -14,8 +14,9 @@ import {
14
14
  ProfileNotFoundError,
15
15
  isTemplate,
16
16
  renderTemplate,
17
- renderTemplatePreview
18
- } from "./index-3djthcm6.js";
17
+ renderTemplatePreview,
18
+ validateExpectedConfigVersion
19
+ } from "./index-27az1qb1.js";
19
20
  import {
20
21
  __export,
21
22
  __require
@@ -114,6 +115,9 @@ function buildCodexAgentsMd(source, context = {}) {
114
115
  function buildOpenCodeAgentsMd(source, context = {}) {
115
116
  return flattenWithRules(source, context);
116
117
  }
118
+ function buildSumiAgentsMd(source, context = {}) {
119
+ return flattenWithRules(source, context);
120
+ }
117
121
  function buildCursorMdc(source) {
118
122
  const stem = source.target_path ? basename(source.target_path, extname(source.target_path)) : source.slug;
119
123
  const description = source.name || stem;
@@ -142,6 +146,8 @@ function applyTransform(source, output, context = {}) {
142
146
  return buildCodexAgentsMd(source, context);
143
147
  case "opencode-flat":
144
148
  return buildOpenCodeAgentsMd(source, context);
149
+ case "sumi-flat":
150
+ return buildSumiAgentsMd(source, context);
145
151
  case "cursor-mdc":
146
152
  return buildCursorMdc(source);
147
153
  case "skill-neutral":
@@ -244,28 +250,6 @@ function truncateText(value, max = 80) {
244
250
  return text.slice(0, max);
245
251
  return `${text.slice(0, max - 3)}...`;
246
252
  }
247
- function summarizeConfig(config, opts = {}) {
248
- const summary = {
249
- id: config.id,
250
- slug: config.slug,
251
- name: config.name,
252
- category: config.category,
253
- agent: config.agent,
254
- kind: config.kind,
255
- format: config.format,
256
- target_path: config.target_path,
257
- output_count: config.outputs.length,
258
- version: config.version,
259
- is_template: config.is_template
260
- };
261
- if (opts.verbose) {
262
- summary.updated_at = config.updated_at;
263
- summary.description = config.description;
264
- summary.tags = config.tags;
265
- summary.outputs = config.outputs;
266
- }
267
- return summary;
268
- }
269
253
  function summarizeProfile(profile, opts = {}) {
270
254
  const selectorCount = (profile.selectors.os?.length ?? 0) + (profile.selectors.arch?.length ?? 0) + (profile.selectors.hostnames?.length ?? 0);
271
255
  const summary = {
@@ -431,6 +415,7 @@ var DEFAULT_ASSET_SURFACES = Object.freeze({
431
415
  codex: "cli",
432
416
  cursor: "ide",
433
417
  opencode: "cli",
418
+ sumi: "cli",
434
419
  codewith: "cli",
435
420
  qwen: "cli",
436
421
  aicopilot: "cli",
@@ -556,6 +541,7 @@ var DEFAULT_PROVIDER_CAPABILITIES = Object.freeze({
556
541
  codex: capability("codex", ">=0.1.0", "flattened", "AGENTS.md", { asset_surface: "cli" }),
557
542
  cursor: capability("cursor", ">=1.0.0", "cursor-rule", ".cursor/rules/*.mdc", { activation_modes: ["always", "glob"], conditional_artifacts: true, asset_surface: "ide" }),
558
543
  opencode: capability("opencode", ">=1.0.0", "managed-fragment", "opencode.json instructions", { provider_variant: "v1-instructions", session_surface: "opencode-config-instructions" }),
544
+ sumi: capability("sumi", ">=0.2.22 <0.3.0", "flattened", "AGENTS.md"),
559
545
  codewith: capability("codewith", ">=0.1.0", "flattened", "CODEWITH.md"),
560
546
  qwen: capability("qwen", ">=0.1.0", "flattened", "QWEN.md"),
561
547
  aicopilot: capability("aicopilot", ">=0.1.0", "flattened", "AICOPILOT.md"),
@@ -2059,6 +2045,19 @@ function parseBoundedOrLegacyPage(value, legacyItems, options, label) {
2059
2045
  const page = boundedReadPage(legacyItems.slice(normalized.cursor, normalized.cursor + normalized.limit), legacyItems.length, normalized);
2060
2046
  return { ...page, source_bounded: false };
2061
2047
  }
2048
+ function projectBoundedPage(page, project) {
2049
+ return {
2050
+ items: page.items.map(project),
2051
+ total: page.total,
2052
+ limit: page.limit,
2053
+ cursor: page.cursor,
2054
+ next_cursor: page.next_cursor,
2055
+ has_more: page.has_more,
2056
+ complete: page.complete,
2057
+ truncated: page.truncated,
2058
+ source_bounded: page.source_bounded
2059
+ };
2060
+ }
2062
2061
 
2063
2062
  class CollectionChangedWhilePagingError extends Error {
2064
2063
  constructor(label, detail) {
@@ -2124,7 +2123,7 @@ function isNotFoundHttpError2(err) {
2124
2123
  var localStoreModulePromise = null;
2125
2124
  function localStoreModule() {
2126
2125
  if (!localStoreModulePromise)
2127
- localStoreModulePromise = import("./local-5wvv5xv3.js");
2126
+ localStoreModulePromise = import("./local-1c1qxzvx.js");
2128
2127
  return localStoreModulePromise;
2129
2128
  }
2130
2129
 
@@ -2138,6 +2137,15 @@ class LocalConfigStore {
2138
2137
  async listConfigs(filter) {
2139
2138
  return (await localStoreModule()).listConfigs(filter, this.db);
2140
2139
  }
2140
+ async listConfigsPage(filter = {}, options = {}) {
2141
+ return (await localStoreModule()).listConfigsPage(filter, options, this.db);
2142
+ }
2143
+ async listConfigIdentitiesPage(filter = {}, options = {}) {
2144
+ return (await localStoreModule()).listConfigIdentitiesPage(filter, options, this.db);
2145
+ }
2146
+ async listConfigSummariesPage(filter = {}, options = {}) {
2147
+ return (await localStoreModule()).listConfigSummariesPage(filter, options, this.db);
2148
+ }
2141
2149
  async getConfig(idOrSlug) {
2142
2150
  return (await localStoreModule()).getConfig(idOrSlug, this.db);
2143
2151
  }
@@ -2241,6 +2249,43 @@ class LocalConfigStore {
2241
2249
  (await localStoreModule()).resetLocalDatabase();
2242
2250
  }
2243
2251
  }
2252
+ function toConfigIdentity(value) {
2253
+ const record = value && typeof value === "object" ? value : {};
2254
+ return {
2255
+ id: String(record.id ?? ""),
2256
+ name: String(record.name ?? ""),
2257
+ slug: String(record.slug ?? ""),
2258
+ kind: String(record.kind ?? ""),
2259
+ category: String(record.category ?? ""),
2260
+ agent: String(record.agent ?? ""),
2261
+ format: String(record.format ?? ""),
2262
+ is_template: Boolean(record.is_template),
2263
+ version: Number(record.version ?? 0),
2264
+ created_at: String(record.created_at ?? ""),
2265
+ updated_at: String(record.updated_at ?? ""),
2266
+ synced_at: record.synced_at == null ? null : String(record.synced_at)
2267
+ };
2268
+ }
2269
+ function toConfigSummary(value) {
2270
+ const record = value && typeof value === "object" ? value : {};
2271
+ const outputs = Array.isArray(record.outputs) ? record.outputs : [];
2272
+ return {
2273
+ id: String(record.id ?? ""),
2274
+ slug: String(record.slug ?? ""),
2275
+ name: String(record.name ?? ""),
2276
+ category: String(record.category ?? ""),
2277
+ agent: String(record.agent ?? ""),
2278
+ kind: String(record.kind ?? ""),
2279
+ format: String(record.format ?? ""),
2280
+ target_path: record.target_path == null ? null : String(record.target_path),
2281
+ output_count: Number(record.output_count ?? outputs.length),
2282
+ version: Number(record.version ?? 0),
2283
+ is_template: Boolean(record.is_template),
2284
+ ...record.updated_at !== undefined ? { updated_at: String(record.updated_at) } : {},
2285
+ ...record.description !== undefined ? { description: record.description == null ? null : String(record.description) } : {},
2286
+ ...Array.isArray(record.tags) ? { tags: record.tags.map(String) } : {}
2287
+ };
2288
+ }
2244
2289
 
2245
2290
  class CloudConfigStore {
2246
2291
  mode = "api";
@@ -2262,7 +2307,7 @@ class CloudConfigStore {
2262
2307
  throw err;
2263
2308
  }
2264
2309
  }
2265
- async listConfigsPageRemote(filter, options) {
2310
+ async listConfigsPage(filter = {}, options = {}) {
2266
2311
  const normalized = normalizeBoundedReadOptions(options);
2267
2312
  const params = new URLSearchParams;
2268
2313
  if (filter.category)
@@ -2273,13 +2318,67 @@ class CloudConfigStore {
2273
2318
  params.set("kind", filter.kind);
2274
2319
  if (filter.search)
2275
2320
  params.set("search", filter.search);
2321
+ for (const tag of filter.tags ?? [])
2322
+ params.append("tag", tag);
2276
2323
  params.set("limit", String(normalized.limit));
2277
2324
  params.set("cursor", String(normalized.cursor));
2278
2325
  const { data } = await this.request("GET", `/configs?${params.toString()}`);
2279
2326
  return parseBoundedOrLegacyPage(data, data?.configs, normalized, "config list");
2280
2327
  }
2328
+ async listConfigIdentitiesPage(filter = {}, options = {}) {
2329
+ const normalized = normalizeBoundedReadOptions(options);
2330
+ const params = new URLSearchParams;
2331
+ if (filter.category)
2332
+ params.set("category", filter.category);
2333
+ if (filter.agent)
2334
+ params.set("agent", filter.agent);
2335
+ if (filter.kind)
2336
+ params.set("kind", filter.kind);
2337
+ if (filter.search)
2338
+ params.set("search", filter.search);
2339
+ for (const tag of filter.tags ?? [])
2340
+ params.append("tag", tag);
2341
+ params.set("view", "identity");
2342
+ params.set("limit", String(normalized.limit));
2343
+ params.set("cursor", String(normalized.cursor));
2344
+ const { data } = await this.request("GET", `/configs?${params.toString()}`);
2345
+ const page = parseBoundedOrLegacyPage(data, data?.configs, normalized, "config identity list");
2346
+ if (page.items.some((item) => {
2347
+ const record = item && typeof item === "object" ? item : {};
2348
+ return ["content", "target_path", "outputs", "description", "tags"].some((field) => Object.prototype.hasOwnProperty.call(record, field));
2349
+ })) {
2350
+ throw new Error("Instructions /v1 config identity projection is unavailable; deploy the identity endpoint before using compact lists");
2351
+ }
2352
+ return projectBoundedPage(page, toConfigIdentity);
2353
+ }
2354
+ async listConfigSummariesPage(filter = {}, options = {}) {
2355
+ const normalized = normalizeBoundedReadOptions(options);
2356
+ const params = new URLSearchParams;
2357
+ if (filter.category)
2358
+ params.set("category", filter.category);
2359
+ if (filter.agent)
2360
+ params.set("agent", filter.agent);
2361
+ if (filter.kind)
2362
+ params.set("kind", filter.kind);
2363
+ if (filter.search)
2364
+ params.set("search", filter.search);
2365
+ for (const tag of filter.tags ?? [])
2366
+ params.append("tag", tag);
2367
+ params.set("view", "summary");
2368
+ params.set("limit", String(normalized.limit));
2369
+ params.set("cursor", String(normalized.cursor));
2370
+ const { data } = await this.request("GET", `/configs?${params.toString()}`);
2371
+ const page = parseBoundedOrLegacyPage(data, data?.configs, normalized, "config summary list");
2372
+ if (page.items.some((item) => {
2373
+ const record = item && typeof item === "object" ? item : {};
2374
+ return Object.prototype.hasOwnProperty.call(record, "content") || Object.prototype.hasOwnProperty.call(record, "outputs");
2375
+ })) {
2376
+ throw new Error("Instructions /v1 config summary projection is unavailable; deploy the summary endpoint before using summary lists");
2377
+ }
2378
+ return projectBoundedPage(page, toConfigSummary);
2379
+ }
2281
2380
  async listConfigs(filter = {}) {
2282
- const configs = await aggregateBoundedCollection("config list", (cursor) => this.listConfigsPageRemote(filter, { limit: 100, cursor }), (config) => config.id, { requireAscendingIdentity: true });
2381
+ const configs = await aggregateBoundedCollection("config list", (cursor) => this.listConfigsPage(filter, { limit: 100, cursor }), (config) => config.id, { requireAscendingIdentity: true });
2283
2382
  let filtered = configs;
2284
2383
  if (filter.tags && filter.tags.length > 0) {
2285
2384
  filtered = filtered.filter((config) => filter.tags.every((tag) => config.tags.includes(tag)));
@@ -2305,7 +2404,9 @@ class CloudConfigStore {
2305
2404
  return data.config;
2306
2405
  }
2307
2406
  async updateConfig(idOrSlug, input) {
2308
- const { data } = await this.request("PATCH", `/configs/${encodeURIComponent(idOrSlug)}`, input);
2407
+ validateExpectedConfigVersion(input.expected_version);
2408
+ const conditional = input.expected_version !== undefined;
2409
+ const { data } = await this.request(conditional ? "POST" : "PATCH", `/configs/${encodeURIComponent(idOrSlug)}${conditional ? "/conditional-update" : ""}`, input);
2309
2410
  return data.config;
2310
2411
  }
2311
2412
  async deleteConfig(idOrSlug) {
@@ -2345,7 +2446,7 @@ class CloudConfigStore {
2345
2446
  return data?.pruned ?? 0;
2346
2447
  }
2347
2448
  async listProfiles() {
2348
- return aggregateBoundedCollection("profile list", (cursor) => this.listProfilesPage({ limit: 100, cursor }), (profile) => profile.id, { requireAscendingIdentity: true });
2449
+ return aggregateBoundedCollection("profile list", (cursor) => this.listProfilesPage({ limit: 100, cursor }), (profile) => profile.id);
2349
2450
  }
2350
2451
  async listProfilesPage(options = {}) {
2351
2452
  const normalized = normalizeBoundedReadOptions(options);
@@ -2382,7 +2483,7 @@ class CloudConfigStore {
2382
2483
  throw new ProfileNotFoundError(idOrSlug);
2383
2484
  return parseBoundedOrLegacyPage(data.configs, data.profile.configs, normalized, "profile membership");
2384
2485
  }
2385
- async getProfileConfigBindings(idOrSlug) {
2486
+ async getProfileConfigBindings(idOrSlug, options = {}) {
2386
2487
  let routeMissing = false;
2387
2488
  const bindings = await aggregateBoundedCollection("profile config bindings", async (cursor) => {
2388
2489
  const normalized = normalizeBoundedReadOptions({ limit: 100, cursor });
@@ -2395,6 +2496,8 @@ class CloudConfigStore {
2395
2496
  }, (binding) => `${binding.profile_id}\x00${binding.config_id}`);
2396
2497
  if (!routeMissing)
2397
2498
  return bindings;
2499
+ if (options.requireExplicit)
2500
+ throw new Error("HOSTED_BINDINGS_REQUIRED: profile config binding route is unavailable; refusing legacy activation fallback.");
2398
2501
  const profile = await this.getProfile(idOrSlug);
2399
2502
  const configs = await this.getProfileConfigs(idOrSlug);
2400
2503
  return configs.map((config, sort_order) => ({
@@ -2459,7 +2562,7 @@ class CloudConfigStore {
2459
2562
  async removeConfigFromProfile(profileIdOrSlug, configId) {
2460
2563
  await this.request("DELETE", `/profiles/${encodeURIComponent(profileIdOrSlug)}/configs/${encodeURIComponent(configId)}`, undefined, { allow404: true });
2461
2564
  }
2462
- async getProfileAssetBindings(profileIdOrSlug) {
2565
+ async getProfileAssetBindings(profileIdOrSlug, options = {}) {
2463
2566
  let routeMissing = false;
2464
2567
  const assets = await aggregateBoundedCollection("profile asset bindings", async (cursor) => {
2465
2568
  const normalized = normalizeBoundedReadOptions({ limit: 100, cursor });
@@ -2472,6 +2575,8 @@ class CloudConfigStore {
2472
2575
  }, (asset) => `${asset.profile_id}\x00${asset.binding.assetKey}`);
2473
2576
  if (!routeMissing)
2474
2577
  return assets;
2578
+ if (options.requireExplicit)
2579
+ throw new Error("HOSTED_ASSETS_REQUIRED: profile asset binding route is unavailable; refusing an empty asset fallback.");
2475
2580
  await this.getProfile(profileIdOrSlug);
2476
2581
  return [];
2477
2582
  }
@@ -7108,6 +7213,15 @@ var SESSION_TOOL_ADAPTERS = {
7108
7213
  description: "OpenCode AGENTS.md plus opencode.json instructions pointing at managed fragments.",
7109
7214
  providerSurface: "legacy-dual"
7110
7215
  },
7216
+ sumi: {
7217
+ tool: "sumi",
7218
+ mode: "flattened-markdown",
7219
+ indexFile: "AGENTS.md",
7220
+ managedDir: SESSION_RENDER_INSTRUCTIONS_MANAGED_DIR,
7221
+ envVar: "SUMI_CONFIG_DIR",
7222
+ nativeImports: false,
7223
+ description: "Sumi native AGENTS.md in the explicit resolved config directory or project root."
7224
+ },
7111
7225
  aicopilot: {
7112
7226
  tool: "aicopilot",
7113
7227
  mode: "flattened-markdown",
@@ -7297,4 +7411,4 @@ function renderMachineAwareContentPreview(content, variables) {
7297
7411
  return isTemplate(content) ? renderTemplatePreview(content, variables) : { content, unresolved: [] };
7298
7412
  }
7299
7413
 
7300
- export { pagedPayload, summarizeConfig, summarizeProfile, summarizeApplyResult, normalizeBoundedReadOptions, boundedReadPage, SESSION_RENDER_SCHEMA, SESSION_RENDER_MANIFEST_RELATIVE_PATH, isRetiredOrUnsupportedConfigAgent, retiredOrUnsupportedAgentReason, applyTransform, normalizeProfileAssetBinding, isCursorGlobalAuthorityPath, stampCursorGlobalAuthorityMarker, getReportedDbPath, getRawStoreRoot, ANTIGRAVITY_RULE_FILE_CHAR_LIMIT, SESSION_RENDERER_OWNER_ID, SESSION_RENDER_OWNED_CONFIG_TARGETS, SESSION_RENDER_EXCLUSIVE_MANAGED_PATHS, legacyProfileConfigBinding, normalizeProfileConfigBinding, hasInstructionsEnvAuthorityIntent, normalizeOsFamily, detectMachineContext, machineContextToVariables, resolveProfileVariables, templateizeMachineContent, renderMachineAwareContentPreview, resolveConfigStore };
7414
+ export { pagedPayload, summarizeProfile, summarizeApplyResult, normalizeBoundedReadOptions, boundedReadPage, SESSION_RENDER_SCHEMA, SESSION_RENDER_MANIFEST_RELATIVE_PATH, isRetiredOrUnsupportedConfigAgent, retiredOrUnsupportedAgentReason, applyTransform, normalizeProfileAssetBinding, isCursorGlobalAuthorityPath, stampCursorGlobalAuthorityMarker, getReportedDbPath, getRawStoreRoot, ANTIGRAVITY_RULE_FILE_CHAR_LIMIT, SESSION_RENDERER_OWNER_ID, SESSION_RENDER_OWNED_CONFIG_TARGETS, SESSION_RENDER_EXCLUSIVE_MANAGED_PATHS, legacyProfileConfigBinding, normalizeProfileConfigBinding, hasInstructionsEnvAuthorityIntent, normalizeOsFamily, detectMachineContext, machineContextToVariables, resolveProfileVariables, templateizeMachineContent, renderMachineAwareContentPreview, resolveConfigStore };
@@ -4,6 +4,7 @@ var CONFIG_AGENTS = [
4
4
  "claude",
5
5
  "codex",
6
6
  "opencode",
7
+ "sumi",
7
8
  "cursor",
8
9
  "codewith",
9
10
  "aicopilot",
@@ -30,6 +31,32 @@ var ASSET_UNINSTALL_POLICIES = ["remove-managed", "retain"];
30
31
  var ASSET_ROLLBACK_POLICIES = ["snapshot", "installer-receipt", "none"];
31
32
  var INSTRUCTIONS_DOMAIN_ARCHIVE_SCHEMA = "hasna.instructions.domain-archive/v2";
32
33
 
34
+ class InvalidExpectedVersionError extends Error {
35
+ code = "INVALID_EXPECTED_VERSION";
36
+ constructor() {
37
+ super("expected_version must be a positive safe integer");
38
+ this.name = "InvalidExpectedVersionError";
39
+ }
40
+ }
41
+ function validateExpectedConfigVersion(value) {
42
+ if (value !== undefined && (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1)) {
43
+ throw new InvalidExpectedVersionError;
44
+ }
45
+ }
46
+
47
+ class ConfigVersionConflictError extends Error {
48
+ config_id;
49
+ expected_version;
50
+ code = "CONFIG_VERSION_CONFLICT";
51
+ status = 409;
52
+ constructor(config_id, expected_version) {
53
+ super(`Config version conflict: ${config_id} no longer has expected version ${expected_version}`);
54
+ this.config_id = config_id;
55
+ this.expected_version = expected_version;
56
+ this.name = "ConfigVersionConflictError";
57
+ }
58
+ }
59
+
33
60
  class ConfigNotFoundError extends Error {
34
61
  constructor(id) {
35
62
  super(`Config not found: ${id}`);
@@ -116,4 +143,4 @@ function isTemplate(content) {
116
143
  return VAR_PATTERN.test(content);
117
144
  }
118
145
 
119
- export { CONFIG_AGENTS, PROFILE_CONFIG_BINDING_SCHEMA, INSTRUCTION_ACTIVATION_MODES, INSTRUCTION_FALLBACKS, PROFILE_ASSET_BINDING_SCHEMA, ASSET_KINDS, ASSET_DESTINATION_STRATEGIES, ASSET_SCOPES, ASSET_UNINSTALL_POLICIES, ASSET_ROLLBACK_POLICIES, INSTRUCTIONS_DOMAIN_ARCHIVE_SCHEMA, ConfigNotFoundError, ProfileNotFoundError, ConfigApplyError, parseTemplateVars, extractTemplateVars, renderTemplate, renderTemplatePreview, isTemplate };
146
+ export { CONFIG_AGENTS, PROFILE_CONFIG_BINDING_SCHEMA, INSTRUCTION_ACTIVATION_MODES, INSTRUCTION_FALLBACKS, PROFILE_ASSET_BINDING_SCHEMA, ASSET_KINDS, ASSET_DESTINATION_STRATEGIES, ASSET_SCOPES, ASSET_UNINSTALL_POLICIES, ASSET_ROLLBACK_POLICIES, INSTRUCTIONS_DOMAIN_ARCHIVE_SCHEMA, validateExpectedConfigVersion, ConfigVersionConflictError, ConfigNotFoundError, ProfileNotFoundError, ConfigApplyError, parseTemplateVars, extractTemplateVars, renderTemplate, renderTemplatePreview, isTemplate };
@@ -18,11 +18,11 @@ import {
18
18
  resolveProfileVariables,
19
19
  scanSecrets,
20
20
  stampCursorGlobalAuthorityMarker
21
- } from "./index-7m4j8a33.js";
21
+ } from "./index-n6nh6f5r.js";
22
22
  import {
23
23
  ConfigApplyError,
24
24
  parseTemplateVars
25
- } from "./index-n3fjspr0.js";
25
+ } from "./index-preyvj8n.js";
26
26
 
27
27
  // src/lib/apply.ts
28
28
  import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, realpathSync, writeFileSync } from "fs";
@@ -529,4 +529,4 @@ function sessionRendererOwnsCanonicalTarget(normalized, opts) {
529
529
  return sessionRenderOwnsPath(normalized);
530
530
  }
531
531
 
532
- export { getConfigHome, expandPath, compactPathForConfigHome, normalizeTargetPath, applyConfig, applyConfigs, applyConfigsWithReport, previewConfigs };
532
+ export { sessionRenderOwnsPath, getConfigHome, expandPath, compactPathForConfigHome, normalizeTargetPath, applyConfig, applyConfigs, applyConfigsWithReport, previewConfigs };
@@ -14,12 +14,14 @@ import {
14
14
  normalizeOsFamily,
15
15
  normalizeProfileAssetBinding,
16
16
  normalizeProfileConfigBinding
17
- } from "./index-4pfq42t5.js";
17
+ } from "./index-pq18fdbj.js";
18
18
  import"./index-35z65jsa.js";
19
19
  import {
20
20
  ConfigNotFoundError,
21
- ProfileNotFoundError
22
- } from "./index-3djthcm6.js";
21
+ ConfigVersionConflictError,
22
+ ProfileNotFoundError,
23
+ validateExpectedConfigVersion
24
+ } from "./index-27az1qb1.js";
23
25
  import"./index-nnwp92tk.js";
24
26
 
25
27
  // src/db/database.ts
@@ -339,7 +341,145 @@ function listConfigs(filter, db) {
339
341
  const rows = d.query(`SELECT * FROM configs ${where} ORDER BY category, name`).all(...params);
340
342
  return rows.map(rowToConfig);
341
343
  }
344
+ function listConfigsPage(filter = {}, options = {}, db) {
345
+ const d = db || getDatabase();
346
+ const conditions = [];
347
+ const params = [];
348
+ if (filter.category) {
349
+ conditions.push("category = ?");
350
+ params.push(filter.category);
351
+ }
352
+ if (filter.agent) {
353
+ conditions.push("agent = ?");
354
+ params.push(filter.agent);
355
+ }
356
+ if (filter.kind) {
357
+ conditions.push("kind = ?");
358
+ params.push(filter.kind);
359
+ }
360
+ if (filter.is_template !== undefined) {
361
+ conditions.push("is_template = ?");
362
+ params.push(filter.is_template ? 1 : 0);
363
+ }
364
+ if (filter.search) {
365
+ conditions.push("(name LIKE ? OR description LIKE ? OR content LIKE ?)");
366
+ const q = `%${filter.search}%`;
367
+ params.push(q, q, q);
368
+ }
369
+ if (filter.tags?.length) {
370
+ conditions.push(`(${filter.tags.map(() => "tags LIKE ?").join(" AND ")})`);
371
+ for (const tag of filter.tags)
372
+ params.push(`%"${tag}"%`);
373
+ }
374
+ const where = conditions.length ? `WHERE ${conditions.join(" AND ")}` : "";
375
+ const normalized = normalizeBoundedReadOptions(options);
376
+ const total = d.query(`SELECT COUNT(*) AS total FROM configs ${where}`).get(...params)?.total ?? 0;
377
+ const pageParams = [...params, normalized.limit, normalized.cursor];
378
+ const rows = d.query(`SELECT * FROM configs ${where} ORDER BY id LIMIT ? OFFSET ?`).all(...pageParams);
379
+ return boundedReadPage(rows.map(rowToConfig), total, normalized);
380
+ }
381
+ function listConfigIdentitiesPage(filter = {}, options = {}, db) {
382
+ const d = db || getDatabase();
383
+ const conditions = [];
384
+ const params = [];
385
+ if (filter.category) {
386
+ conditions.push("category = ?");
387
+ params.push(filter.category);
388
+ }
389
+ if (filter.agent) {
390
+ conditions.push("agent = ?");
391
+ params.push(filter.agent);
392
+ }
393
+ if (filter.kind) {
394
+ conditions.push("kind = ?");
395
+ params.push(filter.kind);
396
+ }
397
+ if (filter.is_template !== undefined) {
398
+ conditions.push("is_template = ?");
399
+ params.push(filter.is_template ? 1 : 0);
400
+ }
401
+ if (filter.search) {
402
+ conditions.push("(name LIKE ? OR description LIKE ? OR content LIKE ?)");
403
+ const q = `%${filter.search}%`;
404
+ params.push(q, q, q);
405
+ }
406
+ if (filter.tags?.length) {
407
+ conditions.push(`(${filter.tags.map(() => "tags LIKE ?").join(" AND ")})`);
408
+ for (const tag of filter.tags)
409
+ params.push(`%"${tag}"%`);
410
+ }
411
+ const where = conditions.length ? `WHERE ${conditions.join(" AND ")}` : "";
412
+ const normalized = normalizeBoundedReadOptions(options);
413
+ const total = d.query(`SELECT COUNT(*) AS total FROM configs ${where}`).get(...params)?.total ?? 0;
414
+ const pageParams = [...params, normalized.limit, normalized.cursor];
415
+ const rows = d.query(`SELECT id, name, slug, kind, category, agent, format, is_template, version, created_at, updated_at, synced_at
416
+ FROM configs ${where} ORDER BY id LIMIT ? OFFSET ?`).all(...pageParams);
417
+ return boundedReadPage(rows.map((row) => ({
418
+ ...row,
419
+ kind: row.kind,
420
+ category: row.category,
421
+ agent: row.agent,
422
+ format: row.format,
423
+ is_template: Boolean(row.is_template)
424
+ })), total, normalized);
425
+ }
426
+ function listConfigSummariesPage(filter = {}, options = {}, db) {
427
+ const d = db || getDatabase();
428
+ const conditions = [];
429
+ const params = [];
430
+ if (filter.category) {
431
+ conditions.push("category = ?");
432
+ params.push(filter.category);
433
+ }
434
+ if (filter.agent) {
435
+ conditions.push("agent = ?");
436
+ params.push(filter.agent);
437
+ }
438
+ if (filter.kind) {
439
+ conditions.push("kind = ?");
440
+ params.push(filter.kind);
441
+ }
442
+ if (filter.is_template !== undefined) {
443
+ conditions.push("is_template = ?");
444
+ params.push(filter.is_template ? 1 : 0);
445
+ }
446
+ if (filter.search) {
447
+ conditions.push("(name LIKE ? OR description LIKE ? OR content LIKE ?)");
448
+ const q = `%${filter.search}%`;
449
+ params.push(q, q, q);
450
+ }
451
+ if (filter.tags && filter.tags.length > 0) {
452
+ conditions.push(`(${filter.tags.map(() => "tags LIKE ?").join(" AND ")})`);
453
+ for (const tag of filter.tags)
454
+ params.push(`%"${tag}"%`);
455
+ }
456
+ const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
457
+ const normalized = normalizeBoundedReadOptions(options);
458
+ const total = d.query(`SELECT COUNT(*) AS total FROM configs ${where}`).get(...params)?.total ?? 0;
459
+ const pageParams = [...params, normalized.limit, normalized.cursor];
460
+ const rows = d.query(`SELECT id, name, slug, kind, category, agent, target_path, format,
461
+ CASE WHEN json_valid(outputs) AND json_type(outputs) = 'array' THEN json_array_length(outputs) ELSE 0 END AS output_count, description, tags,
462
+ is_template, version, updated_at
463
+ FROM configs ${where} ORDER BY category, name, id LIMIT ? OFFSET ?`).all(...pageParams);
464
+ return boundedReadPage(rows.map((row) => ({
465
+ id: row.id,
466
+ slug: row.slug,
467
+ name: row.name,
468
+ category: row.category,
469
+ agent: row.agent,
470
+ kind: row.kind,
471
+ format: row.format,
472
+ target_path: row.target_path,
473
+ output_count: Number(row.output_count ?? 0),
474
+ version: row.version,
475
+ is_template: Boolean(row.is_template),
476
+ updated_at: row.updated_at,
477
+ description: row.description,
478
+ tags: JSON.parse(row.tags || "[]")
479
+ })), total, normalized);
480
+ }
342
481
  function updateConfig(idOrSlug, input, db) {
482
+ validateExpectedConfigVersion(input.expected_version);
343
483
  const d = db || getDatabase();
344
484
  const existing = getConfig(idOrSlug, d);
345
485
  const ts = now();
@@ -395,7 +535,15 @@ function updateConfig(idOrSlug, input, db) {
395
535
  }
396
536
  return d.transaction(() => {
397
537
  params.push(existing.id);
398
- d.run(`UPDATE configs SET ${updates.join(", ")} WHERE id = ?`, params);
538
+ const condition = input.expected_version === undefined ? "" : " AND version = ?";
539
+ if (input.expected_version !== undefined)
540
+ params.push(input.expected_version);
541
+ const result = d.run(`UPDATE configs SET ${updates.join(", ")} WHERE id = ?${condition}`, params);
542
+ if (result.changes !== 1) {
543
+ if (input.expected_version !== undefined)
544
+ throw new ConfigVersionConflictError(existing.id, input.expected_version);
545
+ throw new ConfigNotFoundError(existing.id);
546
+ }
399
547
  const updated = getConfigById(existing.id, d);
400
548
  createSnapshot(updated.id, updated.content, updated.version, d);
401
549
  return updated;
@@ -673,7 +821,10 @@ export {
673
821
  listSnapshots,
674
822
  listProfilesPage,
675
823
  listMachines,
824
+ listConfigsPage,
676
825
  listConfigs,
826
+ listConfigSummariesPage,
827
+ listConfigIdentitiesPage,
677
828
  insertFeedback,
678
829
  getSnapshotByVersion,
679
830
  getSnapshot,