@qvac/harness 0.2.7 → 0.2.8
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/.claude/skills/pr-review/SKILL.md +237 -40
- package/dist/harness.bundle +10 -9
- package/dist-lib/index.js +58 -58
- package/dist-lib/lib/audio-transcode-bare.js +2 -2
- package/dist-lib/lib/capabilities/completion.js +30 -30
- package/dist-lib/lib/capabilities/download.js +2 -2
- package/dist-lib/lib/capabilities/speech-text.js +1 -1
- package/dist-lib/lib/capabilities/tool-prompt-log.js +1 -1
- package/dist-lib/lib/capabilities/tool-selection.js +2 -2
- package/dist-lib/lib/capabilities/tool-turns.js +1 -1
- package/dist-lib/lib/capabilities/usage-breakdown.js +1 -1
- package/dist-lib/lib/capabilities/voice.js +3 -3
- package/dist-lib/lib/connect.js +11 -11
- package/dist-lib/lib/context-window.js +1 -1
- package/dist-lib/lib/docx/index.js +3 -3
- package/dist-lib/lib/hardware/capability-probe.js +3 -3
- package/dist-lib/lib/hardware/gpu-probe-addon.js +2 -2
- package/dist-lib/lib/hardware/gpu-probe-entry.js +1 -1
- package/dist-lib/lib/helpers/markup-stream-filter.js +1 -1
- package/dist-lib/lib/helpers/run-outcome.js +1 -1
- package/dist-lib/lib/helpers/spawn-path.d.ts +1 -1
- package/dist-lib/lib/helpers/thinking.js +2 -2
- package/dist-lib/lib/helpers/tool-intent.js +1 -1
- package/dist-lib/lib/helpers/tool-label.js +3 -3
- package/dist-lib/lib/hooks/built-in/arg-repair.d.ts +1 -1
- package/dist-lib/lib/hooks/built-in/arg-repair.js +1 -1
- package/dist-lib/lib/hooks/built-in/egress.d.ts +1 -1
- package/dist-lib/lib/hooks/built-in/egress.js +2 -2
- package/dist-lib/lib/hooks/built-in/index.js +3 -3
- package/dist-lib/lib/hooks/built-in/skill-catalog.d.ts +1 -1
- package/dist-lib/lib/hooks/pipeline.js +4 -4
- package/dist-lib/lib/hooks/registry.js +1 -1
- package/dist-lib/lib/hooks/run.js +1 -1
- package/dist-lib/lib/models/model-catalog.js +4 -4
- package/dist-lib/lib/models/model-delete.js +1 -1
- package/dist-lib/lib/models/model-handle.js +1 -1
- package/dist-lib/lib/models/model-list.js +1 -1
- package/dist-lib/lib/models/model-pool.js +8 -8
- package/dist-lib/lib/models/model-source.js +1 -1
- package/dist-lib/lib/models/music-catalog.d.ts +1 -1
- package/dist-lib/lib/no-redirect-fetch-bare.js +3 -3
- package/dist-lib/lib/no-redirect-fetch-impl.js +1 -1
- package/dist-lib/lib/no-redirect-fetch-node.js +2 -2
- package/dist-lib/lib/resolution-detector.js +1 -1
- package/dist-lib/lib/sdk-loader.js +2 -2
- package/dist-lib/lib/sdk-storage.js +1 -1
- package/dist-lib/lib/serve.js +10 -10
- package/dist-lib/lib/spawn.js +3 -3
- package/dist-lib/lib/staging.js +1 -1
- package/dist-lib/lib/tools/catalog.js +1 -1
- package/dist-lib/lib/tools/create-documents.js +2 -2
- package/dist-lib/lib/tools/edit-documents.js +2 -2
- package/dist-lib/lib/tools/edit-image.js +2 -2
- package/dist-lib/lib/tools/exec/adapters/python/attachments.js +2 -2
- package/dist-lib/lib/tools/exec/adapters/python/create-effect.js +1 -1
- package/dist-lib/lib/tools/exec/adapters/python/loader.js +1 -1
- package/dist-lib/lib/tools/exec/adapters/python/memfs.js +2 -2
- package/dist-lib/lib/tools/exec/adapters/python/pyodide.js +6 -6
- package/dist-lib/lib/tools/exec/adapters/python/python-adapter.js +3 -3
- package/dist-lib/lib/tools/exec/adapters/python/run-session.js +5 -5
- package/dist-lib/lib/tools/exec/adapters/python/wheels.js +1 -1
- package/dist-lib/lib/tools/exec/adapters/python/worker/client.js +3 -3
- package/dist-lib/lib/tools/exec/adapters/python/worker/entry.js +4 -4
- package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.js +1 -1
- package/dist-lib/lib/tools/exec/obsidian/cli-process.js +2 -2
- package/dist-lib/lib/tools/exec/obsidian/cli.js +4 -4
- package/dist-lib/lib/tools/exec/obsidian/command.js +1 -1
- package/dist-lib/lib/tools/exec/obsidian/route.js +7 -7
- package/dist-lib/lib/tools/exec/obsidian/vault-create.js +2 -2
- package/dist-lib/lib/tools/exec/obsidian/vault-fs.js +6 -6
- package/dist-lib/lib/tools/exec/obsidian/vault-paths.js +2 -2
- package/dist-lib/lib/tools/exec/obsidian/vault-read.js +1 -1
- package/dist-lib/lib/tools/exec/obsidian/vault-write.js +2 -2
- package/dist-lib/lib/tools/exec/runner.js +1 -1
- package/dist-lib/lib/tools/exec.js +13 -13
- package/dist-lib/lib/tools/file-glob.js +3 -3
- package/dist-lib/lib/tools/fs/local.js +1 -1
- package/dist-lib/lib/tools/fs/remote.js +1 -1
- package/dist-lib/lib/tools/fs/walk.js +2 -2
- package/dist-lib/lib/tools/generate-image.js +4 -4
- package/dist-lib/lib/tools/generate-music.js +6 -6
- package/dist-lib/lib/tools/grep.js +6 -6
- package/dist-lib/lib/tools/http-request/truncate-response.js +1 -1
- package/dist-lib/lib/tools/http-request.js +9 -9
- package/dist-lib/lib/tools/mcp/utils.js +1 -1
- package/dist-lib/lib/tools/mcp-call.js +8 -8
- package/dist-lib/lib/tools/operations/builders.d.ts +1 -1
- package/dist-lib/lib/tools/operations/builders.js +1 -1
- package/dist-lib/lib/tools/operations/compile.js +1 -1
- package/dist-lib/lib/tools/operations/manifest.d.ts +16 -16
- package/dist-lib/lib/tools/operations/manifest.js +1 -1
- package/dist-lib/lib/tools/outbound-guard.js +1 -1
- package/dist-lib/lib/tools/rag-search.js +1 -1
- package/dist-lib/lib/tools/read-files.js +3 -3
- package/dist-lib/lib/tools/skill.js +8 -8
- package/dist-lib/lib/tools/skills/auth-resolver.js +2 -2
- package/dist-lib/lib/tools/skills/bin-check.js +1 -1
- package/dist-lib/lib/tools/skills/bundled-dir.js +2 -2
- package/dist-lib/lib/tools/skills/catalog.js +10 -10
- package/dist-lib/lib/tools/skills/cli-schema-check.js +1 -1
- package/dist-lib/lib/tools/skills/cli-schema-load.js +1 -1
- package/dist-lib/lib/tools/skills/cli-schema.js +4 -4
- package/dist-lib/lib/tools/skills/credential-check.js +3 -3
- package/dist-lib/lib/tools/skills/credential-grants.js +1 -1
- package/dist-lib/lib/tools/skills/credential-health.js +2 -2
- package/dist-lib/lib/tools/skills/frontmatter-parser.js +1 -1
- package/dist-lib/lib/tools/skills/index.js +5 -5
- package/dist-lib/lib/tools/skills/mention.js +1 -1
- package/dist-lib/lib/tools/skills/overlay-crud.js +1 -1
- package/dist-lib/lib/tools/skills/setup-routes.js +1 -1
- package/dist-lib/lib/tools/skills/skill-settings.js +1 -1
- package/dist-lib/lib/tools/skills/skill-state-constants.d.ts +8 -8
- package/dist-lib/lib/tools/skills/skill-state.js +9 -9
- package/dist-lib/lib/tools/toolsets.d.ts +1 -1
- package/dist-lib/lib/tools/url-guard.js +2 -2
- package/dist-lib/lib/tools/weather-lookup/place.d.ts +11 -0
- package/dist-lib/lib/tools/weather-lookup/place.js +152 -0
- package/dist-lib/lib/tools/weather-lookup/report.d.ts +37 -0
- package/dist-lib/lib/tools/weather-lookup/report.js +56 -0
- package/dist-lib/lib/tools/weather-lookup.d.ts +8 -0
- package/dist-lib/lib/tools/weather-lookup.js +110 -0
- package/dist-lib/lib/tools/web-fetch.js +10 -10
- package/dist-lib/lib/tools/web-search.js +2 -2
- package/dist-lib/lib/transport.js +1 -1
- package/dist-lib/lib/validating-lookup.js +1 -1
- package/dist-lib/lib/web-fetch/embedded-state.js +1 -1
- package/dist-lib/lib/web-fetch/extract.js +1 -1
- package/dist-lib/lib/web-fetch/images.js +1 -1
- package/dist-lib/lib/web-fetch/video.js +1 -1
- package/dist-lib/lib/web-search/engine-registry.js +7 -7
- package/dist-lib/lib/web-search/engines/aol.js +3 -3
- package/dist-lib/lib/web-search/engines/bing.js +4 -4
- package/dist-lib/lib/web-search/engines/brave.js +2 -2
- package/dist-lib/lib/web-search/engines/duckduckgo.js +3 -3
- package/dist-lib/lib/web-search/engines/google.js +4 -4
- package/dist-lib/lib/web-search/engines/wikipedia.js +2 -2
- package/dist-lib/lib/web-search/engines/yahoo.js +3 -3
- package/dist-lib/lib/web-search/fetch-html.js +1 -1
- package/dist-lib/lib/web-search/merge-results.js +1 -1
- package/dist-lib/lib/web-search/orchestrator.js +3 -3
- package/dist-lib/schema/baseline.js +1 -1
- package/dist-lib/schema/build.js +3 -3
- package/dist-lib/schema/release-tags.d.ts +2 -1
- package/dist-lib/schema/release-tags.js +9 -7
- package/docs/decisions/2026-09-10-skill-wording-is-measured-offline.md +63 -0
- package/docs/decisions/2026-09-16-a-lookup-reports-the-place-it-resolved.md +70 -0
- package/docs/decisions/INDEX.md +17 -15
- package/package.json +16 -3
- package/worker/harness-sidecar.mjs +2 -0
|
@@ -12,6 +12,6 @@ export type BuilderOutcome = {
|
|
|
12
12
|
export interface OperationBuilder {
|
|
13
13
|
build: (args: Record<string, unknown>) => BuilderOutcome;
|
|
14
14
|
}
|
|
15
|
-
export declare const BUILDER_NAMES: readonly [
|
|
15
|
+
export declare const BUILDER_NAMES: readonly ['gmail-send', 'gmail-draft', 'calendar-meet-event', 'calendar-add-meet', 'docs-create', 'docs-append-text', 'sheets-create', 'sheets-write-values', 'sheets-append-values', 'drive-create-folder', 'drive-trash', 'notion-create-page', 'notion-insert-content'];
|
|
16
16
|
export type BuilderName = (typeof BUILDER_NAMES)[number];
|
|
17
17
|
export declare const BUILDERS: Record<BuilderName, OperationBuilder>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomBytes } from 'crypto';
|
|
2
2
|
import b4a from 'b4a';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { buildGmailMessage, GmailEnvelopeSchema } from
|
|
4
|
+
import { buildGmailMessage, GmailEnvelopeSchema } from './gmail-message.js';
|
|
5
5
|
export const BUILDER_NAMES = [
|
|
6
6
|
'gmail-send',
|
|
7
7
|
'gmail-draft',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BUILDERS } from
|
|
1
|
+
import { BUILDERS } from './builders.js';
|
|
2
2
|
export function compileOperationTools(catalog, { httpRequestTool, mcpCallTool }) {
|
|
3
3
|
return catalog.flatMap((entry) => (entry.operations ?? []).flatMap((operation) => {
|
|
4
4
|
const transport = operation.request.transport === 'mcp' ? mcpCallTool : httpRequestTool;
|
|
@@ -9,46 +9,46 @@ declare const OperationSchema: z.ZodObject<{
|
|
|
9
9
|
method: z.ZodString;
|
|
10
10
|
url: z.ZodString;
|
|
11
11
|
builder: z.ZodEnum<{
|
|
12
|
-
"gmail-send": "gmail-send";
|
|
13
|
-
"gmail-draft": "gmail-draft";
|
|
14
|
-
"calendar-meet-event": "calendar-meet-event";
|
|
15
12
|
"calendar-add-meet": "calendar-add-meet";
|
|
16
|
-
"
|
|
13
|
+
"calendar-meet-event": "calendar-meet-event";
|
|
17
14
|
"docs-append-text": "docs-append-text";
|
|
18
|
-
"
|
|
19
|
-
"sheets-write-values": "sheets-write-values";
|
|
20
|
-
"sheets-append-values": "sheets-append-values";
|
|
15
|
+
"docs-create": "docs-create";
|
|
21
16
|
"drive-create-folder": "drive-create-folder";
|
|
22
17
|
"drive-trash": "drive-trash";
|
|
18
|
+
"gmail-draft": "gmail-draft";
|
|
19
|
+
"gmail-send": "gmail-send";
|
|
23
20
|
"notion-create-page": "notion-create-page";
|
|
24
21
|
"notion-insert-content": "notion-insert-content";
|
|
22
|
+
"sheets-append-values": "sheets-append-values";
|
|
23
|
+
"sheets-create": "sheets-create";
|
|
24
|
+
"sheets-write-values": "sheets-write-values";
|
|
25
25
|
}>;
|
|
26
26
|
}, z.core.$strip>, z.ZodObject<{
|
|
27
27
|
transport: z.ZodOptional<z.ZodLiteral<"http">>;
|
|
28
28
|
method: z.ZodEnum<{
|
|
29
|
+
DELETE: "DELETE";
|
|
29
30
|
GET: "GET";
|
|
31
|
+
PATCH: "PATCH";
|
|
30
32
|
POST: "POST";
|
|
31
33
|
PUT: "PUT";
|
|
32
|
-
PATCH: "PATCH";
|
|
33
|
-
DELETE: "DELETE";
|
|
34
34
|
}>;
|
|
35
35
|
url: z.ZodString;
|
|
36
36
|
query: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
37
37
|
urlDefaults: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
38
38
|
builder: z.ZodEnum<{
|
|
39
|
-
"gmail-send": "gmail-send";
|
|
40
|
-
"gmail-draft": "gmail-draft";
|
|
41
|
-
"calendar-meet-event": "calendar-meet-event";
|
|
42
39
|
"calendar-add-meet": "calendar-add-meet";
|
|
43
|
-
"
|
|
40
|
+
"calendar-meet-event": "calendar-meet-event";
|
|
44
41
|
"docs-append-text": "docs-append-text";
|
|
45
|
-
"
|
|
46
|
-
"sheets-write-values": "sheets-write-values";
|
|
47
|
-
"sheets-append-values": "sheets-append-values";
|
|
42
|
+
"docs-create": "docs-create";
|
|
48
43
|
"drive-create-folder": "drive-create-folder";
|
|
49
44
|
"drive-trash": "drive-trash";
|
|
45
|
+
"gmail-draft": "gmail-draft";
|
|
46
|
+
"gmail-send": "gmail-send";
|
|
50
47
|
"notion-create-page": "notion-create-page";
|
|
51
48
|
"notion-insert-content": "notion-insert-content";
|
|
49
|
+
"sheets-append-values": "sheets-append-values";
|
|
50
|
+
"sheets-create": "sheets-create";
|
|
51
|
+
"sheets-write-values": "sheets-write-values";
|
|
52
52
|
}>;
|
|
53
53
|
}, z.core.$strip>]>;
|
|
54
54
|
response: z.ZodOptional<z.ZodObject<{
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { BUILDER_NAMES } from
|
|
2
|
+
import { BUILDER_NAMES } from './builders.js';
|
|
3
3
|
const ParameterType = z.enum(['string', 'number', 'boolean', 'object', 'integer', 'array', 'null']);
|
|
4
4
|
const ParameterSchema = z.lazy(() => z.object({
|
|
5
5
|
type: z.union([ParameterType, z.array(ParameterType).min(1)]),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { grounded } from 'asenion';
|
|
2
2
|
import { decodeBase64, printableRatio, strings } from 'asenion/guards';
|
|
3
|
-
import { READ_METHODS } from
|
|
3
|
+
import { READ_METHODS } from './http-methods.js';
|
|
4
4
|
const ADDRESS = /[^\s<>,;:"'\\]{1,64}@[^\s<>,;:"'\\]{1,255}\.[A-Za-z]{2,24}/g;
|
|
5
5
|
const PRINTABLE_RATIO = 0.9;
|
|
6
6
|
const RESERVED_DOMAINS = new Set(['example.com', 'example.net', 'example.org']);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { readLines } from
|
|
2
|
-
import { isDriveReadTruncated } from
|
|
3
|
-
import { canonicalDenyRoots, defaultRealpath, resolveKey } from
|
|
1
|
+
import { readLines } from './fs/read.js';
|
|
2
|
+
import { isDriveReadTruncated } from './fs/remote.js';
|
|
3
|
+
import { canonicalDenyRoots, defaultRealpath, resolveKey } from './fs/scope.js';
|
|
4
4
|
export const DEFAULT_READ_CHARS = 8192;
|
|
5
5
|
export const MAX_READ_CHARS = 65_536;
|
|
6
6
|
function lineIndex(value) {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import b4a from 'b4a';
|
|
3
3
|
import Localdrive from 'localdrive';
|
|
4
|
-
import { OBSIDIAN_VAULT_MODE_NOTE } from
|
|
5
|
-
import { unquoteArg } from
|
|
6
|
-
import { credentialRecord } from
|
|
7
|
-
import { resolveSkillsOverlayDir } from
|
|
8
|
-
import { parseSkillFrontMatter } from
|
|
9
|
-
import { parseToolGrant } from
|
|
10
|
-
import { shellEscapeArg } from
|
|
11
|
-
import { isObsidianVaultPath, OBSIDIAN_SKILL_NAME, OBSIDIAN_VAULT_PATH_CREDENTIAL_KEY } from
|
|
4
|
+
import { OBSIDIAN_VAULT_MODE_NOTE } from './exec/obsidian/guidance.js';
|
|
5
|
+
import { unquoteArg } from './model-args.js';
|
|
6
|
+
import { credentialRecord } from './skills/auth-resolver.js';
|
|
7
|
+
import { resolveSkillsOverlayDir } from './skills/overlay-dir.js';
|
|
8
|
+
import { parseSkillFrontMatter } from './skills/frontmatter-parser.js';
|
|
9
|
+
import { parseToolGrant } from './skills/tool-grants.js';
|
|
10
|
+
import { shellEscapeArg } from './exec/shell-argv.js';
|
|
11
|
+
import { isObsidianVaultPath, OBSIDIAN_SKILL_NAME, OBSIDIAN_VAULT_PATH_CREDENTIAL_KEY } from './skills/obsidian-readiness.js';
|
|
12
12
|
const MAIN_FILE = 'SKILL.md';
|
|
13
13
|
function resolveSkillDir(root, name) {
|
|
14
14
|
if (!root)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { raceAbort } from
|
|
2
|
-
import { parseObjectArg } from
|
|
1
|
+
import { raceAbort } from '../../helpers/race-abort.js';
|
|
2
|
+
import { parseObjectArg } from '../http-request/utils.js';
|
|
3
3
|
export function credentialRecord(value) {
|
|
4
4
|
if (typeof value === 'string')
|
|
5
5
|
return value ? { token: value } : null;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import process from 'process';
|
|
4
|
-
import { withHomebrewPath } from
|
|
4
|
+
import { withHomebrewPath } from '../../helpers/spawn-path.js';
|
|
5
5
|
const SAFE_BIN_NAME = /^[A-Za-z0-9._-]+$/;
|
|
6
6
|
function envPath() {
|
|
7
7
|
return process.env.PATH ?? process.env.Path ?? '';
|
|
@@ -2,8 +2,8 @@ import fs from 'fs';
|
|
|
2
2
|
import os from 'os';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import process from 'process';
|
|
5
|
-
import { userTmpPath } from
|
|
6
|
-
import { hashBundledSkills } from
|
|
5
|
+
import { userTmpPath } from '../../tmp-path.js';
|
|
6
|
+
import { hashBundledSkills } from './bundled-hash.js';
|
|
7
7
|
import { SKILLS as BUNDLED_SKILLS } from '@qvac/skills/bundled';
|
|
8
8
|
import { SKILLS_HASH as BUNDLED_SKILLS_HASH } from '@qvac/skills/hash';
|
|
9
9
|
let inflight = null;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import { platform } from 'os';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import { parseSkillFrontMatter } from
|
|
5
|
-
import { buildCliValidator, loadSkillCli } from
|
|
6
|
-
import { isModelCompatible, isStub, isToolSupported, resolveSkillState, SKILL_STATE, supportsPlatform } from
|
|
7
|
-
import { validateCredentialChecks } from
|
|
8
|
-
import { OBSIDIAN_SKILL_NAME } from
|
|
9
|
-
import { parseToolGrant } from
|
|
10
|
-
import { deriveSetup } from
|
|
11
|
-
import { resolveSkillsOverlayDir } from
|
|
12
|
-
import { parseOperationsManifest } from
|
|
13
|
-
import { hlog } from
|
|
4
|
+
import { parseSkillFrontMatter } from './frontmatter-parser.js';
|
|
5
|
+
import { buildCliValidator, loadSkillCli } from './cli-schema.js';
|
|
6
|
+
import { isModelCompatible, isStub, isToolSupported, resolveSkillState, SKILL_STATE, supportsPlatform } from './skill-state.js';
|
|
7
|
+
import { validateCredentialChecks } from './credential-check.js';
|
|
8
|
+
import { OBSIDIAN_SKILL_NAME } from './obsidian-readiness.js';
|
|
9
|
+
import { parseToolGrant } from './tool-grants.js';
|
|
10
|
+
import { deriveSetup } from './setup-routes.js';
|
|
11
|
+
import { resolveSkillsOverlayDir } from './overlay-dir.js';
|
|
12
|
+
import { parseOperationsManifest } from '../operations/manifest.js';
|
|
13
|
+
import { hlog } from '../../log.js';
|
|
14
14
|
export function skillSupportsPlatform(entry, platform) {
|
|
15
15
|
return supportsPlatform(entry, platform);
|
|
16
16
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { argvToObject, isObjectSchema, objectProps, walkCommands } from
|
|
2
|
+
import { argvToObject, isObjectSchema, objectProps, walkCommands } from './cli-argv.js';
|
|
3
3
|
export function buildSchemaAnnotation(schema) {
|
|
4
4
|
const resourceEffects = schema['x-resource-effects'];
|
|
5
5
|
return (argv) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import { CLI_SCHEMA_FILENAME } from
|
|
3
|
+
import { CLI_SCHEMA_FILENAME } from './cli-schema-types.js';
|
|
4
4
|
export async function resolveCliSchema(skillDir, bin, readFile = (p) => fs.promises.readFile(p, 'utf8')) {
|
|
5
5
|
const full = path.join(skillDir, CLI_SCHEMA_FILENAME);
|
|
6
6
|
let raw;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { CLI_SCHEMA_FILENAME } from
|
|
2
|
-
export { argvToObject } from
|
|
3
|
-
export { loadSkillCli, resolveCliSchema, execBinFromTools } from
|
|
4
|
-
import { buildSchemaAnnotation, buildSchemaCheck } from
|
|
1
|
+
export { CLI_SCHEMA_FILENAME } from './cli-schema-types.js';
|
|
2
|
+
export { argvToObject } from './cli-argv.js';
|
|
3
|
+
export { loadSkillCli, resolveCliSchema, execBinFromTools } from './cli-schema-load.js';
|
|
4
|
+
import { buildSchemaAnnotation, buildSchemaCheck } from './cli-schema-check.js';
|
|
5
5
|
export function buildCliValidator(def) {
|
|
6
6
|
const bin = def.bin.toLowerCase();
|
|
7
7
|
if (!def.schema) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import fetch from '#fetch';
|
|
2
2
|
import { Headers } from '#headers';
|
|
3
3
|
import { AbortController } from 'bare-abort-controller';
|
|
4
|
-
import { DEFAULT_USER_AGENT } from
|
|
5
|
-
import { credentialRecord, isCredentialUrlAllowed } from
|
|
6
|
-
import { credentialLastProbedAt, markCredentialRejected, markCredentialValid, setCredentialLastProbedAt } from
|
|
4
|
+
import { DEFAULT_USER_AGENT } from '../../user-agent.js';
|
|
5
|
+
import { credentialRecord, isCredentialUrlAllowed } from './auth-resolver.js';
|
|
6
|
+
import { credentialLastProbedAt, markCredentialRejected, markCredentialValid, setCredentialLastProbedAt } from './credential-health.js';
|
|
7
7
|
const TIMEOUT_MS = 5_000;
|
|
8
8
|
export const CREDENTIAL_CHECK_TTL_MS = 45_000;
|
|
9
9
|
const inflight = new Map();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { hlog } from
|
|
2
|
-
import { scopeKey } from
|
|
1
|
+
import { hlog } from '../../log.js';
|
|
2
|
+
import { scopeKey } from './scope-key.js';
|
|
3
3
|
const rejected = new Set();
|
|
4
4
|
const lastProbedAt = new Map();
|
|
5
5
|
function scopedKey(key, agentId, skill) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseManifestBlock } from
|
|
1
|
+
import { parseManifestBlock } from './manifest-parse.js';
|
|
2
2
|
const FRONT_MATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
|
|
3
3
|
const FIELD_RE = /^([A-Za-z_][\w-]*):(.*)$/;
|
|
4
4
|
const LIST_FIELDS = new Set(['tools', 'platform', 'credentials', 'allow_list', 'aliases']);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
1
|
+
export * from './auth-resolver.js';
|
|
2
|
+
export * from './catalog.js';
|
|
3
|
+
export * from './cli-schema.js';
|
|
4
|
+
export * from './credential-grants.js';
|
|
5
|
+
export * from './frontmatter-parser.js';
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export declare const SKILL_STATE: {
|
|
2
|
-
readonly ready:
|
|
3
|
-
readonly needsSetup:
|
|
4
|
-
readonly disconnected:
|
|
5
|
-
readonly unsupported:
|
|
6
|
-
readonly disabled:
|
|
7
|
-
readonly outdated:
|
|
8
|
-
readonly incompatibleModel:
|
|
9
|
-
readonly failed:
|
|
2
|
+
readonly ready: 'ready';
|
|
3
|
+
readonly needsSetup: 'needs-setup';
|
|
4
|
+
readonly disconnected: 'disconnected';
|
|
5
|
+
readonly unsupported: 'unsupported';
|
|
6
|
+
readonly disabled: 'disabled';
|
|
7
|
+
readonly outdated: 'outdated';
|
|
8
|
+
readonly incompatibleModel: 'incompatible-model';
|
|
9
|
+
readonly failed: 'failed';
|
|
10
10
|
};
|
|
11
11
|
export type SkillState = (typeof SKILL_STATE)[keyof typeof SKILL_STATE];
|
|
12
12
|
export declare function isAvailableState(state: SkillState): boolean;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { credentialRecord, isCredentialExpired } from
|
|
2
|
-
import { parseToolGrant } from
|
|
3
|
-
import { missingBins } from
|
|
4
|
-
import { credentialSlots } from
|
|
5
|
-
import { requiredSettings } from
|
|
6
|
-
import { isCredentialRejected } from
|
|
7
|
-
import { isObsidianVaultPath, isSandboxedWorkbenchInstall, OBSIDIAN_SKILL_NAME, OBSIDIAN_VAULT_PATH_CREDENTIAL_KEY, obsidianCliState, obsidianInstallState } from
|
|
8
|
-
import { isCapabilityProfile, meetsMinCapabilityProfile } from
|
|
9
|
-
import { SKILL_STATE, isAvailableState } from
|
|
1
|
+
import { credentialRecord, isCredentialExpired } from './auth-resolver.js';
|
|
2
|
+
import { parseToolGrant } from './tool-grants.js';
|
|
3
|
+
import { missingBins } from './bin-check.js';
|
|
4
|
+
import { credentialSlots } from './credential-slots.js';
|
|
5
|
+
import { requiredSettings } from './skill-settings.js';
|
|
6
|
+
import { isCredentialRejected } from './credential-health.js';
|
|
7
|
+
import { isObsidianVaultPath, isSandboxedWorkbenchInstall, OBSIDIAN_SKILL_NAME, OBSIDIAN_VAULT_PATH_CREDENTIAL_KEY, obsidianCliState, obsidianInstallState } from './obsidian-readiness.js';
|
|
8
|
+
import { isCapabilityProfile, meetsMinCapabilityProfile } from '../../models/model-catalog.js';
|
|
9
|
+
import { SKILL_STATE, isAvailableState } from './skill-state-constants.js';
|
|
10
10
|
export { SKILL_STATE, isAvailableState };
|
|
11
11
|
export function isStub(entry) {
|
|
12
12
|
return entry.stub === true;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const TOOLSETS: readonly [
|
|
1
|
+
export declare const TOOLSETS: readonly ['web-search', 'knowledge', 'files', 'exec', 'http-request', 'mcp-call'];
|
|
2
2
|
export type Toolset = (typeof TOOLSETS)[number];
|
|
3
3
|
export declare function asToolset(value?: string | null): Toolset | null;
|
|
4
4
|
export interface ToolsetScoped {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AbortedError, raceAbort } from
|
|
2
|
-
import { isPrivateOrBlocked, stripIPv6Brackets } from
|
|
1
|
+
import { AbortedError, raceAbort } from '../helpers/race-abort.js';
|
|
2
|
+
import { isPrivateOrBlocked, stripIPv6Brackets } from './private-ip.js';
|
|
3
3
|
const LITERAL_IPV4 = /^\d{1,3}(\.\d{1,3}){3}$/;
|
|
4
4
|
export function checkOutboundHost(url) {
|
|
5
5
|
const host = stripIPv6Brackets(url.hostname);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ResolvedPlace {
|
|
2
|
+
readonly area: string;
|
|
3
|
+
readonly region: string;
|
|
4
|
+
readonly country: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function fold(value: string): string;
|
|
7
|
+
export declare function describePlace(place: ResolvedPlace): string;
|
|
8
|
+
export declare function qualifierOf(location: string): string | null;
|
|
9
|
+
export declare function cityMatches(location: string, place: ResolvedPlace): boolean;
|
|
10
|
+
export type QualifierVerdict = 'match' | 'unverifiable' | 'contradiction';
|
|
11
|
+
export declare function checkQualifier(qualifier: string, place: ResolvedPlace): QualifierVerdict;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
const QUALIFIER_ALIASES = [
|
|
2
|
+
['united states of america', 'united states of america'],
|
|
3
|
+
['united states', 'united states of america'],
|
|
4
|
+
['u.s.a.', 'united states of america'],
|
|
5
|
+
['u.s.', 'united states of america'],
|
|
6
|
+
['usa', 'united states of america'],
|
|
7
|
+
['us', 'united states of america'],
|
|
8
|
+
['united kingdom', 'united kingdom'],
|
|
9
|
+
['great britain', 'united kingdom'],
|
|
10
|
+
['england', 'united kingdom'],
|
|
11
|
+
['scotland', 'united kingdom'],
|
|
12
|
+
['wales', 'united kingdom'],
|
|
13
|
+
['northern ireland', 'united kingdom'],
|
|
14
|
+
['u.k.', 'united kingdom'],
|
|
15
|
+
['uk', 'united kingdom'],
|
|
16
|
+
['gb', 'united kingdom'],
|
|
17
|
+
['united arab emirates', 'united arab emirates'],
|
|
18
|
+
['uae', 'united arab emirates'],
|
|
19
|
+
['holland', 'netherlands'],
|
|
20
|
+
['deutschland', 'germany'],
|
|
21
|
+
['espana', 'spain'],
|
|
22
|
+
['italia', 'italy']
|
|
23
|
+
];
|
|
24
|
+
const OTHER_SUBDIVISIONS = {
|
|
25
|
+
ab: 'alberta',
|
|
26
|
+
bc: 'british columbia',
|
|
27
|
+
mb: 'manitoba',
|
|
28
|
+
nb: 'new brunswick',
|
|
29
|
+
nl: 'newfoundland',
|
|
30
|
+
ns: 'nova scotia',
|
|
31
|
+
on: 'ontario',
|
|
32
|
+
pe: 'prince edward island',
|
|
33
|
+
qc: 'quebec',
|
|
34
|
+
sk: 'saskatchewan',
|
|
35
|
+
nsw: 'new south wales',
|
|
36
|
+
vic: 'victoria',
|
|
37
|
+
qld: 'queensland',
|
|
38
|
+
wa: 'western australia',
|
|
39
|
+
sa: 'south australia',
|
|
40
|
+
tas: 'tasmania',
|
|
41
|
+
nt: 'northern territory',
|
|
42
|
+
act: 'australian capital territory'
|
|
43
|
+
};
|
|
44
|
+
const US_STATES = {
|
|
45
|
+
al: 'alabama',
|
|
46
|
+
ak: 'alaska',
|
|
47
|
+
az: 'arizona',
|
|
48
|
+
ar: 'arkansas',
|
|
49
|
+
ca: 'california',
|
|
50
|
+
co: 'colorado',
|
|
51
|
+
ct: 'connecticut',
|
|
52
|
+
de: 'delaware',
|
|
53
|
+
fl: 'florida',
|
|
54
|
+
ga: 'georgia',
|
|
55
|
+
hi: 'hawaii',
|
|
56
|
+
id: 'idaho',
|
|
57
|
+
il: 'illinois',
|
|
58
|
+
in: 'indiana',
|
|
59
|
+
ia: 'iowa',
|
|
60
|
+
ks: 'kansas',
|
|
61
|
+
ky: 'kentucky',
|
|
62
|
+
la: 'louisiana',
|
|
63
|
+
me: 'maine',
|
|
64
|
+
md: 'maryland',
|
|
65
|
+
ma: 'massachusetts',
|
|
66
|
+
mi: 'michigan',
|
|
67
|
+
mn: 'minnesota',
|
|
68
|
+
ms: 'mississippi',
|
|
69
|
+
mo: 'missouri',
|
|
70
|
+
mt: 'montana',
|
|
71
|
+
ne: 'nebraska',
|
|
72
|
+
nv: 'nevada',
|
|
73
|
+
nh: 'new hampshire',
|
|
74
|
+
nj: 'new jersey',
|
|
75
|
+
nm: 'new mexico',
|
|
76
|
+
ny: 'new york',
|
|
77
|
+
nc: 'north carolina',
|
|
78
|
+
nd: 'north dakota',
|
|
79
|
+
oh: 'ohio',
|
|
80
|
+
ok: 'oklahoma',
|
|
81
|
+
or: 'oregon',
|
|
82
|
+
pa: 'pennsylvania',
|
|
83
|
+
ri: 'rhode island',
|
|
84
|
+
sc: 'south carolina',
|
|
85
|
+
sd: 'south dakota',
|
|
86
|
+
tn: 'tennessee',
|
|
87
|
+
tx: 'texas',
|
|
88
|
+
ut: 'utah',
|
|
89
|
+
vt: 'vermont',
|
|
90
|
+
va: 'virginia',
|
|
91
|
+
wa: 'washington',
|
|
92
|
+
wv: 'west virginia',
|
|
93
|
+
wi: 'wisconsin',
|
|
94
|
+
wy: 'wyoming',
|
|
95
|
+
dc: 'district of columbia'
|
|
96
|
+
};
|
|
97
|
+
export function fold(value) {
|
|
98
|
+
return value
|
|
99
|
+
.normalize('NFD')
|
|
100
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
101
|
+
.toLowerCase()
|
|
102
|
+
.replace(/[^a-z0-9]+/g, ' ')
|
|
103
|
+
.trim();
|
|
104
|
+
}
|
|
105
|
+
export function describePlace(place) {
|
|
106
|
+
return [place.area, place.region, place.country].filter((part) => part.length > 0).join(', ');
|
|
107
|
+
}
|
|
108
|
+
export function qualifierOf(location) {
|
|
109
|
+
const comma = location.indexOf(',');
|
|
110
|
+
if (comma === -1)
|
|
111
|
+
return null;
|
|
112
|
+
const qualifier = fold(location.slice(comma + 1));
|
|
113
|
+
return qualifier.length > 0 ? qualifier : null;
|
|
114
|
+
}
|
|
115
|
+
function expand(qualifier) {
|
|
116
|
+
const code = qualifier.replace(/ /g, '');
|
|
117
|
+
const subdivision = US_STATES[code] ?? OTHER_SUBDIVISIONS[code];
|
|
118
|
+
if (subdivision !== undefined)
|
|
119
|
+
return subdivision;
|
|
120
|
+
for (const [alias, full] of QUALIFIER_ALIASES) {
|
|
121
|
+
if (qualifier === fold(alias))
|
|
122
|
+
return full;
|
|
123
|
+
}
|
|
124
|
+
return qualifier;
|
|
125
|
+
}
|
|
126
|
+
function initialsOf(name) {
|
|
127
|
+
return name
|
|
128
|
+
.split(' ')
|
|
129
|
+
.map((word) => word[0] ?? '')
|
|
130
|
+
.join('');
|
|
131
|
+
}
|
|
132
|
+
const ABBREVIATION = /^[a-z]{1,3}$/;
|
|
133
|
+
export function cityMatches(location, place) {
|
|
134
|
+
const city = fold(location.split(',')[0] ?? '');
|
|
135
|
+
return city.length > 0 && fold(describePlace(place)).includes(city);
|
|
136
|
+
}
|
|
137
|
+
export function checkQualifier(qualifier, place) {
|
|
138
|
+
const wanted = expand(qualifier);
|
|
139
|
+
const code = qualifier.replace(/ /g, '');
|
|
140
|
+
const opaque = wanted === qualifier && ABBREVIATION.test(code);
|
|
141
|
+
for (const candidate of [fold(place.region), fold(place.country)]) {
|
|
142
|
+
if (candidate.length === 0)
|
|
143
|
+
continue;
|
|
144
|
+
if (initialsOf(candidate) === code)
|
|
145
|
+
return 'match';
|
|
146
|
+
if (opaque)
|
|
147
|
+
continue;
|
|
148
|
+
if (candidate.includes(wanted) || wanted.includes(candidate))
|
|
149
|
+
return 'match';
|
|
150
|
+
}
|
|
151
|
+
return opaque ? 'unverifiable' : 'contradiction';
|
|
152
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type ResolvedPlace } from './place.ts';
|
|
2
|
+
interface Translated {
|
|
3
|
+
readonly value: string;
|
|
4
|
+
}
|
|
5
|
+
interface CurrentCondition {
|
|
6
|
+
readonly temp_C?: string;
|
|
7
|
+
readonly temp_F?: string;
|
|
8
|
+
readonly FeelsLikeC?: string;
|
|
9
|
+
readonly humidity?: string;
|
|
10
|
+
readonly windspeedKmph?: string;
|
|
11
|
+
readonly weatherDesc?: ReadonlyArray<Translated>;
|
|
12
|
+
}
|
|
13
|
+
interface HourlyEntry {
|
|
14
|
+
readonly time?: string;
|
|
15
|
+
readonly weatherDesc?: ReadonlyArray<Translated>;
|
|
16
|
+
}
|
|
17
|
+
interface DailyForecast {
|
|
18
|
+
readonly date?: string;
|
|
19
|
+
readonly maxtempC?: string;
|
|
20
|
+
readonly mintempC?: string;
|
|
21
|
+
readonly maxtempF?: string;
|
|
22
|
+
readonly mintempF?: string;
|
|
23
|
+
readonly hourly?: ReadonlyArray<HourlyEntry>;
|
|
24
|
+
}
|
|
25
|
+
interface NearestArea {
|
|
26
|
+
readonly areaName?: ReadonlyArray<Translated>;
|
|
27
|
+
readonly region?: ReadonlyArray<Translated>;
|
|
28
|
+
readonly country?: ReadonlyArray<Translated>;
|
|
29
|
+
}
|
|
30
|
+
export interface WeatherJson {
|
|
31
|
+
readonly nearest_area?: ReadonlyArray<NearestArea>;
|
|
32
|
+
readonly current_condition?: ReadonlyArray<CurrentCondition>;
|
|
33
|
+
readonly weather?: ReadonlyArray<DailyForecast>;
|
|
34
|
+
}
|
|
35
|
+
export declare function placeOf(json: WeatherJson): ResolvedPlace | null;
|
|
36
|
+
export declare function renderReport(json: WeatherJson, place: ResolvedPlace, asked: string, verified: boolean): string;
|
|
37
|
+
export {};
|