@kindgi/cli 0.1.6-rc.0 → 0.1.7-rc.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 +23 -12
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +84 -13
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/doctor.d.ts +5 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +102 -18
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/guardrails.d.ts.map +1 -1
- package/dist/commands/guardrails.js +13 -2
- package/dist/commands/guardrails.js.map +1 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +4 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +23 -3
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/license.d.ts +3 -0
- package/dist/commands/license.d.ts.map +1 -0
- package/dist/commands/license.js +187 -0
- package/dist/commands/license.js.map +1 -0
- package/dist/commands/mcp.js +1 -1
- package/dist/commands/providers.d.ts.map +1 -1
- package/dist/commands/providers.js +11 -9
- package/dist/commands/providers.js.map +1 -1
- package/dist/commands/test.d.ts.map +1 -1
- package/dist/commands/test.js +21 -9
- package/dist/commands/test.js.map +1 -1
- package/dist/commands/webhooks.d.ts +20 -0
- package/dist/commands/webhooks.d.ts.map +1 -0
- package/dist/commands/webhooks.js +444 -0
- package/dist/commands/webhooks.js.map +1 -0
- package/dist/context.d.ts +4 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +1 -0
- package/dist/context.js.map +1 -1
- package/dist/dev/already-running.d.ts +22 -0
- package/dist/dev/already-running.d.ts.map +1 -0
- package/dist/dev/already-running.js +72 -0
- package/dist/dev/already-running.js.map +1 -0
- package/dist/dev/defaults.d.ts.map +1 -1
- package/dist/dev/defaults.js +5 -2
- package/dist/dev/defaults.js.map +1 -1
- package/dist/dev/dev-lock.d.ts +50 -0
- package/dist/dev/dev-lock.d.ts.map +1 -0
- package/dist/dev/dev-lock.js +203 -0
- package/dist/dev/dev-lock.js.map +1 -0
- package/dist/dev/port.d.ts +6 -2
- package/dist/dev/port.d.ts.map +1 -1
- package/dist/dev/port.js +8 -4
- package/dist/dev/port.js.map +1 -1
- package/dist/dev/providers.d.ts.map +1 -1
- package/dist/dev/providers.js +112 -23
- package/dist/dev/providers.js.map +1 -1
- package/dist/dev/runners.d.ts +21 -2
- package/dist/dev/runners.d.ts.map +1 -1
- package/dist/dev/runtime-container.d.ts +78 -3
- package/dist/dev/runtime-container.d.ts.map +1 -1
- package/dist/dev/runtime-container.js +256 -25
- package/dist/dev/runtime-container.js.map +1 -1
- package/dist/dev/runtime-image.d.ts +1 -1
- package/dist/dev/runtime-image.js +1 -1
- package/dist/dev/start-phases.d.ts +41 -0
- package/dist/dev/start-phases.d.ts.map +1 -0
- package/dist/dev/start-phases.js +103 -0
- package/dist/dev/start-phases.js.map +1 -0
- package/dist/help.js +1 -1
- package/dist/help.js.map +1 -1
- package/dist/init/augment-scaffolder.d.ts +20 -7
- package/dist/init/augment-scaffolder.d.ts.map +1 -1
- package/dist/init/augment-scaffolder.js +94 -21
- package/dist/init/augment-scaffolder.js.map +1 -1
- package/dist/init/pinning.d.ts +39 -0
- package/dist/init/pinning.d.ts.map +1 -0
- package/dist/init/pinning.js +130 -0
- package/dist/init/pinning.js.map +1 -0
- package/dist/init/template-files.d.ts +1 -1
- package/dist/init/tsconfig-paths.d.ts +29 -0
- package/dist/init/tsconfig-paths.d.ts.map +1 -0
- package/dist/init/tsconfig-paths.js +235 -0
- package/dist/init/tsconfig-paths.js.map +1 -0
- package/dist/init/vitest-setup.d.ts +41 -0
- package/dist/init/vitest-setup.d.ts.map +1 -0
- package/dist/init/vitest-setup.js +163 -0
- package/dist/init/vitest-setup.js.map +1 -0
- package/dist/license/aws.d.ts +24 -0
- package/dist/license/aws.d.ts.map +1 -0
- package/dist/license/aws.js +291 -0
- package/dist/license/aws.js.map +1 -0
- package/dist/license/cloud.d.ts +13 -0
- package/dist/license/cloud.d.ts.map +1 -0
- package/dist/license/cloud.js +193 -0
- package/dist/license/cloud.js.map +1 -0
- package/dist/license/expiry.d.ts +33 -0
- package/dist/license/expiry.d.ts.map +1 -0
- package/dist/license/expiry.js +35 -0
- package/dist/license/expiry.js.map +1 -0
- package/dist/license/license-key.d.ts +32 -0
- package/dist/license/license-key.d.ts.map +1 -0
- package/dist/license/license-key.js +91 -0
- package/dist/license/license-key.js.map +1 -0
- package/dist/license/protocol.d.ts +63 -0
- package/dist/license/protocol.d.ts.map +1 -0
- package/dist/license/protocol.js +102 -0
- package/dist/license/protocol.js.map +1 -0
- package/dist/license/renew.d.ts +59 -0
- package/dist/license/renew.d.ts.map +1 -0
- package/dist/license/renew.js +153 -0
- package/dist/license/renew.js.map +1 -0
- package/dist/license/stores.d.ts +19 -0
- package/dist/license/stores.d.ts.map +1 -0
- package/dist/license/stores.js +150 -0
- package/dist/license/stores.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +1 -0
- package/dist/main.js.map +1 -1
- package/dist/package-manager.d.ts.map +1 -1
- package/dist/package-manager.js +2 -1
- package/dist/package-manager.js.map +1 -1
- package/dist/providers/preset-loader.d.ts +52 -1
- package/dist/providers/preset-loader.d.ts.map +1 -1
- package/dist/providers/preset-loader.js +85 -6
- package/dist/providers/preset-loader.js.map +1 -1
- package/dist/providers/presets/anthropic.json +1 -1
- package/dist/providers/presets/azure-openai.json +65 -0
- package/dist/providers/presets/bedrock.json +102 -0
- package/dist/sdk-skills/kindgi-authoring-agents/SKILL.md +3 -3
- package/dist/sdk-skills/kindgi-authoring-flows/SKILL.md +3 -3
- package/dist/sdk-skills/kindgi-authoring-guardrails/SKILL.md +11 -10
- package/dist/sdk-skills/kindgi-authoring-mcp-servers/SKILL.md +4 -4
- package/dist/sdk-skills/kindgi-authoring-providers/SKILL.md +16 -9
- package/dist/sdk-skills/kindgi-authoring-tools/SKILL.md +9 -11
- package/dist/sdk-skills/kindgi-framework-feedback/SKILL.md +3 -3
- package/dist/sdk-skills/kindgi-getting-started/SKILL.md +28 -5
- package/dist/sdk-skills/kindgi-java-authoring-agents/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-java-authoring-flows/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-java-authoring-guardrails/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-java-authoring-tools/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-java-getting-started/SKILL.md +6 -1
- package/dist/sdk-skills/kindgi-python-authoring-agents/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-python-authoring-flows/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-python-authoring-guardrails/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-python-authoring-tools/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-python-getting-started/SKILL.md +6 -1
- package/dist/sdk-skills/kindgi-scala-authoring-agents/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-scala-authoring-flows/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-scala-authoring-guardrails/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-scala-authoring-tools/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-scala-getting-started/SKILL.md +6 -1
- package/dist/sdk-skills/kindgi-using/SKILL.md +236 -0
- package/dist/templates/drupal/.nvmrc +1 -0
- package/dist/templates/drupal/AGENTS.md +62 -0
- package/dist/templates/drupal/README.md.tmpl +321 -0
- package/dist/templates/drupal/agents/content-agent/index.test.ts.tmpl +47 -0
- package/dist/templates/drupal/agents/content-agent/index.ts.tmpl +69 -0
- package/dist/templates/drupal/agents/content-reviewer/index.test.ts.tmpl +37 -0
- package/dist/templates/drupal/agents/content-reviewer/index.ts.tmpl +57 -0
- package/dist/templates/drupal/fixtures/node-updated.json +174 -0
- package/dist/templates/drupal/flows/content-review/index.ts.tmpl +66 -0
- package/dist/templates/drupal/gitignore +8 -0
- package/dist/templates/drupal/guardrails/no-contact-details/index.test.ts.tmpl +29 -0
- package/dist/templates/drupal/guardrails/no-contact-details/index.ts.tmpl +73 -0
- package/dist/templates/drupal/kindgi.config.ts.tmpl +41 -0
- package/dist/templates/drupal/lib/drupal.ts.tmpl +64 -0
- package/dist/templates/drupal/package.json.tmpl +31 -0
- package/dist/templates/drupal/pnpm-workspace.yaml +9 -0
- package/dist/templates/drupal/scripts/connect-drupal.mjs.tmpl +57 -0
- package/dist/templates/drupal/tools/check-content-event/index.test.ts.tmpl +72 -0
- package/dist/templates/drupal/tools/check-content-event/index.ts.tmpl +115 -0
- package/dist/templates/drupal/tsconfig.json.tmpl +28 -0
- package/dist/templates/drupal/vitest.config.ts.tmpl +14 -0
- package/dist/templates/java/AGENTS.md +6 -0
- package/dist/templates/java/README.md.tmpl +1 -1
- package/dist/templates/minimal/AGENTS.md +6 -0
- package/dist/templates/minimal/README.md.tmpl +3 -2
- package/dist/templates/minimal/package.json.tmpl +3 -2
- package/dist/templates/python/AGENTS.md +3 -2
- package/dist/templates/sample/AGENTS.md +6 -0
- package/dist/templates/sample/package.json.tmpl +3 -2
- package/dist/templates/scala/AGENTS.md +6 -0
- package/dist/templates/scala/README.md.tmpl +1 -1
- package/dist/templates/woocommerce/.nvmrc +1 -0
- package/dist/templates/woocommerce/AGENTS.md +49 -0
- package/dist/templates/woocommerce/README.md.tmpl +273 -0
- package/dist/templates/woocommerce/agents/order-reviewer/index.test.ts.tmpl +28 -0
- package/dist/templates/woocommerce/agents/order-reviewer/index.ts.tmpl +45 -0
- package/dist/templates/woocommerce/agents/store-agent/index.test.ts.tmpl +47 -0
- package/dist/templates/woocommerce/agents/store-agent/index.ts.tmpl +79 -0
- package/dist/templates/woocommerce/fixtures/order-created.json +67 -0
- package/dist/templates/woocommerce/flows/order-review/index.ts.tmpl +64 -0
- package/dist/templates/woocommerce/gitignore +8 -0
- package/dist/templates/woocommerce/guardrails/no-customer-contact-details/index.test.ts.tmpl +29 -0
- package/dist/templates/woocommerce/guardrails/no-customer-contact-details/index.ts.tmpl +74 -0
- package/dist/templates/woocommerce/kindgi.config.ts.tmpl +41 -0
- package/dist/templates/woocommerce/lib/fake-store.ts.tmpl +82 -0
- package/dist/templates/woocommerce/lib/woo.ts.tmpl +182 -0
- package/dist/templates/woocommerce/package.json.tmpl +30 -0
- package/dist/templates/woocommerce/pnpm-workspace.yaml +9 -0
- package/dist/templates/woocommerce/tools/check-order-event/index.test.ts.tmpl +76 -0
- package/dist/templates/woocommerce/tools/check-order-event/index.ts.tmpl +131 -0
- package/dist/templates/woocommerce/tools/find-orders/index.ts.tmpl +80 -0
- package/dist/templates/woocommerce/tools/publish-product/index.ts.tmpl +34 -0
- package/dist/templates/woocommerce/tools/refund/index.test.ts.tmpl +125 -0
- package/dist/templates/woocommerce/tools/refund/index.ts.tmpl +70 -0
- package/dist/templates/woocommerce/tools/refund-large/index.test.ts.tmpl +53 -0
- package/dist/templates/woocommerce/tools/refund-large/index.ts.tmpl +44 -0
- package/dist/templates/woocommerce/tools/set-price/index.ts.tmpl +36 -0
- package/dist/templates/woocommerce/tsconfig.json.tmpl +28 -0
- package/dist/templates/woocommerce/vitest.config.ts.tmpl +14 -0
- package/dist/test/defaults.d.ts +1 -1
- package/dist/test/defaults.d.ts.map +1 -1
- package/dist/test/defaults.js +2 -7
- package/dist/test/defaults.js.map +1 -1
- package/dist/test/runners.d.ts +6 -0
- package/dist/test/runners.d.ts.map +1 -1
- package/dist/test/runners.js +18 -1
- package/dist/test/runners.js.map +1 -1
- package/package.json +14 -14
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// {{PACK_ID}}.woo.find-orders — look up orders. Read-only (`mutating:
|
|
2
|
+
// false`), so the agent's approval policy lets it run without a person.
|
|
3
|
+
import { defineTool } from '@kindgi/sdk/define';
|
|
4
|
+
import type { ToolId } from '@kindgi/sdk/types';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
|
|
7
|
+
import { WOO_NEEDS, type WooOrder, refundedSoFar, woo } from '../../lib/woo.js';
|
|
8
|
+
|
|
9
|
+
const STATUSES = [
|
|
10
|
+
'pending',
|
|
11
|
+
'processing',
|
|
12
|
+
'on-hold',
|
|
13
|
+
'completed',
|
|
14
|
+
'cancelled',
|
|
15
|
+
'refunded',
|
|
16
|
+
'failed',
|
|
17
|
+
] as const;
|
|
18
|
+
|
|
19
|
+
const FindOrdersInput = z.object({
|
|
20
|
+
search: z
|
|
21
|
+
.string()
|
|
22
|
+
.min(1)
|
|
23
|
+
.max(100)
|
|
24
|
+
.optional()
|
|
25
|
+
.describe('An order number, or a customer name or email address.'),
|
|
26
|
+
status: z.enum(STATUSES).optional(),
|
|
27
|
+
limit: z.number().int().min(1).max(20).default(10),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const Order = z.object({
|
|
31
|
+
id: z.number().int(),
|
|
32
|
+
number: z.string(),
|
|
33
|
+
status: z.string(),
|
|
34
|
+
total: z.string(),
|
|
35
|
+
/** What the order has been refunded already. */
|
|
36
|
+
refunded: z.string(),
|
|
37
|
+
currency: z.string(),
|
|
38
|
+
createdAt: z.string(),
|
|
39
|
+
/** The customer's name, never their email or address. */
|
|
40
|
+
customer: z.string(),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const defined = defineTool({
|
|
44
|
+
id: '{{PACK_ID}}.woo.find-orders' as ToolId,
|
|
45
|
+
description:
|
|
46
|
+
"Look up the store's orders by order number, customer name or email, or status. Read-only: it changes nothing.",
|
|
47
|
+
version: '{{PACK_VERSION}}',
|
|
48
|
+
input: FindOrdersInput,
|
|
49
|
+
output: z.object({ orders: z.array(Order) }),
|
|
50
|
+
effects: [
|
|
51
|
+
{ kind: 'reads', resource: 'external:woocommerce' },
|
|
52
|
+
{ kind: 'network', resource: 'external:woocommerce' },
|
|
53
|
+
],
|
|
54
|
+
mutating: false,
|
|
55
|
+
needsSpec: WOO_NEEDS,
|
|
56
|
+
handler: async ({ search, status, limit }, ctx) => {
|
|
57
|
+
const query = new URLSearchParams({ per_page: String(limit) });
|
|
58
|
+
if (search !== undefined) query.set('search', search);
|
|
59
|
+
if (status !== undefined) query.set('status', status);
|
|
60
|
+
const orders = await woo<WooOrder[]>(ctx, 'GET', `orders?${query.toString()}`);
|
|
61
|
+
return {
|
|
62
|
+
orders: orders.map((o) => ({
|
|
63
|
+
id: o.id,
|
|
64
|
+
number: o.number,
|
|
65
|
+
status: o.status,
|
|
66
|
+
total: o.total,
|
|
67
|
+
refunded: refundedSoFar(o).toFixed(2),
|
|
68
|
+
currency: o.currency,
|
|
69
|
+
createdAt: o.date_created,
|
|
70
|
+
customer: [o.billing?.first_name, o.billing?.last_name].filter(Boolean).join(' '),
|
|
71
|
+
})),
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
if (defined.kind === 'err') {
|
|
77
|
+
throw new Error(`{{PACK_ID}}.woo.find-orders failed to compile: ${defined.error.message}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export default defined.value;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// {{PACK_ID}}.woo.publish-product — publish a draft product, so shoppers can
|
|
2
|
+
// see it. A store change, so the agent's approval policy has a person
|
|
3
|
+
// approve every call.
|
|
4
|
+
import { defineTool } from '@kindgi/sdk/define';
|
|
5
|
+
import type { ToolId } from '@kindgi/sdk/types';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
|
|
8
|
+
import { WOO_NEEDS, woo } from '../../lib/woo.js';
|
|
9
|
+
|
|
10
|
+
const defined = defineTool({
|
|
11
|
+
id: '{{PACK_ID}}.woo.publish-product' as ToolId,
|
|
12
|
+
description: 'Publish a draft product in the store. Waits for a person to approve it.',
|
|
13
|
+
version: '{{PACK_VERSION}}',
|
|
14
|
+
input: z.object({ productId: z.number().int().positive() }),
|
|
15
|
+
output: z.object({ productId: z.number().int(), name: z.string(), status: z.string() }),
|
|
16
|
+
effects: [{ kind: 'writes', resource: 'external:woocommerce' }],
|
|
17
|
+
mutating: true,
|
|
18
|
+
needsSpec: WOO_NEEDS,
|
|
19
|
+
handler: async ({ productId }, ctx) => {
|
|
20
|
+
const product = await woo<{ readonly id: number; readonly name: string; readonly status: string }>(
|
|
21
|
+
ctx,
|
|
22
|
+
'PUT',
|
|
23
|
+
`products/${productId}`,
|
|
24
|
+
{ status: 'publish' },
|
|
25
|
+
);
|
|
26
|
+
return { productId: product.id, name: product.name, status: product.status };
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
if (defined.kind === 'err') {
|
|
31
|
+
throw new Error(`{{PACK_ID}}.woo.publish-product failed to compile: ${defined.error.message}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default defined.value;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// {{PACK_ID}}.woo.refund — the limit of 100, and each refund once, called as a
|
|
2
|
+
// run calls it (`invokeToolForTest`: the input schema first, then the env
|
|
3
|
+
// values Kindgi would give it, defaults included, then the handler). The
|
|
4
|
+
// store is `lib/fake-store.ts`; no WooCommerce needed.
|
|
5
|
+
|
|
6
|
+
import { randomUUID } from 'node:crypto';
|
|
7
|
+
|
|
8
|
+
import { afterEach, describe, expect, test, vi } from 'vitest';
|
|
9
|
+
|
|
10
|
+
import { invokeToolForTest } from '@kindgi/sdk/define';
|
|
11
|
+
|
|
12
|
+
import { fakeStore } from '../../lib/fake-store.js';
|
|
13
|
+
import { IDEMPOTENCY_META_KEY } from '../../lib/woo.js';
|
|
14
|
+
import refund from './index.js';
|
|
15
|
+
|
|
16
|
+
/** What `kindgi env set` and `kindgi secrets set` would give the tool. */
|
|
17
|
+
const settings = {
|
|
18
|
+
env: { WOO_STORE_URL: 'http://store.test', WOO_USER: 'shop-agent' },
|
|
19
|
+
secrets: { WOO_APP_PASSWORD: 'not-a-real-password' },
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
vi.unstubAllGlobals();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe('{{PACK_ID}}.woo.refund', () => {
|
|
27
|
+
test('refunds 40 on an order with no refunds yet', async () => {
|
|
28
|
+
const store = fakeStore();
|
|
29
|
+
const result = await invokeToolForTest(refund, { orderId: 1043, amount: 40, reason: 'Arrived torn' }, settings);
|
|
30
|
+
expect(result).toEqual({
|
|
31
|
+
kind: 'ok',
|
|
32
|
+
value: { refundId: 501, orderId: 1043, amount: '40.00', currency: 'USD' },
|
|
33
|
+
});
|
|
34
|
+
const post = store.calls.find((c) => c.method === 'POST');
|
|
35
|
+
expect(post?.path).toBe('/wp-json/wc/v3/orders/1043/refunds');
|
|
36
|
+
// WOO_REFUND_THROUGH_GATEWAY isn't set: its default, false, applies. Outside a run
|
|
37
|
+
// there's no idempotency key, so nothing goes on the refund.
|
|
38
|
+
expect(post?.body).toEqual({ amount: '40.00', reason: 'Arrived torn', api_refund: false });
|
|
39
|
+
expect(post?.authorization).toBe(`Basic ${Buffer.from('shop-agent:not-a-real-password').toString('base64')}`);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('refunds through the payment gateway when WOO_REFUND_THROUGH_GATEWAY is true', async () => {
|
|
43
|
+
const store = fakeStore();
|
|
44
|
+
const result = await invokeToolForTest(
|
|
45
|
+
refund,
|
|
46
|
+
{ orderId: 1043, amount: 40, reason: 'Arrived torn' },
|
|
47
|
+
{ ...settings, env: { ...settings.env, WOO_REFUND_THROUGH_GATEWAY: 'true' } },
|
|
48
|
+
);
|
|
49
|
+
expect(result.kind).toBe('ok');
|
|
50
|
+
expect(store.calls.find((c) => c.method === 'POST')?.body).toEqual({
|
|
51
|
+
amount: '40.00',
|
|
52
|
+
reason: 'Arrived torn',
|
|
53
|
+
api_refund: true,
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("doesn't run without the store's address, and never calls the store", async () => {
|
|
58
|
+
const store = fakeStore();
|
|
59
|
+
const result = await invokeToolForTest(
|
|
60
|
+
refund,
|
|
61
|
+
{ orderId: 1043, amount: 40, reason: 'Arrived torn' },
|
|
62
|
+
{ ...settings, env: { WOO_USER: 'shop-agent' } },
|
|
63
|
+
);
|
|
64
|
+
expect(result).toMatchObject({ kind: 'err', error: { code: 'precondition-failed', reason: 'env-value-missing' } });
|
|
65
|
+
expect(store.calls).toEqual([]);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('refuses 240 at the input schema, before the store is called', async () => {
|
|
69
|
+
const store = fakeStore();
|
|
70
|
+
const result = await invokeToolForTest(refund, { orderId: 1043, amount: 240, reason: 'Arrived torn' }, settings);
|
|
71
|
+
expect(result.kind).toBe('err');
|
|
72
|
+
if (result.kind === 'err') expect(result.error.code).toBe('input-validation-failed');
|
|
73
|
+
expect(store.calls).toEqual([]);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test('refuses a refund that takes the order past 100 in total', async () => {
|
|
77
|
+
const store = fakeStore([80]);
|
|
78
|
+
const result = await invokeToolForTest(refund, { orderId: 1043, amount: 80, reason: 'Arrived torn' }, settings);
|
|
79
|
+
expect(result.kind).toBe('err');
|
|
80
|
+
if (result.kind === 'err') {
|
|
81
|
+
expect(result.error.code).toBe('handler-error');
|
|
82
|
+
expect(result.error.message).toContain('{{PACK_ID}}.woo.refund-large');
|
|
83
|
+
}
|
|
84
|
+
expect(store.calls.some((c) => c.method === 'POST')).toBe(false);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('refunds up to exactly 100 in total', async () => {
|
|
88
|
+
fakeStore([60]);
|
|
89
|
+
const result = await invokeToolForTest(refund, { orderId: 1043, amount: 40, reason: 'Arrived torn' }, settings);
|
|
90
|
+
expect(result.kind).toBe('ok');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test('the same call run twice refunds once: the second finds the refund the first made', async () => {
|
|
94
|
+
const store = fakeStore();
|
|
95
|
+
const call = { ...settings, idempotencyKey: randomUUID() };
|
|
96
|
+
const first = await invokeToolForTest(refund, { orderId: 1043, amount: 40, reason: 'Arrived torn' }, call);
|
|
97
|
+
const again = await invokeToolForTest(refund, { orderId: 1043, amount: 40, reason: 'Arrived torn' }, call);
|
|
98
|
+
expect(first).toEqual({ kind: 'ok', value: { refundId: 501, orderId: 1043, amount: '40.00', currency: 'USD' } });
|
|
99
|
+
expect(again).toEqual(first);
|
|
100
|
+
expect(store.refunds).toHaveLength(1);
|
|
101
|
+
expect(store.refunds[0]?.meta_data).toEqual([{ key: IDEMPOTENCY_META_KEY, value: call.idempotencyKey }]);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('a refund the store made but answered 502 for is returned as made, not refunded again', async () => {
|
|
105
|
+
const store = fakeStore();
|
|
106
|
+
store.failNextRefundAfterSaving(502);
|
|
107
|
+
const result = await invokeToolForTest(
|
|
108
|
+
refund,
|
|
109
|
+
{ orderId: 1043, amount: 40, reason: 'Arrived torn' },
|
|
110
|
+
{ ...settings, idempotencyKey: randomUUID() },
|
|
111
|
+
);
|
|
112
|
+
expect(result).toEqual({ kind: 'ok', value: { refundId: 501, orderId: 1043, amount: '40.00', currency: 'USD' } });
|
|
113
|
+
expect(store.refunds).toHaveLength(1);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test('a call run again after its refund reached the limit returns that refund, not a refusal', async () => {
|
|
117
|
+
const store = fakeStore([60]);
|
|
118
|
+
const call = { ...settings, idempotencyKey: randomUUID() };
|
|
119
|
+
const first = await invokeToolForTest(refund, { orderId: 1043, amount: 40, reason: 'Arrived torn' }, call);
|
|
120
|
+
const again = await invokeToolForTest(refund, { orderId: 1043, amount: 40, reason: 'Arrived torn' }, call);
|
|
121
|
+
expect(first.kind).toBe('ok');
|
|
122
|
+
expect(again).toEqual(first);
|
|
123
|
+
expect(store.refunds).toHaveLength(2);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// {{PACK_ID}}.woo.refund — a refund of up to 100 (in the order's currency) on
|
|
2
|
+
// an order, with no one to approve it.
|
|
3
|
+
//
|
|
4
|
+
// Kindgi's approval rules key on the tool, not on its arguments, so "refunds
|
|
5
|
+
// over 100 need a person" is two tools: this one, which the agent's policy
|
|
6
|
+
// lets run on its own, and `{{PACK_ID}}.woo.refund-large`, which always waits
|
|
7
|
+
// for a person. The limit is enforced here, not by the model:
|
|
8
|
+
// - the input schema caps one refund at `maximum: 100`, and Kindgi checks
|
|
9
|
+
// every call against it before the handler runs;
|
|
10
|
+
// - the handler refuses a refund that would take what the order has been
|
|
11
|
+
// refunded past 100, so splitting a large refund into small ones
|
|
12
|
+
// doesn't get around the approval.
|
|
13
|
+
// Change `REFUND_LIMIT` to change the limit (the schema follows).
|
|
14
|
+
import { defineTool } from '@kindgi/sdk/define';
|
|
15
|
+
import type { ToolId } from '@kindgi/sdk/types';
|
|
16
|
+
import { z } from 'zod';
|
|
17
|
+
|
|
18
|
+
import { REFUND_NEEDS, type WooOrder, createRefund, refundedSoFar } from '../../lib/woo.js';
|
|
19
|
+
|
|
20
|
+
/** The most this tool refunds on one order, in the order's currency. */
|
|
21
|
+
export const REFUND_LIMIT = 100;
|
|
22
|
+
|
|
23
|
+
export const RefundInput = z.object({
|
|
24
|
+
orderId: z.number().int().positive(),
|
|
25
|
+
amount: z
|
|
26
|
+
.number()
|
|
27
|
+
.positive()
|
|
28
|
+
.max(REFUND_LIMIT)
|
|
29
|
+
.describe(`At most ${REFUND_LIMIT}; a larger refund goes through the refund-large tool.`),
|
|
30
|
+
reason: z.string().min(3).max(500),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export const RefundOutput = z.object({
|
|
34
|
+
refundId: z.number().int(),
|
|
35
|
+
orderId: z.number().int(),
|
|
36
|
+
amount: z.string(),
|
|
37
|
+
currency: z.string(),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const defined = defineTool({
|
|
41
|
+
id: '{{PACK_ID}}.woo.refund' as ToolId,
|
|
42
|
+
description: `Refund up to ${REFUND_LIMIT} on an order, counting what it has been refunded already. Runs without approval. For more, use {{PACK_ID}}.woo.refund-large, which waits for a person.`,
|
|
43
|
+
version: '{{PACK_VERSION}}',
|
|
44
|
+
input: RefundInput,
|
|
45
|
+
output: RefundOutput,
|
|
46
|
+
effects: [
|
|
47
|
+
{ kind: 'writes', resource: 'external:woocommerce' },
|
|
48
|
+
{ kind: 'external-side-effect', notes: 'Refunds money to the customer.' },
|
|
49
|
+
],
|
|
50
|
+
mutating: true,
|
|
51
|
+
needsSpec: REFUND_NEEDS,
|
|
52
|
+
// The limit is checked after `createRefund` has looked for this call's own
|
|
53
|
+
// refund: a call run again after its refund went out returns that refund,
|
|
54
|
+
// instead of counting it against itself.
|
|
55
|
+
handler: async (input, ctx) =>
|
|
56
|
+
createRefund(ctx, input, (order: WooOrder) => {
|
|
57
|
+
const already = refundedSoFar(order);
|
|
58
|
+
if (already + input.amount > REFUND_LIMIT) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
`Order ${order.number} has been refunded ${already.toFixed(2)} already; with ${input.amount.toFixed(2)} more it passes ${REFUND_LIMIT}. Use {{PACK_ID}}.woo.refund-large, which waits for a person.`,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
}),
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
if (defined.kind === 'err') {
|
|
67
|
+
throw new Error(`{{PACK_ID}}.woo.refund failed to compile: ${defined.error.message}`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export default defined.value;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// {{PACK_ID}}.woo.refund-large — any amount, once. In a run it waits for a
|
|
2
|
+
// person first; here it's called as the run calls it after the approval
|
|
3
|
+
// (`invokeToolForTest`). The store is `lib/fake-store.ts`.
|
|
4
|
+
|
|
5
|
+
import { randomUUID } from 'node:crypto';
|
|
6
|
+
|
|
7
|
+
import { afterEach, describe, expect, test, vi } from 'vitest';
|
|
8
|
+
|
|
9
|
+
import { invokeToolForTest } from '@kindgi/sdk/define';
|
|
10
|
+
|
|
11
|
+
import { fakeStore } from '../../lib/fake-store.js';
|
|
12
|
+
import refundLarge from './index.js';
|
|
13
|
+
|
|
14
|
+
/** What `kindgi env set` and `kindgi secrets set` would give the tool. */
|
|
15
|
+
const settings = {
|
|
16
|
+
env: { WOO_STORE_URL: 'http://store.test', WOO_USER: 'shop-agent' },
|
|
17
|
+
secrets: { WOO_APP_PASSWORD: 'not-a-real-password' },
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
vi.unstubAllGlobals();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe('{{PACK_ID}}.woo.refund-large', () => {
|
|
25
|
+
test('refunds 240, past the limit of the refund tool', async () => {
|
|
26
|
+
const store = fakeStore();
|
|
27
|
+
const result = await invokeToolForTest(refundLarge, { orderId: 1043, amount: 240, reason: 'Zip broke on day one' }, settings);
|
|
28
|
+
expect(result).toEqual({ kind: 'ok', value: { refundId: 501, orderId: 1043, amount: '240.00', currency: 'USD' } });
|
|
29
|
+
expect(store.refunds).toHaveLength(1);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('the step resumed after its approval, or run again after a crash, refunds once', async () => {
|
|
33
|
+
const store = fakeStore();
|
|
34
|
+
const call = { ...settings, idempotencyKey: randomUUID() };
|
|
35
|
+
const first = await invokeToolForTest(refundLarge, { orderId: 1043, amount: 240, reason: 'Zip broke on day one' }, call);
|
|
36
|
+
const again = await invokeToolForTest(refundLarge, { orderId: 1043, amount: 240, reason: 'Zip broke on day one' }, call);
|
|
37
|
+
expect(first.kind).toBe('ok');
|
|
38
|
+
expect(again).toEqual(first);
|
|
39
|
+
expect(store.refunds).toHaveLength(1);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('a refund the store made but answered 502 for is returned as made', async () => {
|
|
43
|
+
const store = fakeStore();
|
|
44
|
+
store.failNextRefundAfterSaving(502);
|
|
45
|
+
const result = await invokeToolForTest(
|
|
46
|
+
refundLarge,
|
|
47
|
+
{ orderId: 1043, amount: 240, reason: 'Zip broke on day one' },
|
|
48
|
+
{ ...settings, idempotencyKey: randomUUID() },
|
|
49
|
+
);
|
|
50
|
+
expect(result).toEqual({ kind: 'ok', value: { refundId: 501, orderId: 1043, amount: '240.00', currency: 'USD' } });
|
|
51
|
+
expect(store.refunds).toHaveLength(1);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// {{PACK_ID}}.woo.refund-large — a refund of any amount on an order. The
|
|
2
|
+
// agent's approval policy marks it `always_ask`: every call waits for a
|
|
3
|
+
// person to approve it, and the refund happens only after they do, once:
|
|
4
|
+
// the step resumed after the approval, or run again after a crash, finds the
|
|
5
|
+
// refund it made (`createRefund` in `lib/woo.ts`). See
|
|
6
|
+
// `{{PACK_ID}}.woo.refund` for why the store has two refund tools.
|
|
7
|
+
import { defineTool } from '@kindgi/sdk/define';
|
|
8
|
+
import type { ToolId } from '@kindgi/sdk/types';
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
|
|
11
|
+
import { REFUND_NEEDS, createRefund } from '../../lib/woo.js';
|
|
12
|
+
|
|
13
|
+
const RefundLargeInput = z.object({
|
|
14
|
+
orderId: z.number().int().positive(),
|
|
15
|
+
amount: z.number().positive(),
|
|
16
|
+
reason: z.string().min(3).max(500),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const defined = defineTool({
|
|
20
|
+
id: '{{PACK_ID}}.woo.refund-large' as ToolId,
|
|
21
|
+
description:
|
|
22
|
+
'Refund any amount on an order. Waits for a person to approve it before anything is refunded.',
|
|
23
|
+
version: '{{PACK_VERSION}}',
|
|
24
|
+
input: RefundLargeInput,
|
|
25
|
+
output: z.object({
|
|
26
|
+
refundId: z.number().int(),
|
|
27
|
+
orderId: z.number().int(),
|
|
28
|
+
amount: z.string(),
|
|
29
|
+
currency: z.string(),
|
|
30
|
+
}),
|
|
31
|
+
effects: [
|
|
32
|
+
{ kind: 'writes', resource: 'external:woocommerce' },
|
|
33
|
+
{ kind: 'external-side-effect', notes: 'Refunds money to the customer.' },
|
|
34
|
+
],
|
|
35
|
+
mutating: true,
|
|
36
|
+
needsSpec: REFUND_NEEDS,
|
|
37
|
+
handler: async (input, ctx) => createRefund(ctx, input),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
if (defined.kind === 'err') {
|
|
41
|
+
throw new Error(`{{PACK_ID}}.woo.refund-large failed to compile: ${defined.error.message}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default defined.value;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// {{PACK_ID}}.woo.set-price — change a product's regular price. A store
|
|
2
|
+
// change, so the agent's approval policy has a person approve every call.
|
|
3
|
+
import { defineTool } from '@kindgi/sdk/define';
|
|
4
|
+
import type { ToolId } from '@kindgi/sdk/types';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
|
|
7
|
+
import { WOO_NEEDS, woo } from '../../lib/woo.js';
|
|
8
|
+
|
|
9
|
+
const defined = defineTool({
|
|
10
|
+
id: '{{PACK_ID}}.woo.set-price' as ToolId,
|
|
11
|
+
description: "Change a product's regular price. Waits for a person to approve it.",
|
|
12
|
+
version: '{{PACK_VERSION}}',
|
|
13
|
+
input: z.object({
|
|
14
|
+
productId: z.number().int().positive(),
|
|
15
|
+
regularPrice: z.number().positive(),
|
|
16
|
+
}),
|
|
17
|
+
output: z.object({ productId: z.number().int(), name: z.string(), regularPrice: z.string() }),
|
|
18
|
+
effects: [{ kind: 'writes', resource: 'external:woocommerce' }],
|
|
19
|
+
mutating: true,
|
|
20
|
+
needsSpec: WOO_NEEDS,
|
|
21
|
+
handler: async ({ productId, regularPrice }, ctx) => {
|
|
22
|
+
const product = await woo<{ readonly id: number; readonly name: string; readonly regular_price: string }>(
|
|
23
|
+
ctx,
|
|
24
|
+
'PUT',
|
|
25
|
+
`products/${productId}`,
|
|
26
|
+
{ regular_price: regularPrice.toFixed(2) },
|
|
27
|
+
);
|
|
28
|
+
return { productId: product.id, name: product.name, regularPrice: product.regular_price };
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
if (defined.kind === 'err') {
|
|
33
|
+
throw new Error(`{{PACK_ID}}.woo.set-price failed to compile: ${defined.error.message}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default defined.value;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2023",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"lib": ["ES2023", "DOM"],
|
|
7
|
+
"types": ["node"],
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"verbatimModuleSyntax": true,
|
|
12
|
+
"isolatedModules": true,
|
|
13
|
+
"declaration": true,
|
|
14
|
+
"sourceMap": true,
|
|
15
|
+
"noEmit": true,
|
|
16
|
+
"resolveJsonModule": true,
|
|
17
|
+
"forceConsistentCasingInFileNames": true
|
|
18
|
+
},
|
|
19
|
+
"include": [
|
|
20
|
+
"lib/**/*.ts",
|
|
21
|
+
"tools/**/*.ts",
|
|
22
|
+
"guardrails/**/*.ts",
|
|
23
|
+
"agents/**/*.ts",
|
|
24
|
+
"flows/**/*.ts",
|
|
25
|
+
"kindgi.config.ts"
|
|
26
|
+
],
|
|
27
|
+
"exclude": ["node_modules", "dist", ".kindgi"]
|
|
28
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Vitest configuration for {{PACK_NAME}}. Scaffolded by `kindgi init`.
|
|
2
|
+
// `kindgi test` shells out to the pack's local vitest install using
|
|
3
|
+
// this config — the CLI does NOT force a vitest version through.
|
|
4
|
+
|
|
5
|
+
import { defineConfig } from 'vitest/config';
|
|
6
|
+
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
test: {
|
|
9
|
+
include: ['**/*.test.ts'],
|
|
10
|
+
exclude: ['node_modules/**', '.kindgi/**', 'dist/**'],
|
|
11
|
+
reporters: ['default'],
|
|
12
|
+
passWithNoTests: true,
|
|
13
|
+
},
|
|
14
|
+
});
|
package/dist/test/defaults.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/test/defaults.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/test/defaults.ts"],"names":[],"mappings":"AAeA,OAAO,EAGL,KAAK,WAAW,EAEjB,MAAM,cAAc,CAAC;AAEtB,eAAO,MAAM,iBAAiB,EAAE,WAc/B,CAAC"}
|
package/dist/test/defaults.js
CHANGED
|
@@ -10,15 +10,10 @@
|
|
|
10
10
|
import { spawn } from 'node:child_process';
|
|
11
11
|
import { stat } from 'node:fs/promises';
|
|
12
12
|
import { join } from 'node:path';
|
|
13
|
-
|
|
14
|
-
'vitest.config.ts',
|
|
15
|
-
'vitest.config.mjs',
|
|
16
|
-
'vitest.config.js',
|
|
17
|
-
'vitest.config.cjs',
|
|
18
|
-
];
|
|
13
|
+
import { VITEST_CONFIG_FILENAMES, } from './runners.js';
|
|
19
14
|
export const REAL_TEST_RUNNERS = {
|
|
20
15
|
hasVitestConfig: async ({ packDir }) => {
|
|
21
|
-
for (const name of
|
|
16
|
+
for (const name of VITEST_CONFIG_FILENAMES) {
|
|
22
17
|
const abs = join(packDir, name);
|
|
23
18
|
try {
|
|
24
19
|
const s = await stat(abs);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/test/defaults.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC;;;;;;GAMG;AAEH,OAAO,EAAqB,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/test/defaults.ts"],"names":[],"mappings":"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"}
|
package/dist/test/runners.d.ts
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
* flows through this shape so tests inspect the invocation without
|
|
4
4
|
* spawning real vitest.
|
|
5
5
|
*/
|
|
6
|
+
/**
|
|
7
|
+
* vitest's own config file names, in the order it looks for them
|
|
8
|
+
* (`vite.config.*` aside: one often has no `test` block, and vitest then
|
|
9
|
+
* sweeps every test file under the folder).
|
|
10
|
+
*/
|
|
11
|
+
export declare const VITEST_CONFIG_FILENAMES: readonly ["vitest.config.ts", "vitest.config.mts", "vitest.config.cts", "vitest.config.js", "vitest.config.mjs", "vitest.config.cjs"];
|
|
6
12
|
export interface RunTestsOptions {
|
|
7
13
|
/** Absolute pack directory the runner spawns in. */
|
|
8
14
|
readonly packDir: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runners.d.ts","sourceRoot":"","sources":["../../src/test/runners.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH,MAAM,WAAW,eAAe;IAC9B,oDAAoD;IACpD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,8CAA8C;IAC9C,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAC3D;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,MAAM,CAAC,EAAE,yBAAyB,GAAG,oBAAoB,CAAC;IACnE,mEAAmE;IACnE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,sBAAsB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7E;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CACvE"}
|
|
1
|
+
{"version":3,"file":"runners.d.ts","sourceRoot":"","sources":["../../src/test/runners.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,uIAO1B,CAAC;AAEX,MAAM,WAAW,eAAe;IAC9B,oDAAoD;IACpD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,8CAA8C;IAC9C,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAC3D;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,MAAM,CAAC,EAAE,yBAAyB,GAAG,oBAAoB,CAAC;IACnE,mEAAmE;IACnE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,sBAAsB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7E;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CACvE"}
|
package/dist/test/runners.js
CHANGED
|
@@ -1,4 +1,21 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Injectable seams for `kindgi test`. The test-runner shellout
|
|
5
|
+
* flows through this shape so tests inspect the invocation without
|
|
6
|
+
* spawning real vitest.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* vitest's own config file names, in the order it looks for them
|
|
10
|
+
* (`vite.config.*` aside: one often has no `test` block, and vitest then
|
|
11
|
+
* sweeps every test file under the folder).
|
|
12
|
+
*/
|
|
13
|
+
export const VITEST_CONFIG_FILENAMES = [
|
|
14
|
+
'vitest.config.ts',
|
|
15
|
+
'vitest.config.mts',
|
|
16
|
+
'vitest.config.cts',
|
|
17
|
+
'vitest.config.js',
|
|
18
|
+
'vitest.config.mjs',
|
|
19
|
+
'vitest.config.cjs',
|
|
20
|
+
];
|
|
4
21
|
//# sourceMappingURL=runners.js.map
|
package/dist/test/runners.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runners.js","sourceRoot":"","sources":["../../src/test/runners.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC"}
|
|
1
|
+
{"version":3,"file":"runners.js","sourceRoot":"","sources":["../../src/test/runners.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,kBAAkB;IAClB,mBAAmB;IACnB,mBAAmB;IACnB,kBAAkB;IAClB,mBAAmB;IACnB,mBAAmB;CACX,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kindgi/cli",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Command-line interface for Kindgi
|
|
3
|
+
"version": "0.1.7-rc.0",
|
|
4
|
+
"description": "Command-line interface for Kindgi™. Create a pack, run it on your machine (`kindgi dev`), build, sign and deploy it, and work with a running Kindgi API from the terminal.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -37,18 +37,18 @@
|
|
|
37
37
|
"provenance": true
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@kindgi/agents": "0.1.
|
|
41
|
-
"@kindgi/client": "0.1.
|
|
42
|
-
"@kindgi/dotenv-file": "0.1.
|
|
43
|
-
"@kindgi/crypto": "0.1.
|
|
44
|
-
"@kindgi/env-schema": "0.1.
|
|
45
|
-
"@kindgi/flow": "0.1.
|
|
46
|
-
"@kindgi/handler-runtime": "0.1.
|
|
47
|
-
"@kindgi/log": "0.1.
|
|
48
|
-
"@kindgi/secrets-dotenv": "0.1.
|
|
49
|
-
"@kindgi/platform": "0.1.
|
|
50
|
-
"@kindgi/sdk": "0.1.
|
|
51
|
-
"@kindgi/types": "0.1.
|
|
40
|
+
"@kindgi/agents": "0.1.7-rc.0",
|
|
41
|
+
"@kindgi/client": "0.1.7-rc.0",
|
|
42
|
+
"@kindgi/dotenv-file": "0.1.7-rc.0",
|
|
43
|
+
"@kindgi/crypto": "0.1.7-rc.0",
|
|
44
|
+
"@kindgi/env-schema": "0.1.7-rc.0",
|
|
45
|
+
"@kindgi/flow": "0.1.7-rc.0",
|
|
46
|
+
"@kindgi/handler-runtime": "0.1.7-rc.0",
|
|
47
|
+
"@kindgi/log": "0.1.7-rc.0",
|
|
48
|
+
"@kindgi/secrets-dotenv": "0.1.7-rc.0",
|
|
49
|
+
"@kindgi/platform": "0.1.7-rc.0",
|
|
50
|
+
"@kindgi/sdk": "0.1.7-rc.0",
|
|
51
|
+
"@kindgi/types": "0.1.7-rc.0",
|
|
52
52
|
"esbuild": "^0.24.0",
|
|
53
53
|
"semver": "^7.8.5",
|
|
54
54
|
"smol-toml": "^1.9.0",
|