@synap-core/workspace-templates 0.11.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +483 -0
- package/automations/bookmark-enrichment.automation.json +321 -0
- package/automations/github-pr-events.automation.json +505 -0
- package/automations/mail-feed.automation.json +86 -0
- package/automations/ship-a-change-checks-green.automation.json +106 -0
- package/automations/ship-a-change-checks-red.automation.json +106 -0
- package/automations/ship-a-change-deployed.automation.json +56 -0
- package/automations/ship-a-change-pr-merged.automation.json +110 -0
- package/automations/ship-a-change-pr-opened.automation.json +104 -0
- package/automations/url-bookmark-capture.automation.json +132 -0
- package/capabilities/agency-skills.capability.json +157 -0
- package/capabilities/apify.capability.json +265 -0
- package/capabilities/apollo.capability.json +120 -0
- package/capabilities/arch-backend.capability.json +97 -0
- package/capabilities/arch-client-intelligence.capability.json +401 -0
- package/capabilities/backblaze-b2.capability.json +205 -0
- package/capabilities/cal-com.capability.json +266 -0
- package/capabilities/canva.capability.json +274 -0
- package/capabilities/claude-code-routines.capability.json +172 -0
- package/capabilities/claude-managed-agents.capability.json +215 -0
- package/capabilities/client-comms-report.capability.json +246 -0
- package/capabilities/content-idea-to-production.capability.json +29 -0
- package/capabilities/datagouv.capability.json +315 -0
- package/capabilities/discord-bot.capability.json +157 -0
- package/capabilities/dropbox.capability.json +281 -0
- package/capabilities/exa.capability.json +109 -0
- package/capabilities/fal-ai.capability.json +83 -0
- package/capabilities/fal-media-lab.capability.json +158 -0
- package/capabilities/fireflies.capability.json +191 -0
- package/capabilities/freellmapi.capability.json +114 -0
- package/capabilities/generic-apikey.capability.json +92 -0
- package/capabilities/github-merge.capability.json +99 -0
- package/capabilities/github-read.capability.json +325 -0
- package/capabilities/governance-tighten-recommender.capability.json +81 -0
- package/capabilities/jev.capability.json +226 -0
- package/capabilities/lead-conversion-enrollment.capability.json +246 -0
- package/capabilities/mail-feed.capability.json +277 -0
- package/capabilities/mailgun.capability.json +52 -0
- package/capabilities/nango-google.capability.json +639 -0
- package/capabilities/notion.capability.json +417 -0
- package/capabilities/omniroute.capability.json +137 -0
- package/capabilities/posthog-analytics.capability.json +258 -0
- package/capabilities/postiz.capability.json +467 -0
- package/capabilities/proactive-digest.capability.json +190 -0
- package/capabilities/proton.capability.json +288 -0
- package/capabilities/replicate-rvm.capability.json +97 -0
- package/capabilities/research-methods.capability.json +57 -0
- package/capabilities/shopify.capability.json +395 -0
- package/capabilities/slack.capability.json +369 -0
- package/capabilities/stripe.capability.json +420 -0
- package/capabilities/telegram-bridge.capability.json +56 -0
- package/capabilities/treg.capability.json +102 -0
- package/capabilities/unipile-linkedin.capability.json +471 -0
- package/capabilities/vercel.capability.json +424 -0
- package/dist/define-CPS0n8BV.d.ts +1331 -0
- package/dist/index.d.ts +189 -900
- package/dist/index.js +24654 -21639
- package/dist/index.js.map +1 -1
- package/dist/wire.d.ts +222 -0
- package/dist/wire.js +77 -0
- package/dist/wire.js.map +1 -0
- package/package.json +41 -27
- package/packs/bookmark-views-pack.json +33 -0
- package/packs/crm-pack.json +76 -0
- package/packs/customer-profile.json +28 -0
- package/packs/deep-research.playbook.json +30 -0
- package/packs/event-views-pack.json +33 -0
- package/packs/habit-profile.json +27 -0
- package/packs/hr-pack.json +54 -0
- package/packs/invoice-profile.json +28 -0
- package/packs/knowledge-base-pack.json +56 -0
- package/packs/meeting-profile.json +29 -0
- package/packs/product-profile.json +30 -0
- package/packs/project-management-pack.json +49 -0
- package/packs/recipe-profile.json +29 -0
- package/packs/task-views-pack.json +39 -0
- package/retired.yaml +136 -0
- package/skills/app-factory-build-slice/SKILL.md +70 -0
- package/skills/app-factory-build-slice.catalog.json +17 -0
- package/skills/app-factory-design-canvas/SKILL.md +96 -0
- package/skills/app-factory-design-canvas.catalog.json +17 -0
- package/skills/app-factory-design-review/SKILL.md +99 -0
- package/skills/app-factory-design-review.catalog.json +18 -0
- package/skills/app-factory-research/SKILL.md +123 -0
- package/skills/app-factory-research.catalog.json +17 -0
- package/skills/bookmark-enrichment/SKILL.md +40 -0
- package/skills/carousel-format/carousel-format.skill.json +18 -0
- package/skills/collage-broll/collage-broll.skill.json +20 -0
- package/skills/content-taste/content-taste.skill.json +18 -0
- package/skills/creative-director/creative-director.skill.json +18 -0
- package/skills/design-critique/SKILL.md +135 -0
- package/skills/design-critique.catalog.json +12 -0
- package/skills/designing-with-real-components/SKILL.md +140 -0
- package/skills/designing-with-real-components.catalog.json +12 -0
- package/skills/edit-loop/edit-loop.skill.json +25 -0
- package/skills/facecam-edit/facecam-edit.skill.json +24 -0
- package/skills/mapping-the-server/SKILL.md +54 -0
- package/skills/math-explainer-manimgx/math-explainer-manimgx.skill.json +20 -0
- package/skills/motion-quality-gates/motion-quality-gates.skill.json +20 -0
- package/skills/open-design-edit/open-design-edit.skill.json +24 -0
- package/skills/reading-client-progress/SKILL.md +65 -0
- package/skills/routing-to-channels/SKILL.md +54 -0
- package/skills/stellar-scf-grants-advisor/ASSOCIATE-CHEATSHEET.md +133 -0
- package/skills/stellar-scf-grants-advisor/ASSOCIATE-ONBOARDING-GUIDE.md +761 -0
- package/skills/stellar-scf-grants-advisor/CLIENT-FAQ.md +181 -0
- package/skills/stellar-scf-grants-advisor/PARTNER-HANDOVER.md +130 -0
- package/skills/stellar-scf-grants-advisor/SKILL.md +102 -0
- package/skills/stellar-scf-grants-advisor/examples/README.md +43 -0
- package/skills/stellar-scf-grants-advisor/examples/chat-summary-templates.md +158 -0
- package/skills/stellar-scf-grants-advisor/examples/corpus-comparable-rows.md +136 -0
- package/skills/stellar-scf-grants-advisor/examples/q10-team-rewrites.md +109 -0
- package/skills/stellar-scf-grants-advisor/examples/q2-description-rewrites.md +88 -0
- package/skills/stellar-scf-grants-advisor/examples/q6-integration-rewrites.md +107 -0
- package/skills/stellar-scf-grants-advisor/examples/tranche-structures.md +176 -0
- package/skills/stellar-scf-grants-advisor/reference/01-methodology.md +96 -0
- package/skills/stellar-scf-grants-advisor/reference/02-scoring-framework.md +199 -0
- package/skills/stellar-scf-grants-advisor/reference/03-rejection-patterns.md +241 -0
- package/skills/stellar-scf-grants-advisor/reference/04-winner-patterns.md +120 -0
- package/skills/stellar-scf-grants-advisor/reference/05-comeback-patterns.md +92 -0
- package/skills/stellar-scf-grants-advisor/reference/06-budget-benchmarks.md +125 -0
- package/skills/stellar-scf-grants-advisor/reference/07-integration-list.md +147 -0
- package/skills/stellar-scf-grants-advisor/reference/08-abstract-fields.md +258 -0
- package/skills/stellar-scf-grants-advisor/reference/09-build-fields.md +259 -0
- package/skills/stellar-scf-grants-advisor/reference/10-corpus-winners.md +135 -0
- package/skills/stellar-scf-grants-advisor/reference/11-corpus-rejects.md +267 -0
- package/skills/stellar-scf-grants-advisor/reference/12-client-communication.md +131 -0
- package/skills/stellar-scf-grants-advisor/reference/13-excel-output-spec.md +199 -0
- package/skills/stellar-scf-grants-advisor/reference/14-worked-examples.md +160 -0
- package/skills/stellar-scf-grants-advisor/templates/abstract-review-builder.py +253 -0
- package/skills/stellar-scf-grants-advisor/templates/build-review-builder.py +213 -0
- package/skills/video-direction/video-direction.skill.json +20 -0
- package/skills/video-style-vocabulary/video-style-vocabulary.skill.json +20 -0
- package/skills/video-toolbox/video-toolbox.skill.json +20 -0
- package/src/__fixtures__/lifecycle-presets.flat-before.json +205 -0
- package/src/agency-os.yaml +122 -0
- package/src/agent-os-skill-slugs.test.ts +65 -0
- package/src/apify-social-reader.test.ts +317 -0
- package/src/base.template.test.ts +25 -19
- package/src/base.yaml +95 -39
- package/src/blockchain-ecosystem.yaml +1 -0
- package/src/brand-library.yaml +525 -14
- package/src/builder-dev-fold.template.test.ts +113 -0
- package/src/builder.yaml +798 -92
- package/src/business-model-catalog-description.test.ts +47 -0
- package/src/business-model-grp.template.test.ts +214 -0
- package/src/business-model.yaml +598 -0
- package/src/catalog-safety.test.ts +198 -0
- package/src/catalog.template-items.test.ts +75 -0
- package/src/catalog.ts +85 -2
- package/src/civic-france.yaml +102 -0
- package/src/concept-guard.test.ts +28 -8
- package/src/concept-guard.ts +2 -2
- package/src/content-creation.template.test.ts +52 -0
- package/src/content-creation.yaml +192 -0
- package/src/content-os.edit-loop.template.test.ts +210 -0
- package/src/content-os.publish-due-posts.template.test.ts +261 -0
- package/src/content-os.template.test.ts +322 -0
- package/src/content-os.video-takes.template.test.ts +338 -0
- package/src/content-os.work-a-take.template.test.ts +125 -0
- package/src/content-os.yaml +1830 -39
- package/src/content-studio-retired.template.test.ts +82 -0
- package/src/corpus-flow-validity.test.ts +4 -5
- package/src/crm-absorbs-outreach.template.test.ts +117 -0
- package/src/crm-build-plan.template.test.ts +128 -0
- package/src/crm-lists.template.test.ts +96 -0
- package/src/crm-messages-cadence.template.test.ts +164 -0
- package/src/crm-one-send-door.template.test.ts +65 -0
- package/src/crm.yaml +1456 -181
- package/src/decisions-wave.template.test.ts +186 -0
- package/src/define.ts +130 -17
- package/src/design-to-implementation.template.test.ts +94 -0
- package/src/dist-freshness.test.ts +97 -0
- package/src/domain-template-type.test.ts +75 -0
- package/src/ecosystem.yaml +27 -66
- package/src/enterprise-os.yaml +10 -134
- package/src/facecam-edit.audio-studio.test.ts +188 -0
- package/src/fal-generate-image.test.ts +200 -0
- package/src/fal-media-lab-pod-files.test.ts +180 -0
- package/src/finance.yaml +254 -1
- package/src/foundation.yaml +130 -28
- package/src/frame-host-modules.d.mts +6 -0
- package/src/frame-host-modules.mjs +58 -0
- package/src/generate.mjs +9 -3
- package/src/github-merge.test.ts +210 -0
- package/src/grants.yaml +57 -17
- package/src/hr.yaml +39 -6
- package/src/index.ts +36 -1
- package/src/intent.test.ts +161 -0
- package/src/internal-runbook.yaml +19 -1
- package/src/jev.test.ts +356 -0
- package/src/legal.yaml +33 -1
- package/src/life-os.yaml +65 -240
- package/src/lifecycle-coverage.test.ts +124 -0
- package/src/lifecycle-declarations.test.ts +252 -0
- package/src/lifecycle-presets.test.ts +468 -0
- package/src/lifecycle-presets.ts +494 -0
- package/src/lifecycle-stuck.test.ts +46 -0
- package/src/lifecycle-waits.parity.test.ts +319 -0
- package/src/marketing.yaml +108 -4
- package/src/meetings-knowledge.yaml +18 -0
- package/src/networking.yaml +23 -2
- package/src/operations.yaml +304 -4
- package/src/pipeline-views.template.test.ts +88 -0
- package/src/playbook-goal-placeholders.test.ts +57 -0
- package/src/postiz-contract.test.ts +134 -0
- package/src/presentation-declarations.test.ts +174 -0
- package/src/process-contract.validate.test.ts +352 -0
- package/src/project-management.yaml +39 -740
- package/src/publish-body.d.mts +29 -0
- package/src/publish-body.mjs +74 -0
- package/src/publish-body.test.ts +74 -0
- package/src/publish-official-lib.test.ts +176 -0
- package/src/replicate-rvm.test.ts +504 -0
- package/src/research-base.yaml +119 -20
- package/src/research-decision.yaml +60 -3
- package/src/reserved-profile-slugs.test.ts +83 -0
- package/src/retired-goal-kinds.test.ts +58 -0
- package/src/role-reference-and-step-domain.test.ts +192 -0
- package/src/seed-obligation.test.ts +176 -0
- package/src/send-message-maps.test.ts +227 -0
- package/src/shared-role-ssot.test.ts +42 -1
- package/src/ship-a-change.template.test.ts +177 -0
- package/src/skills.test.ts +170 -0
- package/src/social.yaml +85 -27
- package/src/space-packages.freshness.test.ts +97 -0
- package/src/space-packages.generated.ts +40 -0
- package/src/space-packages.test.ts +125 -0
- package/src/space-packages.ts +73 -0
- package/src/start.test.ts +188 -0
- package/src/task-intents.test.ts +293 -0
- package/src/templates.ts +21639 -21522
- package/src/types.ts +443 -60
- package/src/unipile-publish-post.test.ts +162 -0
- package/src/validate-flow.drift.test.ts +2 -3
- package/src/validate-flow.ts +32 -2
- package/src/validate-onboarding.test.ts +59 -0
- package/src/validate.test.ts +156 -3
- package/src/validate.ts +1384 -7
- package/src/wire-core.ts +231 -0
- package/src/wire.test.ts +159 -0
- package/src/wire.ts +107 -0
- package/src/__fixtures__/report-automation-flow.json +0 -393
- package/src/agent-fleet.yaml +0 -1645
- package/src/business-developer.template.test.ts +0 -351
- package/src/business-developer.yaml +0 -860
- package/src/content-studio.yaml +0 -361
- package/src/dev-dashboard.yaml +0 -990
- package/src/outreach-comms.yaml +0 -486
- package/src/the-arch.yaml +0 -201
package/src/jev.test.ts
ADDED
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jev (capability `jev`): the four verbs speak TypeSafe's System One API.
|
|
3
|
+
*
|
|
4
|
+
* SEAM: each verb's REAL `code` body, run the way the pod's executor wraps it
|
|
5
|
+
* (`async (args, context) => { <code> }` with `callProvider` in scope), against
|
|
6
|
+
* responses shaped like TypeSafe's documented examples
|
|
7
|
+
* (https://docs.typesafe.ai/api/system-one.md, OpenAPI 0.2.0, read 2026-10-28).
|
|
8
|
+
* The request asserted is exactly what `callProvider` would send.
|
|
9
|
+
*
|
|
10
|
+
* NOT covered: Jev's live behaviour (the founder's own install is the live
|
|
11
|
+
* test), the pod's `{{param}}` interpolation (simulated below the way
|
|
12
|
+
* `interpolateDeep` does it) and the IS isolate (Node's AsyncFunction is used).
|
|
13
|
+
*/
|
|
14
|
+
import { readFileSync } from "node:fs";
|
|
15
|
+
import { dirname, join } from "node:path";
|
|
16
|
+
import { fileURLToPath } from "node:url";
|
|
17
|
+
import { describe, expect, it } from "vitest";
|
|
18
|
+
|
|
19
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
20
|
+
const manifest = JSON.parse(
|
|
21
|
+
readFileSync(join(HERE, "../capabilities/jev.capability.json"), "utf8")
|
|
22
|
+
);
|
|
23
|
+
type Skill = {
|
|
24
|
+
name: string;
|
|
25
|
+
code?: string;
|
|
26
|
+
parameters?: Record<string, string>;
|
|
27
|
+
};
|
|
28
|
+
const skills = manifest.spec.skills as Skill[];
|
|
29
|
+
|
|
30
|
+
const AsyncFunction = Object.getPrototypeOf(async () => {}).constructor as new (
|
|
31
|
+
...args: string[]
|
|
32
|
+
) => (...a: unknown[]) => Promise<unknown>;
|
|
33
|
+
|
|
34
|
+
type Call = {
|
|
35
|
+
tool: string;
|
|
36
|
+
method: string;
|
|
37
|
+
path: string;
|
|
38
|
+
input: Record<string, any>;
|
|
39
|
+
};
|
|
40
|
+
function verb(name: string) {
|
|
41
|
+
const code = skills.find((s) => s.name === name)!.code!;
|
|
42
|
+
const body = new AsyncFunction("args", "context", "callProvider", code);
|
|
43
|
+
return async (
|
|
44
|
+
args: Record<string, unknown>,
|
|
45
|
+
answers: Record<string, unknown>,
|
|
46
|
+
status = 200
|
|
47
|
+
) => {
|
|
48
|
+
const calls: Call[] = [];
|
|
49
|
+
const callProvider = async (
|
|
50
|
+
tool: string,
|
|
51
|
+
method: string,
|
|
52
|
+
path: string,
|
|
53
|
+
input: Record<string, any>
|
|
54
|
+
) => {
|
|
55
|
+
calls.push({ tool, method, path, input });
|
|
56
|
+
return {
|
|
57
|
+
status,
|
|
58
|
+
headers: {},
|
|
59
|
+
body: {
|
|
60
|
+
model: input.model,
|
|
61
|
+
answers,
|
|
62
|
+
usage: { input_tokens: 120, output_tokens: 12 },
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
const out = (await body(args, {}, callProvider)) as Record<string, any>;
|
|
67
|
+
return { out, calls };
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* What the pod checks BEFORE a verb runs (backend validate-verb-parameters.ts):
|
|
73
|
+
* each declared field's base type against the argument's runtime type, and
|
|
74
|
+
* required fields present. The live run of 28 Oct was refused there ("options
|
|
75
|
+
* should be array, got object") while every code-level test passed.
|
|
76
|
+
*/
|
|
77
|
+
function declaredTypeErrors(
|
|
78
|
+
name: string,
|
|
79
|
+
args: Record<string, unknown>
|
|
80
|
+
): string[] {
|
|
81
|
+
const declared = skills.find((s) => s.name === name)!.parameters ?? {};
|
|
82
|
+
const kind = (v: unknown) =>
|
|
83
|
+
Array.isArray(v) ? "array" : v === null ? "null" : typeof v;
|
|
84
|
+
const errors: string[] = [];
|
|
85
|
+
for (const [field, type] of Object.entries(declared)) {
|
|
86
|
+
const optional = type.endsWith("?");
|
|
87
|
+
const base = type.replace(/\?$/, "");
|
|
88
|
+
if (!(field in args)) {
|
|
89
|
+
if (!optional) errors.push(`${field} missing`);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (kind(args[field]) !== base)
|
|
93
|
+
errors.push(`${field} should be ${base}, got ${kind(args[field])}`);
|
|
94
|
+
}
|
|
95
|
+
return errors;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const STATE =
|
|
99
|
+
"I was charged twice for my subscription this month. Please refund the extra charge.";
|
|
100
|
+
|
|
101
|
+
describe("jev_choose — one choice question, Jev's probabilities and confidence back", () => {
|
|
102
|
+
it("sends one POST /v1/systemone through jev_api with the options as criteria", async () => {
|
|
103
|
+
const { out, calls } = await verb("jev_choose")(
|
|
104
|
+
{
|
|
105
|
+
state: STATE,
|
|
106
|
+
question: "What is the tone?",
|
|
107
|
+
options: ["angry", "calm"],
|
|
108
|
+
descriptions: { angry: "An upset message", calm: "A polite message" },
|
|
109
|
+
minConfidence: 0.6,
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
decision: {
|
|
113
|
+
type: "choice",
|
|
114
|
+
choice: "calm",
|
|
115
|
+
confidence: 0.7,
|
|
116
|
+
probabilities: { angry: 0.2, calm: 0.8 },
|
|
117
|
+
},
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
expect(calls).toEqual([
|
|
121
|
+
{
|
|
122
|
+
tool: "jev_api",
|
|
123
|
+
method: "POST",
|
|
124
|
+
path: "/v1/systemone",
|
|
125
|
+
input: {
|
|
126
|
+
model: "jev-latest",
|
|
127
|
+
state: STATE,
|
|
128
|
+
questions: {
|
|
129
|
+
decision: {
|
|
130
|
+
type: "choice",
|
|
131
|
+
instructions: "What is the tone?",
|
|
132
|
+
criteria: { angry: "An upset message", calm: "A polite message" },
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
]);
|
|
138
|
+
expect(out).toMatchObject({
|
|
139
|
+
choice: "calm",
|
|
140
|
+
confidence: 0.7,
|
|
141
|
+
confident: true,
|
|
142
|
+
probabilities: { angry: 0.2, calm: 0.8 },
|
|
143
|
+
model: "jev-latest",
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("a list of options becomes criteria keyed by the option; under minConfidence is not confident", async () => {
|
|
148
|
+
const { out, calls } = await verb("jev_choose")(
|
|
149
|
+
{
|
|
150
|
+
state: STATE,
|
|
151
|
+
question: "Which team?",
|
|
152
|
+
options: ["billing", "support", "none_of_these"],
|
|
153
|
+
minConfidence: 0.8,
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
decision: {
|
|
157
|
+
type: "choice",
|
|
158
|
+
choice: "billing",
|
|
159
|
+
confidence: 0.55,
|
|
160
|
+
probabilities: { billing: 0.6, support: 0.3, none_of_these: 0.1 },
|
|
161
|
+
},
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
expect(calls[0].input.questions.decision.criteria).toEqual({
|
|
165
|
+
billing: "billing",
|
|
166
|
+
support: "support",
|
|
167
|
+
none_of_these: "none_of_these",
|
|
168
|
+
});
|
|
169
|
+
expect(out.confident).toBe(false);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it("a model passed in the call is the one sent", async () => {
|
|
173
|
+
const { calls } = await verb("jev_choose")(
|
|
174
|
+
{
|
|
175
|
+
state: STATE,
|
|
176
|
+
question: "Tone?",
|
|
177
|
+
options: ["angry", "calm"],
|
|
178
|
+
model: "jev-1.14.0",
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
decision: {
|
|
182
|
+
type: "choice",
|
|
183
|
+
choice: "calm",
|
|
184
|
+
confidence: 0.9,
|
|
185
|
+
probabilities: {},
|
|
186
|
+
},
|
|
187
|
+
}
|
|
188
|
+
);
|
|
189
|
+
expect(calls[0].input.model).toBe("jev-1.14.0");
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it("refuses fewer than 2 options or no state, before calling Jev", async () => {
|
|
193
|
+
await expect(
|
|
194
|
+
verb("jev_choose")(
|
|
195
|
+
{ state: STATE, question: "Tone?", options: ["calm"] },
|
|
196
|
+
{}
|
|
197
|
+
)
|
|
198
|
+
).rejects.toThrow(/at least 2 options/);
|
|
199
|
+
await expect(
|
|
200
|
+
verb("jev_choose")({ question: "Tone?", options: ["a", "b"] }, {})
|
|
201
|
+
).rejects.toThrow(/state is required/);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it("a non-2xx answer fails loudly with Jev's status", async () => {
|
|
205
|
+
await expect(
|
|
206
|
+
verb("jev_choose")(
|
|
207
|
+
{ state: STATE, question: "Tone?", options: ["a", "b"] },
|
|
208
|
+
{},
|
|
209
|
+
429
|
|
210
|
+
)
|
|
211
|
+
).rejects.toThrow(/Jev answered 429/);
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
describe("the template can be updated on every pod", () => {
|
|
216
|
+
// The pod's capability reconcile refuses to re-apply a skill whose code carries an
|
|
217
|
+
// install-time {{param}} ("manual re-apply needed"): on 28 Oct every installed jev was stuck
|
|
218
|
+
// on its install-day version because each verb baked {{jevModel}} into its code.
|
|
219
|
+
const codeSkills = skills.filter((s) => s.code && s.name.startsWith("jev_"));
|
|
220
|
+
|
|
221
|
+
it("sees every verb's code (the scan is not empty)", () => {
|
|
222
|
+
expect(codeSkills.map((s) => s.name).sort()).toEqual([
|
|
223
|
+
"jev_ask",
|
|
224
|
+
"jev_choose",
|
|
225
|
+
"jev_noul",
|
|
226
|
+
"jev_score",
|
|
227
|
+
]);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it.each(codeSkills.map((s) => [s.name, s.code!] as const))(
|
|
231
|
+
"%s carries no install-time placeholder in its code",
|
|
232
|
+
(_name, code) => {
|
|
233
|
+
expect(code).not.toMatch(/\{\{\s*\w+\s*\}\}/);
|
|
234
|
+
}
|
|
235
|
+
);
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
describe("every verb speaks System One", () => {
|
|
239
|
+
// Each verb carries its own copy of the call helper (skill code is standalone), so each is checked.
|
|
240
|
+
const cases: Array<[string, Record<string, unknown>]> = [
|
|
241
|
+
[
|
|
242
|
+
"jev_choose",
|
|
243
|
+
{
|
|
244
|
+
state: STATE,
|
|
245
|
+
question: "Tone?",
|
|
246
|
+
options: ["a", "b"],
|
|
247
|
+
descriptions: { a: "first", b: "second" },
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
[
|
|
251
|
+
"jev_score",
|
|
252
|
+
{ state: STATE, question: "Urgency?", levels: ["low", "high"] },
|
|
253
|
+
],
|
|
254
|
+
["jev_noul", { state: STATE, question: "Billing?" }],
|
|
255
|
+
[
|
|
256
|
+
"jev_ask",
|
|
257
|
+
{
|
|
258
|
+
state: STATE,
|
|
259
|
+
questions: { q: { type: "noul", instructions: "Billing?" } },
|
|
260
|
+
},
|
|
261
|
+
],
|
|
262
|
+
];
|
|
263
|
+
it.each(cases)(
|
|
264
|
+
"%s posts to /v1/systemone through jev_api with the default model",
|
|
265
|
+
async (name, args) => {
|
|
266
|
+
expect(declaredTypeErrors(name, args)).toEqual([]);
|
|
267
|
+
const { calls } = await verb(name)(args, {});
|
|
268
|
+
expect(calls).toHaveLength(1);
|
|
269
|
+
expect(calls[0]).toMatchObject({
|
|
270
|
+
tool: "jev_api",
|
|
271
|
+
method: "POST",
|
|
272
|
+
path: "/v1/systemone",
|
|
273
|
+
input: { model: "jev-latest", state: STATE },
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
describe("jev_score, jev_noul, jev_ask — the other primitives", () => {
|
|
280
|
+
it("jev_score sends ordered levels as criteria and returns the score", async () => {
|
|
281
|
+
const { out, calls } = await verb("jev_score")(
|
|
282
|
+
{
|
|
283
|
+
state: STATE,
|
|
284
|
+
question: "How urgent?",
|
|
285
|
+
levels: ["Can wait", "This week", "Today"],
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
rating: {
|
|
289
|
+
type: "score",
|
|
290
|
+
score: 1.7,
|
|
291
|
+
confidence: 0.55,
|
|
292
|
+
legend: { "0": "Can wait", "1": "This week", "2": "Today" },
|
|
293
|
+
probabilities: { "0": 0.1, "1": 0.1, "2": 0.8 },
|
|
294
|
+
},
|
|
295
|
+
}
|
|
296
|
+
);
|
|
297
|
+
expect(calls[0].input.questions).toEqual({
|
|
298
|
+
rating: {
|
|
299
|
+
type: "score",
|
|
300
|
+
instructions: "How urgent?",
|
|
301
|
+
criteria: ["Can wait", "This week", "Today"],
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
expect(out).toMatchObject({ score: 1.7, confidence: 0.55 });
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it("jev_noul asks a yes/no question and returns the probability of yes", async () => {
|
|
308
|
+
const { out, calls } = await verb("jev_noul")(
|
|
309
|
+
{ state: STATE, question: "Is this about billing?" },
|
|
310
|
+
{ answer: { type: "noul", noul: 0.98 } }
|
|
311
|
+
);
|
|
312
|
+
expect(calls[0].input.questions).toEqual({
|
|
313
|
+
answer: { type: "noul", instructions: "Is this about billing?" },
|
|
314
|
+
});
|
|
315
|
+
expect(out.probabilityYes).toBe(0.98);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it("jev_ask sends several questions in ONE call and returns the answers by name", async () => {
|
|
319
|
+
const questions = {
|
|
320
|
+
billing: { type: "noul", instructions: "Is this about billing?" },
|
|
321
|
+
tone: {
|
|
322
|
+
type: "choice",
|
|
323
|
+
instructions: "Tone?",
|
|
324
|
+
criteria: { angry: "upset", calm: "polite" },
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
const answers = {
|
|
328
|
+
billing: { type: "noul", noul: 0.98 },
|
|
329
|
+
tone: {
|
|
330
|
+
type: "choice",
|
|
331
|
+
choice: "calm",
|
|
332
|
+
confidence: 0.7,
|
|
333
|
+
probabilities: { angry: 0.2, calm: 0.8 },
|
|
334
|
+
},
|
|
335
|
+
};
|
|
336
|
+
const { out, calls } = await verb("jev_ask")(
|
|
337
|
+
{ state: STATE, questions },
|
|
338
|
+
answers
|
|
339
|
+
);
|
|
340
|
+
expect(calls).toHaveLength(1);
|
|
341
|
+
expect(calls[0].input.questions).toEqual(questions);
|
|
342
|
+
expect(out.answers).toEqual(answers);
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
it("jev_ask refuses a question type Jev does not have", async () => {
|
|
346
|
+
await expect(
|
|
347
|
+
verb("jev_ask")(
|
|
348
|
+
{
|
|
349
|
+
state: STATE,
|
|
350
|
+
questions: { q: { type: "generate", instructions: "Write a reply" } },
|
|
351
|
+
},
|
|
352
|
+
{}
|
|
353
|
+
)
|
|
354
|
+
).rejects.toThrow(/use choice, score or noul/);
|
|
355
|
+
});
|
|
356
|
+
});
|
package/src/legal.yaml
CHANGED
|
@@ -13,6 +13,12 @@ meta:
|
|
|
13
13
|
color: "#4338CA"
|
|
14
14
|
tags: [legal, contracts, compliance, ip]
|
|
15
15
|
isPublic: true
|
|
16
|
+
# What this space PRODUCES (homes): the purpose word, then its kinds/roles.
|
|
17
|
+
intent:
|
|
18
|
+
label: Legal
|
|
19
|
+
produces:
|
|
20
|
+
- profile: legal-contract
|
|
21
|
+
- profile: compliance-item
|
|
16
22
|
|
|
17
23
|
workspace:
|
|
18
24
|
name: Legal
|
|
@@ -20,7 +26,10 @@ workspace:
|
|
|
20
26
|
proposalId: legal-v1
|
|
21
27
|
subtype: legal
|
|
22
28
|
visibility: members
|
|
23
|
-
|
|
29
|
+
# A DOMAIN workspace that holds entities — NOT `operational`. `operational`
|
|
30
|
+
# marks an admin/system surface: `isDomainHomeWorkspace` refuses filing
|
|
31
|
+
# entities into it and excludes it from auto-placement (2026-09-25).
|
|
32
|
+
workspaceType: personal
|
|
24
33
|
capabilities:
|
|
25
34
|
- legal.contracts
|
|
26
35
|
- legal.compliance
|
|
@@ -74,6 +83,17 @@ profiles:
|
|
|
74
83
|
icon: file-signature
|
|
75
84
|
color: violet
|
|
76
85
|
description: "A legal agreement with a counterparty — its status, term, and renewal."
|
|
86
|
+
# The ONE lifecycle (work model L1): every option's category.
|
|
87
|
+
lifecycle:
|
|
88
|
+
property: status
|
|
89
|
+
options:
|
|
90
|
+
- { key: draft, category: open }
|
|
91
|
+
- { key: in-review, category: active }
|
|
92
|
+
- { key: negotiation, category: active }
|
|
93
|
+
- { key: signed, category: active }
|
|
94
|
+
- { key: active, category: active }
|
|
95
|
+
- { key: expired, category: done }
|
|
96
|
+
- { key: terminated, category: lost }
|
|
77
97
|
properties:
|
|
78
98
|
- slug: contractType
|
|
79
99
|
label: Type
|
|
@@ -139,6 +159,15 @@ profiles:
|
|
|
139
159
|
icon: shield-check
|
|
140
160
|
color: cyan
|
|
141
161
|
description: "A regulatory or legal obligation with an owner and a deadline."
|
|
162
|
+
# The ONE lifecycle (work model L1): every option's category.
|
|
163
|
+
lifecycle:
|
|
164
|
+
property: status
|
|
165
|
+
options:
|
|
166
|
+
- { key: not-started, category: open }
|
|
167
|
+
- { key: in-progress, category: active }
|
|
168
|
+
- { key: submitted, category: active }
|
|
169
|
+
- { key: complete, category: done }
|
|
170
|
+
- { key: overdue, category: active }
|
|
142
171
|
properties:
|
|
143
172
|
- slug: obligationType
|
|
144
173
|
label: Obligation Type
|
|
@@ -498,14 +527,17 @@ onboarding:
|
|
|
498
527
|
lawyer, and not one invented legal conclusion anywhere in it.
|
|
499
528
|
collect:
|
|
500
529
|
- profileSlug: legal-entity
|
|
530
|
+
min: 1
|
|
501
531
|
what: The company's legal entities and the jurisdictions they operate in.
|
|
502
532
|
cardinality: few
|
|
503
533
|
keyFields: [entityType, jurisdiction, status]
|
|
504
534
|
- profileSlug: legal-contract
|
|
535
|
+
min: 1
|
|
505
536
|
what: The key live agreements — the ones with real obligations, value, or renewal dates.
|
|
506
537
|
cardinality: several
|
|
507
538
|
keyFields: [contractType, status, counterparty, renewalDate]
|
|
508
539
|
- profileSlug: compliance-item
|
|
540
|
+
min: 1
|
|
509
541
|
what: Compliance obligations and filings with real deadlines.
|
|
510
542
|
cardinality: several
|
|
511
543
|
keyFields: [obligationType, dueDate, owner]
|