gsd-pi 2.72.0-dev.3118184 → 2.72.0-dev.4f3264a
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/dist/resources/extensions/async-jobs/await-tool.js +4 -7
- package/dist/resources/extensions/async-jobs/job-manager.js +3 -28
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +26 -27
- package/dist/resources/extensions/gsd/auto/loop.js +1 -84
- package/dist/resources/extensions/gsd/auto-post-unit.js +0 -6
- package/dist/resources/extensions/gsd/auto.js +19 -25
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +11 -9
- package/dist/resources/extensions/gsd/commands-handlers.js +1 -4
- package/dist/resources/extensions/gsd/context-injector.js +1 -1
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +7 -3
- package/dist/resources/extensions/gsd/gsd-db.js +5 -47
- package/dist/resources/extensions/gsd/key-manager.js +0 -2
- package/dist/resources/extensions/gsd/preferences-skills.js +34 -2
- package/dist/resources/extensions/gsd/preferences-types.js +0 -15
- package/dist/resources/extensions/gsd/preferences.js +3 -16
- package/dist/resources/extensions/gsd/prompt-loader.js +1 -4
- package/dist/resources/extensions/gsd/state.js +1 -21
- package/dist/resources/extensions/gsd/write-intercept.js +1 -10
- package/dist/resources/extensions/ollama/index.js +5 -4
- package/dist/resources/extensions/ollama/ollama-client.js +6 -35
- package/dist/resources/extensions/ollama/ollama-discovery.js +6 -32
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +3 -3
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
- package/dist/web/standalone/.next/server/chunks/2331.js +16 -16
- package/dist/web/standalone/.next/server/chunks/4741.js +12 -12
- package/dist/web/standalone/.next/server/chunks/5822.js +2 -2
- package/dist/web/standalone/.next/server/chunks/63.js +8 -8
- package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
- package/dist/web/standalone/.next/server/functions-config-manifest.json +9 -0
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +2 -29
- package/dist/web/standalone/.next/server/middleware.js +12 -4
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
- package/package.json +1 -1
- package/packages/pi-ai/dist/env-api-keys.js +0 -1
- package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
- package/packages/pi-ai/dist/models.custom.d.ts +0 -105
- package/packages/pi-ai/dist/models.custom.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.custom.js +0 -97
- package/packages/pi-ai/dist/models.custom.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +140 -648
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +364 -861
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.test.js +0 -105
- package/packages/pi-ai/dist/models.test.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +1 -1
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/src/env-api-keys.ts +0 -1
- package/packages/pi-ai/src/models.custom.ts +0 -98
- package/packages/pi-ai/src/models.generated.ts +364 -861
- package/packages/pi-ai/src/models.test.ts +0 -135
- package/packages/pi-ai/src/types.ts +0 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +0 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/src/core/model-resolver.ts +0 -1
- package/src/resources/extensions/async-jobs/await-tool.test.ts +7 -40
- package/src/resources/extensions/async-jobs/await-tool.ts +4 -7
- package/src/resources/extensions/async-jobs/job-manager.ts +3 -33
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +26 -27
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +2 -20
- package/src/resources/extensions/gsd/auto/loop.ts +1 -89
- package/src/resources/extensions/gsd/auto-post-unit.ts +0 -7
- package/src/resources/extensions/gsd/auto.ts +20 -25
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +10 -8
- package/src/resources/extensions/gsd/commands-handlers.ts +1 -5
- package/src/resources/extensions/gsd/context-injector.ts +1 -1
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +8 -4
- package/src/resources/extensions/gsd/gsd-db.ts +5 -52
- package/src/resources/extensions/gsd/key-manager.ts +0 -2
- package/src/resources/extensions/gsd/preferences-skills.ts +36 -2
- package/src/resources/extensions/gsd/preferences-types.ts +0 -16
- package/src/resources/extensions/gsd/preferences.ts +6 -19
- package/src/resources/extensions/gsd/prompt-loader.ts +1 -6
- package/src/resources/extensions/gsd/state.ts +0 -20
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +0 -74
- package/src/resources/extensions/gsd/tests/key-manager.test.ts +0 -63
- package/src/resources/extensions/gsd/tests/preferences.test.ts +0 -53
- package/src/resources/extensions/gsd/write-intercept.ts +1 -10
- package/src/resources/extensions/ollama/index.ts +5 -4
- package/src/resources/extensions/ollama/ollama-client.ts +6 -35
- package/src/resources/extensions/ollama/ollama-discovery.ts +6 -37
- package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +0 -54
- package/dist/resources/extensions/gsd/definition-io.js +0 -15
- package/dist/web/standalone/.next/server/edge-runtime-webpack.js +0 -2
- package/packages/pi-ai/dist/models.generated.test.d.ts +0 -2
- package/packages/pi-ai/dist/models.generated.test.d.ts.map +0 -1
- package/packages/pi-ai/dist/models.generated.test.js +0 -334
- package/packages/pi-ai/dist/models.generated.test.js.map +0 -1
- package/packages/pi-ai/src/models.generated.test.ts +0 -373
- package/src/resources/extensions/gsd/definition-io.ts +0 -18
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +0 -27
- package/src/resources/extensions/gsd/tests/block-db-writes.test.ts +0 -63
- package/src/resources/extensions/gsd/tests/definition-io.test.ts +0 -57
- package/src/resources/extensions/gsd/tests/doctor-heal-fixable-warnings.test.ts +0 -14
- package/src/resources/extensions/gsd/tests/false-degraded-mode-warning.test.ts +0 -104
- package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +0 -54
- package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +0 -34
- package/src/resources/extensions/gsd/tests/preferences-formatting.test.ts +0 -87
- package/src/resources/extensions/gsd/tests/prompt-loader-working-directory.test.ts +0 -19
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +0 -97
- package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +0 -41
- /package/dist/web/standalone/.next/static/{NzO79SOz9jHX-VY5-0t2O → vr6Pbde48w4rMUplqDdh_}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{NzO79SOz9jHX-VY5-0t2O → vr6Pbde48w4rMUplqDdh_}/_ssgManifest.js +0 -0
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
getRequirementById,
|
|
16
16
|
getActiveDecisions,
|
|
17
17
|
getActiveRequirements,
|
|
18
|
-
getTask,
|
|
19
18
|
transaction,
|
|
20
19
|
_getAdapter,
|
|
21
20
|
_resetProvider,
|
|
@@ -360,79 +359,6 @@ describe('gsd-db', () => {
|
|
|
360
359
|
closeDatabase();
|
|
361
360
|
});
|
|
362
361
|
|
|
363
|
-
test('gsd-db: recreates missing verification evidence dedup index after removing duplicate rows', () => {
|
|
364
|
-
const dbPath = tempDbPath();
|
|
365
|
-
openDatabase(dbPath);
|
|
366
|
-
|
|
367
|
-
let adapter = _getAdapter()!;
|
|
368
|
-
adapter.prepare("INSERT INTO milestones (id, created_at) VALUES (?, '')").run('M001');
|
|
369
|
-
adapter.prepare("INSERT INTO slices (milestone_id, id, created_at) VALUES (?, ?, '')").run('M001', 'S01');
|
|
370
|
-
adapter.prepare("INSERT INTO tasks (milestone_id, slice_id, id) VALUES (?, ?, ?)").run('M001', 'S01', 'T01');
|
|
371
|
-
adapter.exec('DROP INDEX IF EXISTS idx_verification_evidence_dedup');
|
|
372
|
-
|
|
373
|
-
const insertEvidence = adapter.prepare(
|
|
374
|
-
`INSERT INTO verification_evidence (
|
|
375
|
-
task_id, slice_id, milestone_id, command, exit_code, verdict, duration_ms, created_at
|
|
376
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
377
|
-
);
|
|
378
|
-
insertEvidence.run('T01', 'S01', 'M001', 'npm test', 1, 'fail', 125, '2026-04-12T00:00:00.000Z');
|
|
379
|
-
insertEvidence.run('T01', 'S01', 'M001', 'npm test', 1, 'fail', 125, '2026-04-12T00:00:01.000Z');
|
|
380
|
-
insertEvidence.run('T01', 'S01', 'M001', 'npm run lint', 0, 'pass', 90, '2026-04-12T00:00:02.000Z');
|
|
381
|
-
|
|
382
|
-
closeDatabase();
|
|
383
|
-
|
|
384
|
-
assert.equal(openDatabase(dbPath), true, 'openDatabase should repair legacy duplicate evidence rows');
|
|
385
|
-
|
|
386
|
-
adapter = _getAdapter()!;
|
|
387
|
-
const countRow = adapter.prepare(
|
|
388
|
-
`SELECT count(*) as cnt
|
|
389
|
-
FROM verification_evidence
|
|
390
|
-
WHERE task_id = ? AND slice_id = ? AND milestone_id = ? AND command = ? AND verdict = ?`,
|
|
391
|
-
).get('T01', 'S01', 'M001', 'npm test', 'fail');
|
|
392
|
-
assert.equal(countRow?.['cnt'], 1, 'duplicate verification evidence rows should be deduplicated before index creation');
|
|
393
|
-
|
|
394
|
-
const indexRow = adapter.prepare(
|
|
395
|
-
"SELECT name FROM sqlite_master WHERE type = 'index' AND name = 'idx_verification_evidence_dedup'",
|
|
396
|
-
).get();
|
|
397
|
-
assert.equal(indexRow?.['name'], 'idx_verification_evidence_dedup', 'dedup index should be recreated on reopen');
|
|
398
|
-
|
|
399
|
-
cleanup(dbPath);
|
|
400
|
-
});
|
|
401
|
-
|
|
402
|
-
test('gsd-db: rowToTask tolerates legacy comma-separated task arrays', () => {
|
|
403
|
-
openDatabase(':memory:');
|
|
404
|
-
|
|
405
|
-
const adapter = _getAdapter()!;
|
|
406
|
-
adapter.prepare("INSERT INTO milestones (id, created_at) VALUES (?, '')").run('M001');
|
|
407
|
-
adapter.prepare("INSERT INTO slices (milestone_id, id, created_at) VALUES (?, ?, '')").run('M001', 'S01');
|
|
408
|
-
adapter.prepare(
|
|
409
|
-
`INSERT INTO tasks (
|
|
410
|
-
milestone_id, slice_id, id, key_files, key_decisions, files, inputs, expected_output
|
|
411
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
412
|
-
).run(
|
|
413
|
-
'M001',
|
|
414
|
-
'S01',
|
|
415
|
-
'T01',
|
|
416
|
-
'[]',
|
|
417
|
-
'[]',
|
|
418
|
-
'tests/test_verify.py, config.yaml, configs/roster_2026-05-11.yaml',
|
|
419
|
-
'tests/test_verify.py',
|
|
420
|
-
'reports/summary.md, artifacts/output.json',
|
|
421
|
-
);
|
|
422
|
-
|
|
423
|
-
const task = getTask('M001', 'S01', 'T01');
|
|
424
|
-
assert.ok(task, 'task should load successfully from DB');
|
|
425
|
-
assert.deepEqual(task?.files, [
|
|
426
|
-
'tests/test_verify.py',
|
|
427
|
-
'config.yaml',
|
|
428
|
-
'configs/roster_2026-05-11.yaml',
|
|
429
|
-
]);
|
|
430
|
-
assert.deepEqual(task?.inputs, ['tests/test_verify.py']);
|
|
431
|
-
assert.deepEqual(task?.expected_output, ['reports/summary.md', 'artifacts/output.json']);
|
|
432
|
-
|
|
433
|
-
closeDatabase();
|
|
434
|
-
});
|
|
435
|
-
|
|
436
362
|
test('gsd-db: query wrappers return null/empty when DB unavailable', () => {
|
|
437
363
|
// Ensure DB is closed
|
|
438
364
|
closeDatabase();
|
|
@@ -427,66 +427,3 @@ test("formatDoctorFindings shows findings with appropriate icons", () => {
|
|
|
427
427
|
assert.ok(output.includes("1 warning"));
|
|
428
428
|
assert.ok(output.includes("1 fixed"));
|
|
429
429
|
});
|
|
430
|
-
|
|
431
|
-
// ─── Regression #3891 — alibaba-coding-plan missing from PROVIDER_REGISTRY ───────
|
|
432
|
-
//
|
|
433
|
-
// Before this fix, `alibaba-coding-plan` was not in PROVIDER_REGISTRY, causing
|
|
434
|
-
// `/gsd keys add alibaba-coding-plan` to silently fail (provider not found).
|
|
435
|
-
// alibaba-dashscope is the new standalone provider added in the same PR.
|
|
436
|
-
|
|
437
|
-
test("regression #3891 — alibaba-coding-plan is in PROVIDER_REGISTRY", () => {
|
|
438
|
-
const provider = findProvider("alibaba-coding-plan");
|
|
439
|
-
assert.ok(provider, "alibaba-coding-plan must be in PROVIDER_REGISTRY for /gsd keys add to work");
|
|
440
|
-
assert.equal(provider.id, "alibaba-coding-plan");
|
|
441
|
-
assert.equal(provider.category, "llm");
|
|
442
|
-
assert.equal(provider.envVar, "ALIBABA_API_KEY");
|
|
443
|
-
});
|
|
444
|
-
|
|
445
|
-
test("alibaba-dashscope is in PROVIDER_REGISTRY", () => {
|
|
446
|
-
const provider = findProvider("alibaba-dashscope");
|
|
447
|
-
assert.ok(provider, "alibaba-dashscope must be in PROVIDER_REGISTRY for /gsd keys add to work");
|
|
448
|
-
assert.equal(provider.id, "alibaba-dashscope");
|
|
449
|
-
assert.equal(provider.category, "llm");
|
|
450
|
-
assert.equal(provider.envVar, "DASHSCOPE_API_KEY");
|
|
451
|
-
});
|
|
452
|
-
|
|
453
|
-
test("alibaba-coding-plan and alibaba-dashscope are separate providers (different env vars)", () => {
|
|
454
|
-
const codingPlan = findProvider("alibaba-coding-plan");
|
|
455
|
-
const dashscope = findProvider("alibaba-dashscope");
|
|
456
|
-
assert.ok(codingPlan, "alibaba-coding-plan must exist");
|
|
457
|
-
assert.ok(dashscope, "alibaba-dashscope must exist");
|
|
458
|
-
assert.notEqual(
|
|
459
|
-
codingPlan.envVar,
|
|
460
|
-
dashscope.envVar,
|
|
461
|
-
"alibaba-coding-plan and alibaba-dashscope must use different env vars",
|
|
462
|
-
);
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
test("getAllKeyStatuses includes alibaba-coding-plan", () => {
|
|
466
|
-
const auth = makeAuth();
|
|
467
|
-
const statuses = getAllKeyStatuses(auth);
|
|
468
|
-
const found = statuses.find((s) => s.provider.id === "alibaba-coding-plan");
|
|
469
|
-
assert.ok(found, "getAllKeyStatuses must include alibaba-coding-plan");
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
test("getAllKeyStatuses includes alibaba-dashscope", () => {
|
|
473
|
-
const auth = makeAuth();
|
|
474
|
-
const statuses = getAllKeyStatuses(auth);
|
|
475
|
-
const found = statuses.find((s) => s.provider.id === "alibaba-dashscope");
|
|
476
|
-
assert.ok(found, "getAllKeyStatuses must include alibaba-dashscope");
|
|
477
|
-
});
|
|
478
|
-
|
|
479
|
-
test("getAllKeyStatuses detects DASHSCOPE_API_KEY for alibaba-dashscope (failure path: missing key shows not configured)", () => {
|
|
480
|
-
const saved = process.env.DASHSCOPE_API_KEY;
|
|
481
|
-
delete process.env.DASHSCOPE_API_KEY;
|
|
482
|
-
try {
|
|
483
|
-
const auth = makeAuth();
|
|
484
|
-
const statuses = getAllKeyStatuses(auth);
|
|
485
|
-
const found = statuses.find((s) => s.provider.id === "alibaba-dashscope");
|
|
486
|
-
assert.ok(found);
|
|
487
|
-
assert.equal(found.configured, false);
|
|
488
|
-
assert.equal(found.source, "none");
|
|
489
|
-
} finally {
|
|
490
|
-
if (saved !== undefined) process.env.DASHSCOPE_API_KEY = saved;
|
|
491
|
-
}
|
|
492
|
-
});
|
|
@@ -10,14 +10,10 @@
|
|
|
10
10
|
|
|
11
11
|
import test from "node:test";
|
|
12
12
|
import assert from "node:assert/strict";
|
|
13
|
-
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
14
|
-
import { tmpdir } from "node:os";
|
|
15
|
-
import { join } from "node:path";
|
|
16
13
|
import {
|
|
17
14
|
validatePreferences,
|
|
18
15
|
applyModeDefaults,
|
|
19
16
|
getIsolationMode,
|
|
20
|
-
loadEffectiveGSDPreferences,
|
|
21
17
|
parsePreferencesMarkdown,
|
|
22
18
|
_resetParseWarningFlag,
|
|
23
19
|
} from "../preferences.ts";
|
|
@@ -505,55 +501,6 @@ test("experimental.rtk parses correctly from preferences markdown", () => {
|
|
|
505
501
|
assert.equal(prefs!.experimental?.rtk, true);
|
|
506
502
|
});
|
|
507
503
|
|
|
508
|
-
test("loadEffectiveGSDPreferences preserves experimental prefs across global+project merge", () => {
|
|
509
|
-
const originalCwd = process.cwd();
|
|
510
|
-
const originalGsdHome = process.env.GSD_HOME;
|
|
511
|
-
const tempProject = mkdtempSync(join(tmpdir(), "gsd-prefs-project-"));
|
|
512
|
-
const tempGsdHome = mkdtempSync(join(tmpdir(), "gsd-prefs-home-"));
|
|
513
|
-
|
|
514
|
-
try {
|
|
515
|
-
mkdirSync(join(tempProject, ".gsd"), { recursive: true });
|
|
516
|
-
|
|
517
|
-
writeFileSync(
|
|
518
|
-
join(tempGsdHome, "preferences.md"),
|
|
519
|
-
[
|
|
520
|
-
"---",
|
|
521
|
-
"version: 1",
|
|
522
|
-
"experimental:",
|
|
523
|
-
" rtk: true",
|
|
524
|
-
"---",
|
|
525
|
-
].join("\n"),
|
|
526
|
-
"utf-8",
|
|
527
|
-
);
|
|
528
|
-
|
|
529
|
-
writeFileSync(
|
|
530
|
-
join(tempProject, ".gsd", "PREFERENCES.md"),
|
|
531
|
-
[
|
|
532
|
-
"---",
|
|
533
|
-
"version: 1",
|
|
534
|
-
"git:",
|
|
535
|
-
" isolation: none",
|
|
536
|
-
"---",
|
|
537
|
-
].join("\n"),
|
|
538
|
-
"utf-8",
|
|
539
|
-
);
|
|
540
|
-
|
|
541
|
-
process.env.GSD_HOME = tempGsdHome;
|
|
542
|
-
process.chdir(tempProject);
|
|
543
|
-
|
|
544
|
-
const loaded = loadEffectiveGSDPreferences();
|
|
545
|
-
assert.notEqual(loaded, null);
|
|
546
|
-
assert.equal(loaded!.preferences.experimental?.rtk, true);
|
|
547
|
-
assert.equal(loaded!.preferences.git?.isolation, "none");
|
|
548
|
-
} finally {
|
|
549
|
-
process.chdir(originalCwd);
|
|
550
|
-
if (originalGsdHome === undefined) delete process.env.GSD_HOME;
|
|
551
|
-
else process.env.GSD_HOME = originalGsdHome;
|
|
552
|
-
rmSync(tempProject, { recursive: true, force: true });
|
|
553
|
-
rmSync(tempGsdHome, { recursive: true, force: true });
|
|
554
|
-
}
|
|
555
|
-
});
|
|
556
|
-
|
|
557
504
|
test("experimental.rtk defaults to off in new project preferences", () => {
|
|
558
505
|
// No experimental key → feature is disabled
|
|
559
506
|
const content = "---\nversion: 1\n---\n";
|
|
@@ -24,9 +24,6 @@ const BLOCKED_PATTERNS: RegExp[] = [
|
|
|
24
24
|
/(^|[/\\])\.gsd[/\\]STATE\.md$/i,
|
|
25
25
|
// Also match resolved symlink paths under ~/.gsd/projects/ (Pitfall #6)
|
|
26
26
|
/(^|[/\\])\.gsd[/\\]projects[/\\][^/\\]+[/\\]STATE\.md$/i,
|
|
27
|
-
// gsd.db and WAL/SHM files — single-writer WAL connection managed by engine (#3625)
|
|
28
|
-
/(^|[/\\])\.gsd[/\\]gsd\.db(-wal|-shm)?$/i,
|
|
29
|
-
/(^|[/\\])\.gsd[/\\]projects[/\\][^/\\]+[/\\]gsd\.db(-wal|-shm)?$/i,
|
|
30
27
|
];
|
|
31
28
|
|
|
32
29
|
/**
|
|
@@ -44,12 +41,6 @@ const BASH_STATE_PATTERNS: RegExp[] = [
|
|
|
44
41
|
/\bsed\b.*-i.*STATE\.md/i,
|
|
45
42
|
// dd output to STATE.md
|
|
46
43
|
/\bdd\b.*of=\S*STATE\.md/i,
|
|
47
|
-
// Direct DB access via sqlite3/sql.js/better-sqlite3 targeting gsd.db (#3625)
|
|
48
|
-
/\b(sqlite3|sql\.js|better-sqlite3|node:sqlite)\b.*gsd\.db/i,
|
|
49
|
-
/\bgsd\.db\b.*\b(sqlite3|sql\.js|better-sqlite3)\b/i,
|
|
50
|
-
// Shell writes targeting gsd.db files
|
|
51
|
-
/[>|]+\s*\S*gsd\.db/i,
|
|
52
|
-
/\b(cp|mv|dd)\b.*gsd\.db/i,
|
|
53
44
|
];
|
|
54
45
|
|
|
55
46
|
/**
|
|
@@ -90,7 +81,7 @@ function matchesBlockedPattern(path: string): boolean {
|
|
|
90
81
|
* Error message returned when an agent attempts to directly write an authoritative .gsd/ state file.
|
|
91
82
|
* Directs the agent to use engine tool calls instead.
|
|
92
83
|
*/
|
|
93
|
-
export const BLOCKED_WRITE_ERROR = `Direct writes to .gsd/STATE.md
|
|
84
|
+
export const BLOCKED_WRITE_ERROR = `Direct writes to .gsd/STATE.md are blocked. Use engine tool calls instead:
|
|
94
85
|
- To complete a task: call gsd_complete_task(milestone_id, slice_id, task_id, summary)
|
|
95
86
|
- To complete a slice: call gsd_complete_slice(milestone_id, slice_id, summary, uat_result)
|
|
96
87
|
- To save a decision: call gsd_save_decision(scope, decision, choice, rationale)
|
|
@@ -69,12 +69,13 @@ async function probeAndRegister(pi: ExtensionAPI): Promise<boolean> {
|
|
|
69
69
|
|
|
70
70
|
const baseUrl = client.getOllamaHost();
|
|
71
71
|
|
|
72
|
-
// Use authMode "apiKey" (#3440).
|
|
73
|
-
//
|
|
74
|
-
//
|
|
72
|
+
// Use authMode "apiKey" with a dummy key (#3440).
|
|
73
|
+
// authMode "none" requires a custom streamSimple handler, but Ollama uses
|
|
74
|
+
// the standard OpenAI-compatible streaming endpoint. Ollama ignores the
|
|
75
|
+
// Authorization header so the dummy key is harmless.
|
|
75
76
|
pi.registerProvider("ollama", {
|
|
76
77
|
authMode: "apiKey",
|
|
77
|
-
apiKey:
|
|
78
|
+
apiKey: "ollama",
|
|
78
79
|
baseUrl,
|
|
79
80
|
api: "ollama-chat",
|
|
80
81
|
streamSimple: streamOllamaChat,
|
|
@@ -34,34 +34,11 @@ export function getOllamaHost(): string {
|
|
|
34
34
|
return `http://${host}`;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
/**
|
|
38
|
-
* Get auth headers for Ollama API requests.
|
|
39
|
-
* For cloud endpoints (OLLAMA_HOST pointing to ollama.com or remote instances),
|
|
40
|
-
* OLLAMA_API_KEY is used as a Bearer token. Local Ollama ignores the header.
|
|
41
|
-
*/
|
|
42
|
-
function getAuthHeaders(): Record<string, string> {
|
|
43
|
-
const apiKey = process.env.OLLAMA_API_KEY;
|
|
44
|
-
if (!apiKey) return {};
|
|
45
|
-
return { Authorization: `Bearer ${apiKey}` };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Merge auth headers into request options.
|
|
50
|
-
*/
|
|
51
|
-
function withAuth(options: RequestInit = {}): RequestInit {
|
|
52
|
-
const authHeaders = getAuthHeaders();
|
|
53
|
-
if (Object.keys(authHeaders).length === 0) return options;
|
|
54
|
-
return {
|
|
55
|
-
...options,
|
|
56
|
-
headers: { ...authHeaders, ...(options.headers as Record<string, string> || {}) },
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
37
|
async function fetchWithTimeout(url: string, options: RequestInit = {}, timeoutMs = REQUEST_TIMEOUT_MS): Promise<Response> {
|
|
61
38
|
const controller = new AbortController();
|
|
62
39
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
63
40
|
try {
|
|
64
|
-
return await fetch(url,
|
|
41
|
+
return await fetch(url, { ...options, signal: controller.signal });
|
|
65
42
|
} finally {
|
|
66
43
|
clearTimeout(timeout);
|
|
67
44
|
}
|
|
@@ -69,16 +46,10 @@ async function fetchWithTimeout(url: string, options: RequestInit = {}, timeoutM
|
|
|
69
46
|
|
|
70
47
|
/**
|
|
71
48
|
* Check if Ollama is running and reachable.
|
|
72
|
-
* For cloud endpoints (OLLAMA_HOST pointing to ollama.com), uses /api/tags
|
|
73
|
-
* as the probe since the root endpoint may not be available.
|
|
74
49
|
*/
|
|
75
50
|
export async function isRunning(): Promise<boolean> {
|
|
76
51
|
try {
|
|
77
|
-
const
|
|
78
|
-
const isCloud = host.includes("ollama.com") || host.includes("cloud");
|
|
79
|
-
const probeUrl = isCloud ? `${host}/api/tags` : `${host}/`;
|
|
80
|
-
const timeout = isCloud ? REQUEST_TIMEOUT_MS : PROBE_TIMEOUT_MS;
|
|
81
|
-
const response = await fetchWithTimeout(probeUrl, isCloud ? { method: "GET" } : {}, timeout);
|
|
52
|
+
const response = await fetchWithTimeout(`${getOllamaHost()}/`, {}, PROBE_TIMEOUT_MS);
|
|
82
53
|
return response.ok;
|
|
83
54
|
} catch {
|
|
84
55
|
return false;
|
|
@@ -146,12 +117,12 @@ export async function pullModel(
|
|
|
146
117
|
onProgress?: (progress: OllamaPullProgress) => void,
|
|
147
118
|
signal?: AbortSignal,
|
|
148
119
|
): Promise<void> {
|
|
149
|
-
const response = await fetch(`${getOllamaHost()}/api/pull`,
|
|
120
|
+
const response = await fetch(`${getOllamaHost()}/api/pull`, {
|
|
150
121
|
method: "POST",
|
|
151
122
|
headers: { "Content-Type": "application/json" },
|
|
152
123
|
body: JSON.stringify({ name, stream: true }),
|
|
153
124
|
signal,
|
|
154
|
-
})
|
|
125
|
+
});
|
|
155
126
|
|
|
156
127
|
if (!response.ok) {
|
|
157
128
|
const text = await response.text();
|
|
@@ -175,12 +146,12 @@ export async function* chat(
|
|
|
175
146
|
request: OllamaChatRequest,
|
|
176
147
|
signal?: AbortSignal,
|
|
177
148
|
): AsyncGenerator<OllamaChatResponse> {
|
|
178
|
-
const response = await fetch(`${getOllamaHost()}/api/chat`,
|
|
149
|
+
const response = await fetch(`${getOllamaHost()}/api/chat`, {
|
|
179
150
|
method: "POST",
|
|
180
151
|
headers: { "Content-Type": "application/json" },
|
|
181
152
|
body: JSON.stringify(request),
|
|
182
153
|
signal,
|
|
183
|
-
})
|
|
154
|
+
});
|
|
184
155
|
|
|
185
156
|
if (!response.ok) {
|
|
186
157
|
const text = await response.text();
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* Returns models in the format expected by pi.registerProvider().
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { listModels
|
|
11
|
+
import { listModels } from "./ollama-client.js";
|
|
12
12
|
import {
|
|
13
13
|
estimateContextFromParams,
|
|
14
14
|
formatModelSize,
|
|
@@ -17,24 +17,6 @@ import {
|
|
|
17
17
|
} from "./model-capabilities.js";
|
|
18
18
|
import type { OllamaChatOptions, OllamaModelInfo } from "./types.js";
|
|
19
19
|
|
|
20
|
-
/**
|
|
21
|
-
* Extract context window from /api/show model_info.
|
|
22
|
-
* Keys follow the pattern "{architecture}.context_length" (e.g. "llama.context_length").
|
|
23
|
-
*/
|
|
24
|
-
function extractContextFromModelInfo(modelInfo: Record<string, unknown>): number | undefined {
|
|
25
|
-
for (const [key, value] of Object.entries(modelInfo)) {
|
|
26
|
-
if (key.endsWith(".context_length") && typeof value === "number" && value > 0) {
|
|
27
|
-
return value;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return undefined;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
type ClientDeps = {
|
|
34
|
-
listModels: typeof listModels;
|
|
35
|
-
showModel: typeof showModel;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
20
|
export interface DiscoveredOllamaModel {
|
|
39
21
|
id: string;
|
|
40
22
|
name: string;
|
|
@@ -53,26 +35,13 @@ export interface DiscoveredOllamaModel {
|
|
|
53
35
|
|
|
54
36
|
const ZERO_COST = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
55
37
|
|
|
56
|
-
|
|
38
|
+
function enrichModel(info: OllamaModelInfo): DiscoveredOllamaModel {
|
|
57
39
|
const caps = getModelCapabilities(info.name);
|
|
58
40
|
const parameterSize = info.details?.parameter_size ?? "";
|
|
59
41
|
|
|
60
|
-
//
|
|
61
|
-
let showContextWindow: number | undefined;
|
|
62
|
-
if (caps.contextWindow === undefined) {
|
|
63
|
-
try {
|
|
64
|
-
const showData = await deps.showModel(info.name);
|
|
65
|
-
showContextWindow = extractContextFromModelInfo(showData.model_info);
|
|
66
|
-
} catch (err) {
|
|
67
|
-
// non-fatal: fall through to estimate
|
|
68
|
-
if (process.env.GSD_DEBUG) console.warn(`[ollama] /api/show failed for ${info.name}:`, err instanceof Error ? err.message : String(err));
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Determine context window: known table > /api/show > estimate from param size > default
|
|
42
|
+
// Determine context window: known table > estimate from param size > default
|
|
73
43
|
const contextWindow =
|
|
74
44
|
caps.contextWindow ??
|
|
75
|
-
showContextWindow ??
|
|
76
45
|
(parameterSize ? estimateContextFromParams(parameterSize) : 8192);
|
|
77
46
|
|
|
78
47
|
// Determine max tokens: known table > fraction of context > default
|
|
@@ -104,11 +73,11 @@ async function enrichModel(info: OllamaModelInfo, deps: ClientDeps): Promise<Dis
|
|
|
104
73
|
/**
|
|
105
74
|
* Discover all locally available Ollama models with enriched capabilities.
|
|
106
75
|
*/
|
|
107
|
-
export async function discoverModels(
|
|
108
|
-
const tags = await
|
|
76
|
+
export async function discoverModels(): Promise<DiscoveredOllamaModel[]> {
|
|
77
|
+
const tags = await listModels();
|
|
109
78
|
if (!tags.models || tags.models.length === 0) return [];
|
|
110
79
|
|
|
111
|
-
return
|
|
80
|
+
return tags.models.map(enrichModel);
|
|
112
81
|
}
|
|
113
82
|
|
|
114
83
|
/**
|
|
@@ -1,55 +1 @@
|
|
|
1
1
|
// GSD2 — Tests for Ollama model discovery and enrichment
|
|
2
|
-
import { describe, it } from "node:test";
|
|
3
|
-
import assert from "node:assert/strict";
|
|
4
|
-
import { discoverModels } from "../ollama-discovery.js";
|
|
5
|
-
import type { OllamaTagsResponse, OllamaShowResponse } from "../types.js";
|
|
6
|
-
|
|
7
|
-
const EMPTY_DETAILS = { parent_model: "", format: "", family: "", families: null, parameter_size: "", quantization_level: "" };
|
|
8
|
-
|
|
9
|
-
function modelStub(name: string, parameterSize = "") {
|
|
10
|
-
return { name, model: name, modified_at: "", size: 0, digest: "", details: { ...EMPTY_DETAILS, parameter_size: parameterSize } };
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function tagsStub(name: string, parameterSize = ""): OllamaTagsResponse {
|
|
14
|
-
return { models: [modelStub(name, parameterSize)] };
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function showStub(modelInfo: Record<string, unknown>): OllamaShowResponse {
|
|
18
|
-
return { modelfile: "", parameters: "", template: "", details: EMPTY_DETAILS, model_info: modelInfo };
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
describe("discoverModels — context window resolution", () => {
|
|
22
|
-
it("uses known table context window without calling /api/show", async () => {
|
|
23
|
-
let showCalled = false;
|
|
24
|
-
const models = await discoverModels({
|
|
25
|
-
listModels: async () => tagsStub("llama3.2:latest", "3B"),
|
|
26
|
-
showModel: async () => { showCalled = true; throw new Error("should not be called"); },
|
|
27
|
-
});
|
|
28
|
-
assert.equal(models[0].contextWindow, 131072);
|
|
29
|
-
assert.equal(showCalled, false);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it("uses context_length from /api/show model_info for unknown model", async () => {
|
|
33
|
-
const models = await discoverModels({
|
|
34
|
-
listModels: async () => tagsStub("gemini-3-flash-preview:latest"),
|
|
35
|
-
showModel: async () => showStub({ "gemini.context_length": 1048576 }),
|
|
36
|
-
});
|
|
37
|
-
assert.equal(models[0].contextWindow, 1048576);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it("falls back to 8192 when /api/show model_info has no context_length key", async () => {
|
|
41
|
-
const models = await discoverModels({
|
|
42
|
-
listModels: async () => tagsStub("unknown-model:latest"),
|
|
43
|
-
showModel: async () => showStub({}),
|
|
44
|
-
});
|
|
45
|
-
assert.equal(models[0].contextWindow, 8192);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("falls back to 8192 when /api/show throws", async () => {
|
|
49
|
-
const models = await discoverModels({
|
|
50
|
-
listModels: async () => tagsStub("unknown-model:latest"),
|
|
51
|
-
showModel: async () => { throw new Error("network error"); },
|
|
52
|
-
});
|
|
53
|
-
assert.equal(models[0].contextWindow, 8192);
|
|
54
|
-
});
|
|
55
|
-
});
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* definition-io.ts — Read frozen DEFINITION.yaml from a run directory.
|
|
3
|
-
*
|
|
4
|
-
* Extracted from custom-workflow-engine.ts to break the circular dependency
|
|
5
|
-
* between context-injector.ts and custom-workflow-engine.ts.
|
|
6
|
-
*/
|
|
7
|
-
import { readFileSync } from "node:fs";
|
|
8
|
-
import { join } from "node:path";
|
|
9
|
-
import { parse } from "yaml";
|
|
10
|
-
/** Read and parse the frozen DEFINITION.yaml from a run directory. */
|
|
11
|
-
export function readFrozenDefinition(runDir) {
|
|
12
|
-
const defPath = join(runDir, "DEFINITION.yaml");
|
|
13
|
-
const raw = readFileSync(defPath, "utf-8");
|
|
14
|
-
return parse(raw, { schema: "core" });
|
|
15
|
-
}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
(()=>{"use strict";var a,b,c,d,e={},f={};function g(a){var b=f[a];if(void 0!==b)return b.exports;var c=f[a]={exports:{}},d=!0;try{e[a](c,c.exports,g),d=!1}finally{d&&delete f[a]}return c.exports}g.m=e,g.amdO={},a=[],g.O=(b,c,d,e)=>{if(c){e=e||0;for(var f=a.length;f>0&&a[f-1][2]>e;f--)a[f]=a[f-1];a[f]=[c,d,e];return}for(var h=1/0,f=0;f<a.length;f++){for(var[c,d,e]=a[f],i=!0,j=0;j<c.length;j++)(!1&e||h>=e)&&Object.keys(g.O).every(a=>g.O[a](c[j]))?c.splice(j--,1):(i=!1,e<h&&(h=e));if(i){a.splice(f--,1);var k=d();void 0!==k&&(b=k)}}return b},g.n=a=>{var b=a&&a.__esModule?()=>a.default:()=>a;return g.d(b,{a:b}),b},g.d=(a,b)=>{for(var c in b)g.o(b,c)&&!g.o(a,c)&&Object.defineProperty(a,c,{enumerable:!0,get:b[c]})},g.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(a){if("object"==typeof window)return window}}(),g.o=(a,b)=>Object.prototype.hasOwnProperty.call(a,b),g.r=a=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(a,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(a,"__esModule",{value:!0})},b={149:0},g.O.j=a=>0===b[a],c=(a,c)=>{var d,e,[f,h,i]=c,j=0;if(f.some(a=>0!==b[a])){for(d in h)g.o(h,d)&&(g.m[d]=h[d]);if(i)var k=i(g)}for(a&&a(c);j<f.length;j++)e=f[j],g.o(b,e)&&b[e]&&b[e][0](),b[e]=0;return g.O(k)},(d=self.webpackChunk_N_E=self.webpackChunk_N_E||[]).forEach(c.bind(null,0)),d.push=c.bind(null,d.push.bind(d))})();
|
|
2
|
-
//# sourceMappingURL=edge-runtime-webpack.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"models.generated.test.d.ts","sourceRoot":"","sources":["../src/models.generated.test.ts"],"names":[],"mappings":""}
|