@rubytech/create-realagent-code 0.1.615 → 0.1.616
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/package.json +1 -1
- package/payload/platform/lib/aeo-llms-txt-writer/dist/__tests__/write-llms-txt.test.d.ts +2 -0
- package/payload/platform/lib/aeo-llms-txt-writer/dist/__tests__/write-llms-txt.test.d.ts.map +1 -0
- package/payload/platform/lib/aeo-llms-txt-writer/dist/__tests__/write-llms-txt.test.js +291 -0
- package/payload/platform/lib/aeo-llms-txt-writer/dist/__tests__/write-llms-txt.test.js.map +1 -0
- package/payload/platform/lib/aeo-llms-txt-writer/dist/index.d.ts +13 -1
- package/payload/platform/lib/aeo-llms-txt-writer/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/aeo-llms-txt-writer/dist/index.js +127 -18
- package/payload/platform/lib/aeo-llms-txt-writer/dist/index.js.map +1 -1
- package/payload/platform/lib/aeo-llms-txt-writer/src/__tests__/write-llms-txt.test.ts +391 -0
- package/payload/platform/lib/aeo-llms-txt-writer/src/index.ts +156 -19
- package/payload/platform/lib/aeo-llms-txt-writer/vitest.config.ts +10 -0
- package/payload/platform/lib/mcp-spawn-tee/dist/index.d.ts +15 -1
- package/payload/platform/lib/mcp-spawn-tee/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/mcp-spawn-tee/dist/index.js +129 -7
- package/payload/platform/lib/mcp-spawn-tee/dist/index.js.map +1 -1
- package/payload/platform/lib/mcp-spawn-tee/src/__tests__/spawn-tee.test.ts +227 -0
- package/payload/platform/lib/mcp-spawn-tee/src/index.ts +133 -6
- package/payload/platform/plugins/admin/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/admin/mcp/dist/index.js +11 -3
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/tools/publish-site.d.ts +3 -0
- package/payload/platform/plugins/admin/mcp/dist/tools/publish-site.d.ts.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/tools/publish-site.js +38 -20
- package/payload/platform/plugins/admin/mcp/dist/tools/publish-site.js.map +1 -1
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +6 -5
- package/payload/platform/plugins/admin/skills/publish-site/SKILL.md +3 -0
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +8 -0
- package/payload/platform/plugins/aeo/PLUGIN.md +1 -1
- package/payload/platform/plugins/aeo/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/aeo/mcp/dist/index.js +17 -10
- package/payload/platform/plugins/aeo/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/browser/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/connector/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/contacts/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/dispatch/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/docs/references/aeo.md +4 -3
- package/payload/platform/plugins/docs/references/plugins-guide.md +1 -1
- package/payload/platform/plugins/email/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/filesystem/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/google/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/graph-viewer/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/inventory/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/ledger/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/memory/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/outlook/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/quickbooks/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/replicate/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/scheduling/PLUGIN.md +3 -4
- package/payload/platform/plugins/scheduling/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/scheduling/mcp/dist/index.js +0 -6
- package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js +65 -20
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-classification.test.js +20 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-classification.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts +12 -4
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js +39 -6
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js +21 -6
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +26 -5
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-waiver.test.js +17 -51
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-waiver.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.js +6 -4
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js +113 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts +8 -18
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +14 -27
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js +125 -56
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js.map +1 -1
- package/payload/platform/plugins/storage-broker/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/url-get/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/voice-mirror/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/whatsapp/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/work/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/workflows/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/services/claude-session-manager/dist/index.js +17 -0
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/mcp-helper-census.d.ts +80 -0
- package/payload/platform/services/claude-session-manager/dist/mcp-helper-census.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/mcp-helper-census.js +201 -0
- package/payload/platform/services/claude-session-manager/dist/mcp-helper-census.js.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/buyers/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/premium-plugins/real-agent/plugins/estate-sales/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/premium-plugins/real-agent/plugins/loop/PLUGIN.md +12 -0
- package/payload/premium-plugins/real-agent/plugins/loop/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/index.js +13 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/index.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/field-census.d.ts +22 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/field-census.d.ts.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/field-census.js +81 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/field-census.js.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/loop-api.d.ts +17 -5
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/loop-api.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/loop-api.js +90 -17
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/loop-api.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/loop-schema-keys.d.ts +2 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/loop-schema-keys.d.ts.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/loop-schema-keys.js +1010 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/loop-schema-keys.js.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/auto-responder.js +2 -2
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/auto-responder.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/customer-preferences.js +3 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/customer-preferences.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/feedback.d.ts +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/feedback.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/feedback.js +5 -5
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/feedback.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/marketing-match-batch.d.ts +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/marketing-match-batch.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/marketing-match-batch.js +2 -2
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/marketing-match-batch.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/marketing-match.d.ts +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/marketing-match.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/marketing-match.js +4 -4
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/marketing-match.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/people-detail.d.ts +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/people-detail.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/people-detail.js +3 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/people-detail.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/people-search.d.ts +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/people-search.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/people-search.js +3 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/people-search.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/property-detail.d.ts +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/property-detail.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/property-detail.js +13 -6
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/property-detail.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/property-listed.d.ts +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/property-listed.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/property-listed.js +3 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/property-listed.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/property-search.d.ts +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/property-search.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/property-search.js +3 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/property-search.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/property-sold.d.ts +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/property-sold.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/property-sold.js +3 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/property-sold.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/supplier.js +4 -4
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/supplier.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/team-availability.d.ts +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/team-availability.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/team-availability.js +3 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/team-availability.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/team-info.d.ts +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/team-info.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/team-info.js +3 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/team-info.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/viewing-detail.d.ts +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/viewing-detail.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/viewing-detail.js +3 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/viewing-detail.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/viewing-search.d.ts +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/viewing-search.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/viewing-search.js +3 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/viewing-search.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/package.json +2 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/scripts/generate-loop-schema-keys.mjs +87 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/__tests__/new-tool-shape.test.ts +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/__tests__/read-fidelity.test.ts +303 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/__tests__/swagger-write-coverage.test.ts +6 -6
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/index.ts +13 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/lib/field-census.ts +86 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/lib/loop-api.ts +116 -17
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/lib/loop-schema-keys.ts +1010 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/auto-responder.ts +2 -2
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/customer-preferences.ts +3 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/feedback.ts +6 -4
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/marketing-match-batch.ts +4 -2
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/marketing-match.ts +6 -4
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/people-detail.ts +5 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/people-search.ts +5 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/property-detail.ts +17 -7
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/property-listed.ts +5 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/property-search.ts +5 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/property-sold.ts +5 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/supplier.ts +4 -4
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/team-availability.ts +5 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/team-info.ts +6 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/viewing-detail.ts +5 -3
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/viewing-search.ts +5 -3
- package/payload/premium-plugins/real-agent/plugins/property-data/lib/mcp-spawn-tee/index.js +129 -7
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { selectLoopKeyStore } from "./key-store.js";
|
|
2
|
+
import { LOOP_SCHEMA_KEYS } from "./loop-schema-keys.js";
|
|
3
|
+
import {
|
|
4
|
+
censusRecords,
|
|
5
|
+
falsyPresentKeys,
|
|
6
|
+
matchPathPattern,
|
|
7
|
+
wireKeys,
|
|
8
|
+
} from "./field-census.js";
|
|
2
9
|
|
|
3
10
|
// ─────────────────────────────────────────────────────────────────
|
|
4
11
|
// Loop API V2 HTTP Client + Cross-Team Aggregation Engine
|
|
@@ -17,6 +24,12 @@ import { selectLoopKeyStore } from "./key-store.js";
|
|
|
17
24
|
// ─────────────────────────────────────────────────────────────────
|
|
18
25
|
|
|
19
26
|
const LOOP_BASE_URL = "https://api.loop.software";
|
|
27
|
+
|
|
28
|
+
// The Loop API version every path below targets. Declared once so tool output
|
|
29
|
+
// and log lines can both state which version a read actually reached. An agent
|
|
30
|
+
// reading either must never have to infer it from the shape of the paths: a
|
|
31
|
+
// capability audit did exactly that on 2026-08-18 and recorded v1.
|
|
32
|
+
export const LOOP_API_VERSION = "v2";
|
|
20
33
|
const REQUEST_TIMEOUT_MS = 10_000;
|
|
21
34
|
const TIMEOUT_RETRY_BACKOFF_MS = 2_000;
|
|
22
35
|
const DEFAULT_LIMIT_PER_TEAM = 50;
|
|
@@ -139,14 +152,58 @@ function logErrorBody(
|
|
|
139
152
|
);
|
|
140
153
|
}
|
|
141
154
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
155
|
+
// Two standing signals, both blind spots before this.
|
|
156
|
+
//
|
|
157
|
+
// field-census: a read that returned falsy-present keys while raw was off gave
|
|
158
|
+
// its caller a lossy answer. It fires on every read whether or not raw was
|
|
159
|
+
// asked for, because "nobody asked for raw" is exactly the failure being
|
|
160
|
+
// watched and it produces no event of its own. A log hung on the raw path
|
|
161
|
+
// would only ever record the reads that were already correct.
|
|
162
|
+
//
|
|
163
|
+
// schema-drift: Loop's own deploys change what arrives, which never reproduces
|
|
164
|
+
// on demand here. schemaOnly means Loop stopped sending documented fields;
|
|
165
|
+
// wireOnly means Loop added fields we have never seen. An unmatched path says
|
|
166
|
+
// so rather than skipping silently.
|
|
167
|
+
function emitReadSignals(toolName: string, path: string, data: unknown, raw: boolean): void {
|
|
168
|
+
const records = censusRecords(data);
|
|
169
|
+
const keys = wireKeys(data);
|
|
170
|
+
const falsy = falsyPresentKeys(data);
|
|
171
|
+
// falsyKeys unions across records, so it alone cannot separate one lossy row
|
|
172
|
+
// in two hundred from all two hundred. falsyRecords counts the rows carrying
|
|
173
|
+
// at least one, which is the difference between an edge case and a systemic
|
|
174
|
+
// gap in the operator's data.
|
|
175
|
+
const falsyRecords = records.filter((r) => falsyPresentKeys(r).length > 0).length;
|
|
176
|
+
|
|
177
|
+
console.error(
|
|
178
|
+
`[loop] op=field-census tool=${toolName} apiVersion=${LOOP_API_VERSION} ` +
|
|
179
|
+
`raw=${raw} records=${records.length} falsyRecords=${falsyRecords} ` +
|
|
180
|
+
`wireKeys=${keys.length} falsyKeys=${falsy.length ? falsy.join(",") : "-"}`
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
const patterns = Object.keys(LOOP_SCHEMA_KEYS);
|
|
184
|
+
const pattern = matchPathPattern(path, patterns);
|
|
185
|
+
if (!pattern) {
|
|
186
|
+
console.error(
|
|
187
|
+
`[loop] op=schema-drift tool=${toolName} apiVersion=${LOOP_API_VERSION} path=unmatched`
|
|
188
|
+
);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const documented = LOOP_SCHEMA_KEYS[pattern];
|
|
192
|
+
const schemaOnly = documented.filter((k) => !keys.includes(k));
|
|
193
|
+
const wireOnly = keys.filter((k) => !documented.includes(k));
|
|
194
|
+
console.error(
|
|
195
|
+
`[loop] op=schema-drift tool=${toolName} apiVersion=${LOOP_API_VERSION} path=${pattern} ` +
|
|
196
|
+
`schemaOnly=${schemaOnly.length ? schemaOnly.join(",") : "-"} ` +
|
|
197
|
+
`wireOnly=${wireOnly.length ? wireOnly.join(",") : "-"}`
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
145
201
|
export async function loopGet<T>(
|
|
146
202
|
apiKey: string,
|
|
147
203
|
path: string,
|
|
148
204
|
toolName: string,
|
|
149
|
-
teamName: string
|
|
205
|
+
teamName: string,
|
|
206
|
+
opts: { raw?: boolean } = {}
|
|
150
207
|
): Promise<T> {
|
|
151
208
|
const url = `${LOOP_BASE_URL}${path}`;
|
|
152
209
|
const start = Date.now();
|
|
@@ -158,7 +215,8 @@ export async function loopGet<T>(
|
|
|
158
215
|
|
|
159
216
|
const duration = Date.now() - start;
|
|
160
217
|
console.error(
|
|
161
|
-
`[loop]
|
|
218
|
+
`[loop] op=request tool=${toolName} apiVersion=${LOOP_API_VERSION} team=${teamName} ` +
|
|
219
|
+
`method=GET path=${path} status=${response.status} duration=${duration}ms`
|
|
162
220
|
);
|
|
163
221
|
|
|
164
222
|
if (response.status === 204) {
|
|
@@ -172,9 +230,10 @@ export async function loopGet<T>(
|
|
|
172
230
|
}
|
|
173
231
|
|
|
174
232
|
const text = await response.text();
|
|
233
|
+
let data: T;
|
|
175
234
|
try {
|
|
176
235
|
const parsed = JSON.parse(text);
|
|
177
|
-
|
|
236
|
+
data = unwrapEnvelope<T>(parsed, toolName, teamName);
|
|
178
237
|
} catch (err) {
|
|
179
238
|
if (err instanceof SyntaxError) {
|
|
180
239
|
throw new Error(
|
|
@@ -184,6 +243,13 @@ export async function loopGet<T>(
|
|
|
184
243
|
}
|
|
185
244
|
throw err;
|
|
186
245
|
}
|
|
246
|
+
|
|
247
|
+
// Outside the parse guard on purpose. Inside it, any throw from
|
|
248
|
+
// instrumentation was caught by a handler written for parse failures and
|
|
249
|
+
// re-thrown, which drops the whole team from the aggregate and blames Loop
|
|
250
|
+
// for a telemetry bug. Observability must never fail the read it observes.
|
|
251
|
+
emitReadSignals(toolName, path, data, opts.raw === true);
|
|
252
|
+
return data;
|
|
187
253
|
}
|
|
188
254
|
|
|
189
255
|
/**
|
|
@@ -214,7 +280,8 @@ export async function loopPost<T>(
|
|
|
214
280
|
|
|
215
281
|
const duration = Date.now() - start;
|
|
216
282
|
console.error(
|
|
217
|
-
`[loop]
|
|
283
|
+
`[loop] op=request kind=write tool=${toolName} apiVersion=${LOOP_API_VERSION} team=${teamName} ` +
|
|
284
|
+
`method=POST path=${path} status=${response.status} duration=${duration}ms`
|
|
218
285
|
);
|
|
219
286
|
|
|
220
287
|
if (response.status === 204) {
|
|
@@ -269,7 +336,8 @@ export async function loopPut<T>(
|
|
|
269
336
|
|
|
270
337
|
const duration = Date.now() - start;
|
|
271
338
|
console.error(
|
|
272
|
-
`[loop]
|
|
339
|
+
`[loop] op=request kind=write tool=${toolName} apiVersion=${LOOP_API_VERSION} team=${teamName} ` +
|
|
340
|
+
`method=PUT path=${path} status=${response.status} duration=${duration}ms`
|
|
273
341
|
);
|
|
274
342
|
|
|
275
343
|
if (response.status === 204) {
|
|
@@ -435,11 +503,11 @@ export async function aggregateAcrossTeams<T>(
|
|
|
435
503
|
const erroredCount = failures.length - timedOutCount;
|
|
436
504
|
|
|
437
505
|
console.error(
|
|
438
|
-
`[loop] aggregate tool=${toolName} teams=${keys.length} ` +
|
|
506
|
+
`[loop] aggregate tool=${toolName} apiVersion=${LOOP_API_VERSION} teams=${keys.length} ` +
|
|
439
507
|
`succeeded=${results.length} failed=${failures.length} skipped=${skipped.length}`
|
|
440
508
|
);
|
|
441
509
|
console.error(
|
|
442
|
-
`[loop] aggregate-coverage tool=${toolName} requested=${keys.length} ` +
|
|
510
|
+
`[loop] aggregate-coverage tool=${toolName} apiVersion=${LOOP_API_VERSION} requested=${keys.length} ` +
|
|
443
511
|
`answered=${results.length} timed_out=${timedOutCount} errored=${erroredCount}`
|
|
444
512
|
);
|
|
445
513
|
|
|
@@ -482,13 +550,37 @@ export async function withTeamKey<T>(
|
|
|
482
550
|
/**
|
|
483
551
|
* Format an aggregation result into a human-readable text response.
|
|
484
552
|
*/
|
|
553
|
+
/**
|
|
554
|
+
* Version header and raw rendering for the reads that do NOT aggregate across
|
|
555
|
+
* teams. `withTeamKey` tools format their own prose, so without this they were
|
|
556
|
+
* the four Loop reads that named no version and offered no way to see the
|
|
557
|
+
* field set — the exact defect this module exists to close, surviving in the
|
|
558
|
+
* corner the aggregation path does not cover.
|
|
559
|
+
*/
|
|
560
|
+
export function formatSingleTeamRead(
|
|
561
|
+
data: unknown,
|
|
562
|
+
prose: string,
|
|
563
|
+
opts: { raw?: boolean } = {}
|
|
564
|
+
): string {
|
|
565
|
+
const version = `Loop API ${LOOP_API_VERSION}`;
|
|
566
|
+
if (opts.raw === true) {
|
|
567
|
+
return `[${version}]\n\`\`\`json\n${JSON.stringify(data, null, 2)}\n\`\`\``;
|
|
568
|
+
}
|
|
569
|
+
return `[${version}] ${prose}`;
|
|
570
|
+
}
|
|
571
|
+
|
|
485
572
|
export function formatAggregationResult<T>(
|
|
486
573
|
result: AggregationResult<T>,
|
|
487
574
|
formatItem: (item: T, teamName: string) => string,
|
|
488
|
-
entityName: string
|
|
575
|
+
entityName: string,
|
|
576
|
+
opts: { raw?: boolean } = {}
|
|
489
577
|
): string {
|
|
578
|
+
// Every branch states the version the read reached. An agent must be able to
|
|
579
|
+
// answer "which version did I just read" from the output alone.
|
|
580
|
+
const version = `Loop API ${LOOP_API_VERSION}`;
|
|
581
|
+
|
|
490
582
|
if (result.totalTeams === 0) {
|
|
491
|
-
return
|
|
583
|
+
return `[${version}] No Loop teams registered. Use loop-key-register to add team API keys.`;
|
|
492
584
|
}
|
|
493
585
|
|
|
494
586
|
const allSkippedOrFailed =
|
|
@@ -499,7 +591,7 @@ export function formatAggregationResult<T>(
|
|
|
499
591
|
...result.failures.map((f) => `${f.teamName}: ${f.reason}`),
|
|
500
592
|
...result.skipped.map((s) => `${s.teamName}: ${s.reason}`),
|
|
501
593
|
];
|
|
502
|
-
return `All teams failed or were skipped:\n${reasons.join("\n")}`;
|
|
594
|
+
return `[${version}] All teams failed or were skipped:\n${reasons.join("\n")}`;
|
|
503
595
|
}
|
|
504
596
|
|
|
505
597
|
const lines: string[] = [];
|
|
@@ -510,7 +602,14 @@ export function formatAggregationResult<T>(
|
|
|
510
602
|
totalItems += teamResult.data.length;
|
|
511
603
|
lines.push(`\n## ${teamResult.teamName}`);
|
|
512
604
|
for (const item of teamResult.data) {
|
|
513
|
-
|
|
605
|
+
// Raw serialises the wire payload, not the interface, so a field no tool
|
|
606
|
+
// declares still appears — and 0, false and "" survive, which is the
|
|
607
|
+
// whole point: prose drops them and makes a zero look like an absence.
|
|
608
|
+
lines.push(
|
|
609
|
+
opts.raw === true
|
|
610
|
+
? "```json\n" + JSON.stringify(item, null, 2) + "\n```"
|
|
611
|
+
: formatItem(item, teamResult.teamName)
|
|
612
|
+
);
|
|
514
613
|
}
|
|
515
614
|
}
|
|
516
615
|
|
|
@@ -523,18 +622,18 @@ export function formatAggregationResult<T>(
|
|
|
523
622
|
|
|
524
623
|
if (totalItems === 0) {
|
|
525
624
|
if (failed > 0) {
|
|
526
|
-
return `No ${entityName} found across ${answered} of ${totalCovered} teams (${coverageNote}).`;
|
|
625
|
+
return `[${version}] No ${entityName} found across ${answered} of ${totalCovered} teams (${coverageNote}).`;
|
|
527
626
|
}
|
|
528
627
|
const teamCount =
|
|
529
628
|
result.results.length === 1
|
|
530
629
|
? result.results[0].teamName
|
|
531
630
|
: `${result.results.length} teams`;
|
|
532
|
-
return `No ${entityName} found across ${teamCount}.`;
|
|
631
|
+
return `[${version}] No ${entityName} found across ${teamCount}.`;
|
|
533
632
|
}
|
|
534
633
|
|
|
535
634
|
const teamCountFragment =
|
|
536
635
|
failed > 0 ? `${answered} of ${totalCovered} team(s)` : `${answered} team(s)`;
|
|
537
|
-
let header =
|
|
636
|
+
let header = `[${version}] ${totalItems} ${entityName} across ${teamCountFragment}:`;
|
|
538
637
|
const parts: string[] = [header, ...lines];
|
|
539
638
|
|
|
540
639
|
if (failed > 0) {
|