@noodleseed/one 0.168.0 → 0.170.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.
Files changed (142) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +3 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/capabilities.d.ts +19 -0
  5. package/dist/commands/capabilities.d.ts.map +1 -0
  6. package/dist/commands/capabilities.js +128 -0
  7. package/dist/commands/capabilities.js.map +1 -0
  8. package/dist/commands/deployment-delete-ops.d.ts +12 -0
  9. package/dist/commands/deployment-delete-ops.d.ts.map +1 -0
  10. package/dist/commands/deployment-delete-ops.js +230 -0
  11. package/dist/commands/deployment-delete-ops.js.map +1 -0
  12. package/dist/commands/deployment-delete-recovery.d.ts +35 -0
  13. package/dist/commands/deployment-delete-recovery.d.ts.map +1 -0
  14. package/dist/commands/deployment-delete-recovery.js +99 -0
  15. package/dist/commands/deployment-delete-recovery.js.map +1 -0
  16. package/dist/commands/deployments-ops.d.ts +2 -1
  17. package/dist/commands/deployments-ops.d.ts.map +1 -1
  18. package/dist/commands/deployments-ops.js +5 -1
  19. package/dist/commands/deployments-ops.js.map +1 -1
  20. package/dist/index.d.ts +1 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +1 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/plugin-mode/plugin-operation-contract.d.ts +2 -2
  25. package/node_modules/@noodle-borg/agent-kit/dist/curated/command-groups.js +4 -0
  26. package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +1 -1
  27. package/node_modules/@noodle-borg/agent-kit/dist/generated/surface.js +2 -0
  28. package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.js +3 -2
  29. package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
  30. package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-interactive.d.ts +1 -0
  31. package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-interactive.js +4 -1
  32. package/node_modules/@noodle-borg/authoring/dist/assistant.d.ts +2 -2
  33. package/node_modules/@noodle-borg/authoring/dist/assistant.js +3 -1
  34. package/node_modules/@noodle-borg/authoring/dist/index.d.ts +1 -0
  35. package/node_modules/@noodle-borg/authoring/dist/index.js +1 -0
  36. package/node_modules/@noodle-borg/authoring/dist/load-authored.js +1 -1
  37. package/node_modules/@noodle-borg/authoring/dist/recording.d.ts +2 -1
  38. package/node_modules/@noodle-borg/authoring/dist/recording.js +29 -1
  39. package/node_modules/@noodle-borg/authoring/dist/server.d.ts +3 -0
  40. package/node_modules/@noodle-borg/authoring/dist/server.js +5 -1
  41. package/node_modules/@noodle-borg/authoring/dist/web-capabilities.d.ts +17 -0
  42. package/node_modules/@noodle-borg/authoring/dist/web-capabilities.js +15 -0
  43. package/node_modules/@noodle-borg/authoring/package.json +1 -0
  44. package/node_modules/@noodle-borg/capabilities/dist/index.js +7 -0
  45. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-hosted-observability.js +102 -0
  46. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-tenant-resources.js +27 -1
  47. package/node_modules/@noodle-borg/compiler/dist/artifact/assemble.js +3 -0
  48. package/node_modules/@noodle-borg/compiler/dist/artifact/types.d.ts +2 -0
  49. package/node_modules/@noodle-borg/compiler/dist/artifact/version.d.ts +2 -1
  50. package/node_modules/@noodle-borg/compiler/dist/artifact/version.js +2 -1
  51. package/node_modules/@noodle-borg/compiler/dist/compile.js +2 -0
  52. package/node_modules/@noodle-borg/compiler/dist/fulfilment-emit.js +18 -3
  53. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +34 -0
  54. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js +9 -2
  55. package/node_modules/@noodle-borg/compiler/dist/web-capabilities.js +55 -0
  56. package/node_modules/@noodle-borg/compiler/package.json +1 -0
  57. package/node_modules/@noodle-borg/connector-http/dist/ssrf.js +5 -0
  58. package/node_modules/@noodle-borg/control-plane/dist/delete-deployment.d.ts +44 -0
  59. package/node_modules/@noodle-borg/control-plane/dist/delete-deployment.js +105 -0
  60. package/node_modules/@noodle-borg/control-plane/dist/deployment-deletion-contracts.d.ts +20 -0
  61. package/node_modules/@noodle-borg/control-plane/dist/portable.d.ts +2 -0
  62. package/node_modules/@noodle-borg/control-plane/dist/portable.js +1 -0
  63. package/node_modules/@noodle-borg/knowledge-crawl/dist/bounded-body.js +38 -0
  64. package/node_modules/@noodle-borg/knowledge-crawl/dist/first-party.js +2 -3
  65. package/node_modules/@noodle-borg/knowledge-crawl/dist/html-text.js +10 -2
  66. package/node_modules/@noodle-borg/knowledge-crawl/dist/index.d.ts +1 -0
  67. package/node_modules/@noodle-borg/knowledge-crawl/dist/index.js +1 -0
  68. package/node_modules/@noodle-borg/knowledge-crawl/dist/page-reader.d.ts +26 -0
  69. package/node_modules/@noodle-borg/knowledge-crawl/dist/page-reader.js +127 -0
  70. package/node_modules/@noodle-borg/knowledge-crawl/dist/robots.js +48 -23
  71. package/node_modules/@noodle-borg/knowledge-crawl/package.json +1 -0
  72. package/node_modules/@noodle-borg/managed-capabilities/dist/budget.d.ts +29 -0
  73. package/node_modules/@noodle-borg/managed-capabilities/dist/budget.js +124 -0
  74. package/node_modules/@noodle-borg/managed-capabilities/dist/contracts.d.ts +212 -0
  75. package/node_modules/@noodle-borg/managed-capabilities/dist/contracts.js +113 -0
  76. package/node_modules/@noodle-borg/managed-capabilities/dist/errors.d.ts +8 -0
  77. package/node_modules/@noodle-borg/managed-capabilities/dist/errors.js +21 -0
  78. package/node_modules/@noodle-borg/managed-capabilities/dist/executor.d.ts +26 -0
  79. package/node_modules/@noodle-borg/managed-capabilities/dist/executor.js +156 -0
  80. package/node_modules/@noodle-borg/managed-capabilities/dist/limits.d.ts +15 -0
  81. package/node_modules/@noodle-borg/managed-capabilities/dist/limits.js +15 -0
  82. package/node_modules/@noodle-borg/managed-capabilities/dist/operator-contracts.d.ts +159 -0
  83. package/node_modules/@noodle-borg/managed-capabilities/dist/operator-contracts.js +69 -0
  84. package/node_modules/@noodle-borg/managed-capabilities/dist/operator-route.d.ts +5 -0
  85. package/node_modules/@noodle-borg/managed-capabilities/dist/operator-route.js +160 -0
  86. package/node_modules/@noodle-borg/managed-capabilities/dist/policy-store.d.ts +34 -0
  87. package/node_modules/@noodle-borg/managed-capabilities/dist/policy-store.js +61 -0
  88. package/node_modules/@noodle-borg/managed-capabilities/dist/portable.d.ts +10 -0
  89. package/node_modules/@noodle-borg/managed-capabilities/dist/portable.js +10 -0
  90. package/node_modules/@noodle-borg/managed-capabilities/dist/service.d.ts +83 -0
  91. package/node_modules/@noodle-borg/managed-capabilities/dist/service.js +139 -0
  92. package/node_modules/@noodle-borg/managed-capabilities/dist/urls.d.ts +3 -0
  93. package/node_modules/@noodle-borg/managed-capabilities/dist/urls.js +30 -0
  94. package/node_modules/@noodle-borg/managed-capabilities/package.json +49 -0
  95. package/node_modules/@noodle-borg/module/dist/contract.d.ts +11 -0
  96. package/node_modules/@noodle-borg/runtime/dist/confirmation.js +29 -0
  97. package/node_modules/@noodle-borg/runtime/dist/connector/types.d.ts +2 -0
  98. package/node_modules/@noodle-borg/runtime/dist/execute.d.ts +3 -0
  99. package/node_modules/@noodle-borg/runtime/dist/execute.js +6 -1
  100. package/node_modules/@noodle-borg/runtime/dist/index.d.ts +2 -1
  101. package/node_modules/@noodle-borg/runtime/dist/index.js +2 -1
  102. package/node_modules/@noodle-borg/runtime/dist/interactive.js +10 -1
  103. package/node_modules/@noodle-borg/runtime/dist/operation-execution.js +3 -0
  104. package/node_modules/@noodle-borg/runtime/dist/result-meta.d.ts +2 -0
  105. package/node_modules/@noodle-borg/runtime/dist/result-meta.js +6 -0
  106. package/node_modules/@noodle-borg/runtime/dist/result.d.ts +4 -0
  107. package/node_modules/@noodle-borg/runtime/dist/web-capabilities.d.ts +71 -0
  108. package/node_modules/@noodle-borg/runtime/dist/web-capabilities.js +41 -0
  109. package/node_modules/@noodle-borg/runtime/package.json +1 -0
  110. package/node_modules/@noodle-borg/service/dist/deployment-deletion.js +40 -0
  111. package/node_modules/@noodle-borg/service/dist/local-options.d.ts +1 -0
  112. package/node_modules/@noodle-borg/service/dist/local-web-capabilities.js +13 -0
  113. package/node_modules/@noodle-borg/service/dist/mcp-protocol-runtime.js +21 -0
  114. package/node_modules/@noodle-borg/service/dist/modules/route-dispatch.js +13 -0
  115. package/node_modules/@noodle-borg/service/dist/registry-compile.js +9 -0
  116. package/node_modules/@noodle-borg/service/dist/registry-deletion.js +75 -0
  117. package/node_modules/@noodle-borg/service/dist/registry-state.js +4 -2
  118. package/node_modules/@noodle-borg/service/dist/registry-targets.js +4 -0
  119. package/node_modules/@noodle-borg/service/dist/registry-types.d.ts +1 -0
  120. package/node_modules/@noodle-borg/service/dist/registry.d.ts +2 -0
  121. package/node_modules/@noodle-borg/service/dist/registry.js +10 -23
  122. package/node_modules/@noodle-borg/service/dist/routes/assistant-agent.js +5 -2
  123. package/node_modules/@noodle-borg/service/dist/routes/assistant-interactions.js +7 -4
  124. package/node_modules/@noodle-borg/service/dist/routes/deploy-dispatch.js +15 -1
  125. package/node_modules/@noodle-borg/service/dist/routes/deployment-delete.js +53 -0
  126. package/node_modules/@noodle-borg/service/dist/serve-local.js +14 -0
  127. package/node_modules/@noodle-borg/service/dist/serve-resource-auth.js +10 -0
  128. package/node_modules/@noodle-borg/service/dist/service.js +7 -1
  129. package/node_modules/@noodle-borg/service/dist/store/in-memory.d.ts +2 -1
  130. package/node_modules/@noodle-borg/service/dist/store/in-memory.js +8 -0
  131. package/node_modules/@noodle-borg/service/dist/store/json-file-deletion.js +64 -0
  132. package/node_modules/@noodle-borg/service/dist/store/json-file.d.ts +2 -1
  133. package/node_modules/@noodle-borg/service/dist/store/json-file.js +23 -5
  134. package/node_modules/@noodle-borg/service/dist/store.d.ts +5 -1
  135. package/node_modules/@noodle-borg/service/dist/web-capabilities.js +39 -0
  136. package/node_modules/@noodle-borg/service/package.json +3 -1
  137. package/node_modules/@noodle-borg/wire-contracts/dist/deployment-deletion.d.ts +29 -0
  138. package/node_modules/@noodle-borg/wire-contracts/dist/deployment-deletion.js +33 -0
  139. package/node_modules/@noodle-borg/wire-contracts/dist/index.d.ts +2 -0
  140. package/node_modules/@noodle-borg/wire-contracts/dist/index.js +2 -0
  141. package/node_modules/@noodle-borg/wire-contracts/package.json +1 -0
  142. package/package.json +3 -2
@@ -0,0 +1,159 @@
1
+ import { z } from 'zod';
2
+ export declare const capabilityScopeSchema: z.ZodObject<{
3
+ org: z.ZodString;
4
+ app: z.ZodString;
5
+ env: z.ZodString;
6
+ name: z.ZodString;
7
+ }, z.core.$strict>;
8
+ export type CapabilityScope = z.infer<typeof capabilityScopeSchema>;
9
+ export declare const operatorCapabilityPolicySchema: z.ZodObject<{
10
+ maxUrls: z.ZodOptional<z.ZodNumber>;
11
+ maxCalls: z.ZodOptional<z.ZodNumber>;
12
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
13
+ maxTextBytes: z.ZodOptional<z.ZodNumber>;
14
+ domains: z.ZodOptional<z.ZodArray<z.ZodString>>;
15
+ enabled: z.ZodBoolean;
16
+ dailyCalls: z.ZodNumber;
17
+ }, z.core.$strict>;
18
+ export type OperatorCapabilityPolicy = z.infer<typeof operatorCapabilityPolicySchema>;
19
+ export declare const capabilityPolicyUpdateSchema: z.ZodObject<{
20
+ expectedRevision: z.ZodNumber;
21
+ mutationId: z.ZodString;
22
+ policy: z.ZodObject<{
23
+ maxUrls: z.ZodOptional<z.ZodNumber>;
24
+ maxCalls: z.ZodOptional<z.ZodNumber>;
25
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
26
+ maxTextBytes: z.ZodOptional<z.ZodNumber>;
27
+ domains: z.ZodOptional<z.ZodArray<z.ZodString>>;
28
+ enabled: z.ZodBoolean;
29
+ dailyCalls: z.ZodNumber;
30
+ }, z.core.$strict>;
31
+ }, z.core.$strict>;
32
+ export type CapabilityPolicyUpdate = z.infer<typeof capabilityPolicyUpdateSchema> & {
33
+ readonly actor: string;
34
+ };
35
+ export declare const capabilityPolicyRecordSchema: z.ZodObject<{
36
+ revision: z.ZodNumber;
37
+ policy: z.ZodObject<{
38
+ maxUrls: z.ZodOptional<z.ZodNumber>;
39
+ maxCalls: z.ZodOptional<z.ZodNumber>;
40
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
41
+ maxTextBytes: z.ZodOptional<z.ZodNumber>;
42
+ domains: z.ZodOptional<z.ZodArray<z.ZodString>>;
43
+ enabled: z.ZodBoolean;
44
+ dailyCalls: z.ZodNumber;
45
+ }, z.core.$strict>;
46
+ actor: z.ZodString;
47
+ updatedAt: z.ZodISODateTime;
48
+ }, z.core.$strict>;
49
+ export type CapabilityPolicyRecord = z.infer<typeof capabilityPolicyRecordSchema>;
50
+ export declare const capabilityInspectionSchema: z.ZodObject<{
51
+ name: z.ZodString;
52
+ class: z.ZodLiteral<"web.extract.v1">;
53
+ title: z.ZodString;
54
+ serviceKey: z.ZodString;
55
+ available: z.ZodBoolean;
56
+ profile: z.ZodEnum<{
57
+ "managed-learning-cohort": "managed-learning-cohort";
58
+ "local-first-party": "local-first-party";
59
+ }>;
60
+ revision: z.ZodNumber;
61
+ developerPolicy: z.ZodObject<{
62
+ maxUrls: z.ZodOptional<z.ZodNumber>;
63
+ maxCalls: z.ZodOptional<z.ZodNumber>;
64
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
65
+ maxTextBytes: z.ZodOptional<z.ZodNumber>;
66
+ domains: z.ZodOptional<z.ZodArray<z.ZodString>>;
67
+ }, z.core.$strict>;
68
+ operatorPolicy: z.ZodObject<{
69
+ maxUrls: z.ZodOptional<z.ZodNumber>;
70
+ maxCalls: z.ZodOptional<z.ZodNumber>;
71
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
72
+ maxTextBytes: z.ZodOptional<z.ZodNumber>;
73
+ domains: z.ZodOptional<z.ZodArray<z.ZodString>>;
74
+ enabled: z.ZodBoolean;
75
+ dailyCalls: z.ZodNumber;
76
+ }, z.core.$strict>;
77
+ effectivePolicy: z.ZodObject<{
78
+ maxUrls: z.ZodOptional<z.ZodNumber>;
79
+ maxCalls: z.ZodOptional<z.ZodNumber>;
80
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
81
+ maxTextBytes: z.ZodOptional<z.ZodNumber>;
82
+ domains: z.ZodOptional<z.ZodArray<z.ZodString>>;
83
+ }, z.core.$strict>;
84
+ actor: z.ZodOptional<z.ZodString>;
85
+ updatedAt: z.ZodOptional<z.ZodISODateTime>;
86
+ }, z.core.$strict>;
87
+ export declare const capabilityListResponseSchema: z.ZodObject<{
88
+ deploymentId: z.ZodString;
89
+ capabilities: z.ZodArray<z.ZodObject<{
90
+ name: z.ZodString;
91
+ class: z.ZodLiteral<"web.extract.v1">;
92
+ title: z.ZodString;
93
+ serviceKey: z.ZodString;
94
+ available: z.ZodBoolean;
95
+ profile: z.ZodEnum<{
96
+ "managed-learning-cohort": "managed-learning-cohort";
97
+ "local-first-party": "local-first-party";
98
+ }>;
99
+ revision: z.ZodNumber;
100
+ developerPolicy: z.ZodObject<{
101
+ maxUrls: z.ZodOptional<z.ZodNumber>;
102
+ maxCalls: z.ZodOptional<z.ZodNumber>;
103
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
104
+ maxTextBytes: z.ZodOptional<z.ZodNumber>;
105
+ domains: z.ZodOptional<z.ZodArray<z.ZodString>>;
106
+ }, z.core.$strict>;
107
+ operatorPolicy: z.ZodObject<{
108
+ maxUrls: z.ZodOptional<z.ZodNumber>;
109
+ maxCalls: z.ZodOptional<z.ZodNumber>;
110
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
111
+ maxTextBytes: z.ZodOptional<z.ZodNumber>;
112
+ domains: z.ZodOptional<z.ZodArray<z.ZodString>>;
113
+ enabled: z.ZodBoolean;
114
+ dailyCalls: z.ZodNumber;
115
+ }, z.core.$strict>;
116
+ effectivePolicy: z.ZodObject<{
117
+ maxUrls: z.ZodOptional<z.ZodNumber>;
118
+ maxCalls: z.ZodOptional<z.ZodNumber>;
119
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
120
+ maxTextBytes: z.ZodOptional<z.ZodNumber>;
121
+ domains: z.ZodOptional<z.ZodArray<z.ZodString>>;
122
+ }, z.core.$strict>;
123
+ actor: z.ZodOptional<z.ZodString>;
124
+ updatedAt: z.ZodOptional<z.ZodISODateTime>;
125
+ }, z.core.$strict>>;
126
+ }, z.core.$strict>;
127
+ export type CapabilityListResponse = z.infer<typeof capabilityListResponseSchema>;
128
+ export declare const capabilityTestRequestSchema: z.ZodObject<{
129
+ mode: z.ZodEnum<{
130
+ fixture: "fixture";
131
+ live: "live";
132
+ }>;
133
+ request: z.ZodObject<{
134
+ urls: z.ZodArray<z.ZodString>;
135
+ domains: z.ZodOptional<z.ZodArray<z.ZodString>>;
136
+ }, z.core.$strict>;
137
+ }, z.core.$strict>;
138
+ export declare const capabilityTestResponseSchema: z.ZodObject<{
139
+ mode: z.ZodEnum<{
140
+ fixture: "fixture";
141
+ live: "live";
142
+ }>;
143
+ status: z.ZodEnum<{
144
+ complete: "complete";
145
+ partial: "partial";
146
+ }>;
147
+ pages: z.ZodNumber;
148
+ sources: z.ZodArray<z.ZodObject<{
149
+ ref: z.ZodString;
150
+ url: z.ZodString;
151
+ retrievedAt: z.ZodISODateTime;
152
+ }, z.core.$strict>>;
153
+ warnings: z.ZodArray<z.ZodObject<{
154
+ requestIndex: z.ZodNumber;
155
+ code: z.ZodString;
156
+ }, z.core.$strict>>;
157
+ }, z.core.$strict>;
158
+ export type CapabilityTestResponse = z.infer<typeof capabilityTestResponseSchema>;
159
+ //# sourceMappingURL=operator-contracts.d.ts.map
@@ -0,0 +1,69 @@
1
+ import { z } from 'zod';
2
+ import { capabilityNameSchema, webExtractRequestSchema, webPolicySchema } from './contracts.js';
3
+ const scopePart = z
4
+ .string()
5
+ .min(1)
6
+ .max(128)
7
+ .regex(/^[a-zA-Z0-9_-]+$/);
8
+ export const capabilityScopeSchema = z
9
+ .object({ org: scopePart, app: scopePart, env: scopePart, name: capabilityNameSchema })
10
+ .strict();
11
+ export const operatorCapabilityPolicySchema = webPolicySchema.extend({
12
+ enabled: z.boolean(),
13
+ dailyCalls: z.number().int().min(0).max(1000),
14
+ });
15
+ export const capabilityPolicyUpdateSchema = z
16
+ .object({
17
+ expectedRevision: z
18
+ .number()
19
+ .int()
20
+ .min(0)
21
+ .max(Number.MAX_SAFE_INTEGER - 1),
22
+ mutationId: z
23
+ .string()
24
+ .min(1)
25
+ .max(128)
26
+ .regex(/^[a-zA-Z0-9_-]+$/),
27
+ policy: operatorCapabilityPolicySchema,
28
+ })
29
+ .strict();
30
+ export const capabilityPolicyRecordSchema = z
31
+ .object({
32
+ revision: z.number().int().positive(),
33
+ policy: operatorCapabilityPolicySchema,
34
+ actor: z.string().min(1).max(512),
35
+ updatedAt: z.iso.datetime(),
36
+ })
37
+ .strict();
38
+ export const capabilityInspectionSchema = z
39
+ .object({
40
+ name: capabilityNameSchema,
41
+ class: z.literal('web.extract.v1'),
42
+ title: z.string(),
43
+ serviceKey: z.string(),
44
+ available: z.boolean(),
45
+ profile: z.enum(['managed-learning-cohort', 'local-first-party']),
46
+ revision: z.number().int().nonnegative(),
47
+ developerPolicy: webPolicySchema,
48
+ operatorPolicy: operatorCapabilityPolicySchema,
49
+ effectivePolicy: webPolicySchema.extend({ domains: z.array(z.string()).max(32).optional() }),
50
+ actor: z.string().optional(),
51
+ updatedAt: z.iso.datetime().optional(),
52
+ })
53
+ .strict();
54
+ export const capabilityListResponseSchema = z
55
+ .object({ deploymentId: z.string(), capabilities: z.array(capabilityInspectionSchema) })
56
+ .strict();
57
+ export const capabilityTestRequestSchema = z
58
+ .object({ mode: z.enum(['fixture', 'live']), request: webExtractRequestSchema })
59
+ .strict();
60
+ export const capabilityTestResponseSchema = z
61
+ .object({
62
+ mode: z.enum(['fixture', 'live']),
63
+ status: z.enum(['complete', 'partial']),
64
+ pages: z.number().int().nonnegative(),
65
+ sources: z.array(z.object({ ref: z.string(), url: z.string().url(), retrievedAt: z.iso.datetime() }).strict()),
66
+ warnings: z.array(z.object({ requestIndex: z.number().int(), code: z.string() }).strict()),
67
+ })
68
+ .strict();
69
+ //# sourceMappingURL=operator-contracts.js.map
@@ -0,0 +1,5 @@
1
+ import type { ModuleRoute } from '@noodle-borg/module';
2
+ import type { CapabilityService } from './service.js';
3
+ /** Operator diagnostic commands share policy/admission; they never expose source bodies. */
4
+ export declare function capabilityOperatorRoute(service: CapabilityService): ModuleRoute;
5
+ //# sourceMappingURL=operator-route.d.ts.map
@@ -0,0 +1,160 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { z } from 'zod';
3
+ import { CapabilityBudget } from './budget.js';
4
+ import { webCapabilityBaseSchema } from './contracts.js';
5
+ import { CapabilityError } from './errors.js';
6
+ import { capabilityInspectionSchema, capabilityListResponseSchema, capabilityPolicyUpdateSchema, capabilityScopeSchema, capabilityTestRequestSchema, capabilityTestResponseSchema, } from './operator-contracts.js';
7
+ import { CapabilityPolicyConflict } from './policy-store.js';
8
+ const path = /^\/v1\/orgs\/([^/]+)\/apps\/([^/]+)\/envs\/([^/]+)\/capabilities(?:\/([^/]+)(?:\/(policy|test))?)?$/;
9
+ /** Operator diagnostic commands share policy/admission; they never expose source bodies. */
10
+ export function capabilityOperatorRoute(service) {
11
+ return {
12
+ id: 'managed-capabilities',
13
+ match: (_method, url) => path.test(url.pathname),
14
+ handle: async (req, res, ctx) => {
15
+ try {
16
+ const match = path.exec(new URL(req.url ?? '/', 'http://service.invalid').pathname);
17
+ if (!match)
18
+ return send(res, 404, { error: 'not_found' });
19
+ const scope = capabilityScopeSchema.parse({
20
+ org: match[1],
21
+ app: match[2],
22
+ env: match[3],
23
+ name: match[4] ?? 'list',
24
+ });
25
+ const { name, ...tenant } = scope;
26
+ const action = match[5];
27
+ const reading = req.method === 'GET' && action === undefined;
28
+ if (!reading &&
29
+ !(req.method === 'PUT' && action === 'policy') &&
30
+ !(req.method === 'POST' && action === 'test')) {
31
+ return send(res, 405, { error: 'method_not_allowed' });
32
+ }
33
+ const auth = await ctx.tenantControl?.authorize(req, {
34
+ org: scope.org,
35
+ permission: reading ? 'org:member' : 'org:manage',
36
+ });
37
+ if (auth?.ok !== true || auth.identity === undefined)
38
+ return send(res, auth?.ok === false ? auth.status : 401, {
39
+ error: 'capability_forbidden',
40
+ });
41
+ const target = await ctx.capabilityDeployments?.get(req, tenant);
42
+ if (target === undefined)
43
+ return send(res, 404, { error: 'deployment_not_found' });
44
+ // The service has already compiled and authorized these declarations. Diagnostics need only intent.
45
+ const declarations = target.declarations.map((raw) => webCapabilityBaseSchema.strip().parse(raw));
46
+ if (match[4] === undefined) {
47
+ return send(res, 200, capabilityListResponseSchema.parse({
48
+ deploymentId: target.deploymentId,
49
+ capabilities: await Promise.all(declarations.map((d) => service.inspect(tenant, d))),
50
+ }));
51
+ }
52
+ const declaration = declarations.find((d) => d.name === name);
53
+ if (declaration === undefined)
54
+ return send(res, 404, { error: 'capability_not_found' });
55
+ if (reading)
56
+ return send(res, 200, capabilityInspectionSchema.parse(await service.inspect(tenant, declaration)));
57
+ const body = await jsonBody(req);
58
+ if (action === 'policy') {
59
+ const update = capabilityPolicyUpdateSchema.parse(body);
60
+ const record = await service.configure(tenant, declaration, {
61
+ ...update,
62
+ actor: auth.identity.subject,
63
+ });
64
+ await ctx.audit?.emit({
65
+ eventType: 'capability.policy.updated',
66
+ ...tenant,
67
+ actorSubject: auth.identity.subject,
68
+ deploymentId: target.deploymentId,
69
+ details: { name, revision: record.revision, enabled: record.policy.enabled },
70
+ });
71
+ return send(res, 200, capabilityInspectionSchema.parse(await service.inspect(tenant, declaration)));
72
+ }
73
+ const test = capabilityTestRequestSchema.parse(body);
74
+ const cancelled = new AbortController();
75
+ const abort = () => cancelled.abort();
76
+ req.once('aborted', abort);
77
+ res.once('close', abort);
78
+ try {
79
+ const result = await service.execute(declaration, test.request, {
80
+ tenant,
81
+ deploymentId: target.deploymentId,
82
+ executionId: randomUUID(),
83
+ subject: auth.identity.subject,
84
+ anonymous: false,
85
+ authorized: true,
86
+ budget: new CapabilityBudget(),
87
+ signal: cancelled.signal,
88
+ }, test.mode === 'fixture'
89
+ ? {
90
+ read: async ({ url }) => ({
91
+ url,
92
+ title: 'Diagnostic fixture',
93
+ text: 'Synthetic diagnostic evidence. No website was fetched.',
94
+ links: [],
95
+ retrievedAt: new Date().toISOString(),
96
+ }),
97
+ }
98
+ : undefined);
99
+ return send(res, 200, capabilityTestResponseSchema.parse({
100
+ mode: test.mode,
101
+ status: result.status,
102
+ pages: result.items.length,
103
+ sources: result.sources.map(({ ref, url, retrievedAt }) => ({
104
+ ref,
105
+ url,
106
+ retrievedAt,
107
+ })),
108
+ warnings: result.warnings,
109
+ }));
110
+ }
111
+ finally {
112
+ req.off('aborted', abort);
113
+ res.off('close', abort);
114
+ }
115
+ }
116
+ catch (error) {
117
+ const status = error instanceof CapabilityPolicyConflict
118
+ ? 409
119
+ : error instanceof z.ZodError
120
+ ? 400
121
+ : error instanceof CapabilityError
122
+ ? 422
123
+ : 503;
124
+ send(res, status, {
125
+ error: error instanceof CapabilityPolicyConflict
126
+ ? 'capability_policy_conflict'
127
+ : error instanceof z.ZodError
128
+ ? 'invalid_request'
129
+ : error instanceof CapabilityError
130
+ ? error.code
131
+ : 'capability_unavailable',
132
+ });
133
+ }
134
+ },
135
+ };
136
+ }
137
+ async function jsonBody(req) {
138
+ const chunks = [];
139
+ let size = 0;
140
+ for await (const raw of req) {
141
+ const chunk = Buffer.isBuffer(raw) ? raw : Buffer.from(raw);
142
+ size += chunk.length;
143
+ if (size > 16_384)
144
+ throw new CapabilityError('capability_source_rejected');
145
+ chunks.push(chunk);
146
+ }
147
+ try {
148
+ return JSON.parse(Buffer.concat(chunks).toString('utf8'));
149
+ }
150
+ catch {
151
+ throw new CapabilityError('capability_source_rejected');
152
+ }
153
+ }
154
+ function send(res, status, value) {
155
+ if (res.destroyed || res.writableEnded)
156
+ return;
157
+ res.writeHead(status, { 'content-type': 'application/json', 'cache-control': 'no-store' });
158
+ res.end(JSON.stringify(value));
159
+ }
160
+ //# sourceMappingURL=operator-route.js.map
@@ -0,0 +1,34 @@
1
+ import { type CapabilityPolicyRecord, type CapabilityPolicyUpdate, type CapabilityScope } from './operator-contracts.js';
2
+ export * from './operator-contracts.js';
3
+ export interface CapabilityPolicyStore {
4
+ readonly durable: boolean;
5
+ get(scope: CapabilityScope): Promise<CapabilityPolicyRecord | undefined>;
6
+ replace(scope: CapabilityScope, update: CapabilityPolicyUpdate): Promise<CapabilityPolicyRecord>;
7
+ }
8
+ export declare class CapabilityPolicyConflict extends Error {
9
+ constructor();
10
+ }
11
+ export declare function capabilityScopeKey(scope: CapabilityScope): string;
12
+ export declare function checkedPolicyUpdate(update: CapabilityPolicyUpdate): {
13
+ actor: string;
14
+ fingerprint: string;
15
+ expectedRevision: number;
16
+ mutationId: string;
17
+ policy: {
18
+ enabled: boolean;
19
+ dailyCalls: number;
20
+ maxUrls?: number | undefined;
21
+ maxCalls?: number | undefined;
22
+ timeoutMs?: number | undefined;
23
+ maxTextBytes?: number | undefined;
24
+ domains?: string[] | undefined;
25
+ };
26
+ };
27
+ /** Development/test only. Hosted composition rejects a non-durable policy or counter store. */
28
+ export declare class InMemoryCapabilityPolicyStore implements CapabilityPolicyStore {
29
+ #private;
30
+ readonly durable = false;
31
+ get(scope: CapabilityScope): Promise<CapabilityPolicyRecord | undefined>;
32
+ replace(scope: CapabilityScope, input: CapabilityPolicyUpdate): Promise<CapabilityPolicyRecord>;
33
+ }
34
+ //# sourceMappingURL=policy-store.d.ts.map
@@ -0,0 +1,61 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { z } from 'zod';
3
+ import { capabilityPolicyUpdateSchema, capabilityScopeSchema, } from './operator-contracts.js';
4
+ export * from './operator-contracts.js';
5
+ export class CapabilityPolicyConflict extends Error {
6
+ constructor() {
7
+ super('capability_policy_conflict');
8
+ }
9
+ }
10
+ export function capabilityScopeKey(scope) {
11
+ const parsed = capabilityScopeSchema.parse(scope);
12
+ return JSON.stringify([
13
+ parsed.org,
14
+ parsed.app,
15
+ parsed.env,
16
+ `capability.web-extract.${parsed.name}.provider`,
17
+ ]);
18
+ }
19
+ export function checkedPolicyUpdate(update) {
20
+ const { actor, ...body } = update;
21
+ const parsed = capabilityPolicyUpdateSchema.parse(body);
22
+ z.string().min(1).max(512).parse(actor);
23
+ const fingerprint = createHash('sha256')
24
+ .update(JSON.stringify({ ...parsed, actor }))
25
+ .digest('hex');
26
+ return { ...parsed, actor, fingerprint };
27
+ }
28
+ /** Development/test only. Hosted composition rejects a non-durable policy or counter store. */
29
+ export class InMemoryCapabilityPolicyStore {
30
+ durable = false;
31
+ #records = new Map();
32
+ async get(scope) {
33
+ const entry = this.#records.get(capabilityScopeKey(scope));
34
+ return entry === undefined ? undefined : structuredClone(entry.record);
35
+ }
36
+ async replace(scope, input) {
37
+ const key = capabilityScopeKey(scope);
38
+ const update = checkedPolicyUpdate(input);
39
+ const prior = this.#records.get(key);
40
+ if (prior?.mutationId === update.mutationId) {
41
+ if (prior.fingerprint !== update.fingerprint)
42
+ throw new CapabilityPolicyConflict();
43
+ return structuredClone(prior.record);
44
+ }
45
+ if ((prior?.record.revision ?? 0) !== update.expectedRevision)
46
+ throw new CapabilityPolicyConflict();
47
+ const record = {
48
+ revision: update.expectedRevision + 1,
49
+ policy: update.policy,
50
+ actor: update.actor,
51
+ updatedAt: new Date().toISOString(),
52
+ };
53
+ this.#records.set(key, {
54
+ record,
55
+ mutationId: update.mutationId,
56
+ fingerprint: update.fingerprint,
57
+ });
58
+ return structuredClone(record);
59
+ }
60
+ }
61
+ //# sourceMappingURL=policy-store.js.map
@@ -0,0 +1,10 @@
1
+ export { CapabilityBudget, type CapabilityBudgetSnapshot } from './budget.js';
2
+ export * from './contracts.js';
3
+ export { CAPABILITY_ERROR_CODES, CapabilityError, type CapabilityErrorCode } from './errors.js';
4
+ export { effectiveWebPolicy, executeWebExtract, type PublicPageReaderPort, type WebExtractDeps, } from './executor.js';
5
+ export { WEB_EXTRACT_LIMITS } from './limits.js';
6
+ export { capabilityOperatorRoute } from './operator-route.js';
7
+ export * from './policy-store.js';
8
+ export { type CapabilityInvocation, CapabilityService, type CapabilityServiceOptions, } from './service.js';
9
+ export { publicPageUrl } from './urls.js';
10
+ //# sourceMappingURL=portable.d.ts.map
@@ -0,0 +1,10 @@
1
+ export { CapabilityBudget } from './budget.js';
2
+ export * from './contracts.js';
3
+ export { CAPABILITY_ERROR_CODES, CapabilityError } from './errors.js';
4
+ export { effectiveWebPolicy, executeWebExtract, } from './executor.js';
5
+ export { WEB_EXTRACT_LIMITS } from './limits.js';
6
+ export { capabilityOperatorRoute } from './operator-route.js';
7
+ export * from './policy-store.js';
8
+ export { CapabilityService, } from './service.js';
9
+ export { publicPageUrl } from './urls.js';
10
+ //# sourceMappingURL=portable.js.map
@@ -0,0 +1,83 @@
1
+ import type { AtomicDailyCounterStore } from '@noodle-borg/admission-limits/portable';
2
+ import type { CapabilityBudget } from './budget.js';
3
+ import type { WebCapability, WebExtractResult } from './contracts.js';
4
+ import { type PublicPageReaderPort } from './executor.js';
5
+ import { type CapabilityPolicyStore, type CapabilityPolicyUpdate, type CapabilityScope } from './policy-store.js';
6
+ type Tenant = Pick<CapabilityScope, 'org' | 'app' | 'env'>;
7
+ export interface CapabilityServiceOptions {
8
+ readonly profile: 'development' | 'hosted';
9
+ readonly policies: CapabilityPolicyStore;
10
+ readonly counters: AtomicDailyCounterStore;
11
+ readonly reader: PublicPageReaderPort;
12
+ /** Exact hosted cohort targets. Empty or absent disables all hosted extraction. */
13
+ readonly enabledScopes?: readonly Tenant[];
14
+ readonly audit?: (fields: Readonly<Record<string, string | number | boolean>> & Tenant) => void | Promise<void>;
15
+ }
16
+ export interface CapabilityInvocation {
17
+ readonly tenant: Tenant;
18
+ readonly deploymentId: string;
19
+ readonly executionId: string;
20
+ readonly subject?: string;
21
+ readonly anonymous: boolean;
22
+ readonly network?: string;
23
+ readonly authorized: boolean;
24
+ readonly budget: CapabilityBudget;
25
+ readonly signal?: AbortSignal;
26
+ }
27
+ /** Policy/admission authority shared by normal tools and operator diagnostics. Never resolves a model. */
28
+ export declare class CapabilityService {
29
+ readonly options: CapabilityServiceOptions;
30
+ constructor(options: CapabilityServiceOptions);
31
+ enabled(tenant: Tenant): boolean;
32
+ inspect(tenant: Tenant, declaration: WebCapability): Promise<{
33
+ actor?: string;
34
+ updatedAt?: string;
35
+ name: string;
36
+ class: "web.extract.v1";
37
+ title: string;
38
+ serviceKey: string;
39
+ available: boolean;
40
+ profile: string;
41
+ revision: number;
42
+ developerPolicy: {
43
+ maxUrls?: number | undefined;
44
+ maxCalls?: number | undefined;
45
+ timeoutMs?: number | undefined;
46
+ maxTextBytes?: number | undefined;
47
+ domains?: string[] | undefined;
48
+ };
49
+ operatorPolicy: {
50
+ enabled: boolean;
51
+ dailyCalls: number;
52
+ maxUrls?: number | undefined;
53
+ maxCalls?: number | undefined;
54
+ timeoutMs?: number | undefined;
55
+ maxTextBytes?: number | undefined;
56
+ domains?: string[] | undefined;
57
+ };
58
+ effectivePolicy: {
59
+ maxUrls?: number | undefined;
60
+ maxCalls?: number | undefined;
61
+ timeoutMs?: number | undefined;
62
+ maxTextBytes?: number | undefined;
63
+ domains?: string[] | undefined;
64
+ };
65
+ }>;
66
+ configure(tenant: Tenant, declaration: WebCapability, update: CapabilityPolicyUpdate): Promise<{
67
+ revision: number;
68
+ policy: {
69
+ enabled: boolean;
70
+ dailyCalls: number;
71
+ maxUrls?: number | undefined;
72
+ maxCalls?: number | undefined;
73
+ timeoutMs?: number | undefined;
74
+ maxTextBytes?: number | undefined;
75
+ domains?: string[] | undefined;
76
+ };
77
+ actor: string;
78
+ updatedAt: string;
79
+ }>;
80
+ execute(declaration: WebCapability, input: unknown, context: CapabilityInvocation, reader?: PublicPageReaderPort): Promise<WebExtractResult>;
81
+ }
82
+ export {};
83
+ //# sourceMappingURL=service.d.ts.map