skillscript-runtime 0.7.0 → 0.7.3
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 +86 -19
- package/dist/bootstrap.d.ts +11 -1
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +45 -6
- package/dist/bootstrap.js.map +1 -1
- package/dist/cli.js +25 -13
- package/dist/cli.js.map +1 -1
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +14 -1
- package/dist/compile.js.map +1 -1
- package/dist/connectors/config.d.ts +21 -1
- package/dist/connectors/config.d.ts.map +1 -1
- package/dist/connectors/config.js +49 -4
- package/dist/connectors/config.js.map +1 -1
- package/dist/connectors/index.d.ts +4 -0
- package/dist/connectors/index.d.ts.map +1 -1
- package/dist/connectors/index.js +11 -0
- package/dist/connectors/index.js.map +1 -1
- package/dist/connectors/local-model-mcp.d.ts +9 -0
- package/dist/connectors/local-model-mcp.d.ts.map +1 -0
- package/dist/connectors/local-model-mcp.js +73 -0
- package/dist/connectors/local-model-mcp.js.map +1 -0
- package/dist/connectors/memory-store-mcp.d.ts +9 -0
- package/dist/connectors/memory-store-mcp.d.ts.map +1 -0
- package/dist/connectors/memory-store-mcp.js +94 -0
- package/dist/connectors/memory-store-mcp.js.map +1 -0
- package/dist/help-content.d.ts.map +1 -1
- package/dist/help-content.js +321 -239
- package/dist/help-content.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/lint.d.ts.map +1 -1
- package/dist/lint.js +302 -49
- package/dist/lint.js.map +1 -1
- package/dist/parser.d.ts +23 -3
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +121 -9
- package/dist/parser.js.map +1 -1
- package/dist/runtime-config.d.ts +56 -0
- package/dist/runtime-config.d.ts.map +1 -0
- package/dist/runtime-config.js +145 -0
- package/dist/runtime-config.js.map +1 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +15 -7
- package/dist/runtime.js.map +1 -1
- package/examples/classify-support-ticket.skill.md +1 -1
- package/examples/custom-bootstrap.example.ts +130 -0
- package/examples/feedback-sentiment-scan.skill.md +0 -1
- package/examples/hello.skill.provenance.json +1 -1
- package/examples/morning-brief.skill.md +2 -4
- package/examples/onboarding-scaffold/README.md +80 -0
- package/examples/onboarding-scaffold/bootstrap.ts +100 -0
- package/examples/onboarding-scaffold/connectors.json +15 -0
- package/examples/onboarding-scaffold/file-memory-store.ts +95 -0
- package/examples/onboarding-scaffold/memory.example.json +23 -0
- package/examples/onboarding-scaffold/openai-local-model.ts +117 -0
- package/examples/onboarding-scaffold/tmux-shell-agent-connector.ts +110 -0
- package/package.json +1 -1
- package/scaffold/connectors.json +15 -13
package/dist/help-content.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help-content.js","sourceRoot":"","sources":["../src/help-content.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,kEAAkE;AAClE,qEAAqE;AACrE,2BAA2B;AAC3B,EAAE;AACF,kBAAkB;AAClB,0EAA0E;AAC1E,+DAA+D;AAC/D,uCAAuC;AACvC,kFAAkF;AAClF,kFAAkF;AAClF,uDAAuD;AACvD,EAAE;AACF,uEAAuE;AACvE,yDAAyD;AAIzD,MAAM,UAAU,GAAG
|
|
1
|
+
{"version":3,"file":"help-content.js","sourceRoot":"","sources":["../src/help-content.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -22,6 +22,12 @@ export { NoOpAgentConnector } from "./connectors/agent-noop.js";
|
|
|
22
22
|
export type { AgentConnector, AgentConnectorClass, AgentDescriptor, AgentStatus, DeliveryPayload, DeliveryReceipt, WakeOpts, WakeReceipt, } from "./connectors/agent.js";
|
|
23
23
|
export type { SkillStore, SkillStoreClass, SkillSource, SkillMeta, SkillStatus, SkillFilter, VersionInfo, MemoryStore, MemoryStoreClass, PortableMemory, QueryFilters, LocalModel, LocalModelClass, McpConnector, McpConnectorClass, McpDispatchCtx, StaticCapabilities, ManifestInfo, ConnectorType, CuratedMemoryField, } from "./connectors/types.js";
|
|
24
24
|
export { CURATED_MEMORY_FIELDS } from "./connectors/types.js";
|
|
25
|
+
export { loadSkillscriptConfig } from "./runtime-config.js";
|
|
26
|
+
export type { SkillscriptConfig, LoadSkillscriptConfigOpts, LoadSkillscriptConfigResult } from "./runtime-config.js";
|
|
27
|
+
export { bootstrap, defaultRegistry, wireDeclarativeTriggers } from "./bootstrap.js";
|
|
28
|
+
export type { BootstrapOpts, BootstrapResult, DefaultRegistryOpts } from "./bootstrap.js";
|
|
29
|
+
export { registerConnectorClass, unregisterConnectorClass, getConnectorClass, listKnownConnectorClasses, loadConnectorsConfig, } from "./connectors/config.js";
|
|
30
|
+
export type { ConnectorClassEntry, ConfiguredConnector, LoadConnectorsConfigOpts, LoadConnectorsConfigResult, } from "./connectors/config.js";
|
|
25
31
|
export { ConnectorError, SkillNotFoundError, VersionNotFoundError, LintFailureError, StorageConflictError, QueryError, DispatchError, ModelError, TimeoutError, OpError, ConnectorNotFoundError, OpTimeoutError, InteractiveOpInAutonomousModeError, UnsafeShellDisabledError, UnresolvedVariableError, MissingSkillReferenceError, } from "./errors.js";
|
|
26
32
|
export type { LintDiagnostic, OpErrorMetadata } from "./errors.js";
|
|
27
33
|
export { ReferenceIndex, ReferentialIntegrityError, buildReferenceIndex, extractReferences, storeSkill, deleteSkill, invalidateConnector, } from "./skill-manager.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,YAAY,EACV,WAAW,EACX,OAAO,EACP,MAAM,EACN,WAAW,EACX,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,aAAa,EACb,UAAU,EACV,UAAU,GACX,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACtH,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE7F,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEvE,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAElF,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,YAAY,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,YAAY,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,eAAe,EACf,eAAe,EACf,QAAQ,EACR,WAAW,GACZ,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,UAAU,EACV,eAAe,EACf,WAAW,EACX,SAAS,EACT,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,14 @@ export { SqliteMemoryStore } from "./connectors/memory-store.js";
|
|
|
22
22
|
export { CallbackMcpConnector } from "./connectors/mcp.js";
|
|
23
23
|
export { NoOpAgentConnector } from "./connectors/agent-noop.js";
|
|
24
24
|
export { CURATED_MEMORY_FIELDS } from "./connectors/types.js";
|
|
25
|
+
// v0.7.3 — canonical runtime config + adopter-extensible connector class registration.
|
|
26
|
+
export { loadSkillscriptConfig } from "./runtime-config.js";
|
|
27
|
+
// Bootstrap helpers (v0.7.3+ public): adopters wiring custom substrates import
|
|
28
|
+
// `Registry` + the connector classes + `wireDeclarativeTriggers`. The bundled
|
|
29
|
+
// `bootstrap()` is a reference implementation for default deployments — see
|
|
30
|
+
// `examples/onboarding-scaffold/bootstrap.ts` for a custom-substrate walkthrough.
|
|
31
|
+
export { bootstrap, defaultRegistry, wireDeclarativeTriggers } from "./bootstrap.js";
|
|
32
|
+
export { registerConnectorClass, unregisterConnectorClass, getConnectorClass, listKnownConnectorClasses, loadConnectorsConfig, } from "./connectors/config.js";
|
|
25
33
|
export { ConnectorError, SkillNotFoundError, VersionNotFoundError, LintFailureError, StorageConflictError, QueryError, DispatchError, ModelError, TimeoutError, OpError, ConnectorNotFoundError, OpTimeoutError, InteractiveOpInAutonomousModeError, UnsafeShellDisabledError, UnresolvedVariableError, MissingSkillReferenceError, } from "./errors.js";
|
|
26
34
|
export { ReferenceIndex, ReferentialIntegrityError, buildReferenceIndex, extractReferences, storeSkill, deleteSkill, invalidateConnector, } from "./skill-manager.js";
|
|
27
35
|
export { audit, formatAuditResult } from "./audit.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,mFAAmF;AACnF,+FAA+F;AAC/F,kCAAkC;AAClC,EAAE;AACF,wEAAwE;AACxE,6EAA6E;AAC7E,iEAAiE;AACjE,0CAA0C;AAE1C,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAe3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,aAAa,GACd,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAkChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,UAAU,EACV,YAAY,EACZ,OAAO,EACP,sBAAsB,EACtB,cAAc,EACd,kCAAkC,EAClC,wBAAwB,EACxB,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,cAAc,EACd,yBAAyB,EACzB,mBAAmB,EACnB,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGtD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGxD,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,cAAc,GACf,MAAM,YAAY,CAAC;AAUpB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAQ7C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAU5C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,mFAAmF;AACnF,+FAA+F;AAC/F,kCAAkC;AAClC,EAAE;AACF,wEAAwE;AACxE,6EAA6E;AAC7E,iEAAiE;AACjE,0CAA0C;AAE1C,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAe3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,aAAa,GACd,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAkChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,uFAAuF;AACvF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,+EAA+E;AAC/E,8EAA8E;AAC9E,4EAA4E;AAC5E,kFAAkF;AAClF,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAErF,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,iBAAiB,EACjB,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAQhC,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,UAAU,EACV,YAAY,EACZ,OAAO,EACP,sBAAsB,EACtB,cAAc,EACd,kCAAkC,EAClC,wBAAwB,EACxB,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,cAAc,EACd,yBAAyB,EACzB,mBAAmB,EACnB,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGtD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGxD,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,cAAc,GACf,MAAM,YAAY,CAAC;AAUpB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAQ7C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAU5C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/lint.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../src/lint.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../src/lint.ts"],"names":[],"mappings":"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"}
|
package/dist/lint.js
CHANGED
|
@@ -535,6 +535,14 @@ const DISALLOWED_TOOL = {
|
|
|
535
535
|
// masking real misconfiguration). Lint surfaces the same diagnostic at
|
|
536
536
|
// compile time when the runtime registry is queryable.
|
|
537
537
|
//
|
|
538
|
+
// v0.7.3 — name-match-before-primary fix (matches the v0.7.2 runtime
|
|
539
|
+
// dispatch resolver). Bare `$ <name>` where `<name>` matches a wired
|
|
540
|
+
// connector name (e.g., the auto-wired `llm` + `memory` bridges) routes
|
|
541
|
+
// to that connector directly; the lint must mirror the runtime's
|
|
542
|
+
// resolution order or the bare-form canonical syntax fails at lint
|
|
543
|
+
// before reaching dispatch. Same lesson as the v0.7.2 push-blocker:
|
|
544
|
+
// multi-layer promises need every layer to match.
|
|
545
|
+
//
|
|
538
546
|
// False-positive guard: only fires when `mcpConnectorNames` is non-undefined
|
|
539
547
|
// (lint context has real registry info) — embedder contexts that don't
|
|
540
548
|
// expose the registry stay silent rather than risk noise on legitimate
|
|
@@ -542,13 +550,11 @@ const DISALLOWED_TOOL = {
|
|
|
542
550
|
const UNWIRED_PRIMARY_CONNECTOR = {
|
|
543
551
|
id: "unwired-primary-connector",
|
|
544
552
|
severity: "error",
|
|
545
|
-
description: "A bare `$ TOOL` op (no connector prefix)
|
|
546
|
-
remediation: "Either add a `primary` entry to connectors.json that handles the tool, or qualify the op as `$ named_connector.TOOL` against a wired connector.
|
|
553
|
+
description: "A bare `$ TOOL` op (no connector prefix) routes to either (a) a wired connector matching the op name, or (b) the `primary` connector's tool dispatch. Neither resolves.",
|
|
554
|
+
remediation: "Either wire a connector whose name matches the bare op (the v0.7.2 canonical pattern — e.g., `llm` / `memory` auto-wire by default), add a `primary` entry to connectors.json that handles the tool, or qualify the op as `$ named_connector.TOOL` against a wired connector.",
|
|
547
555
|
check: (ctx) => {
|
|
548
556
|
if (ctx.mcpConnectorNames === undefined)
|
|
549
557
|
return [];
|
|
550
|
-
if (ctx.mcpConnectorNames.includes("primary"))
|
|
551
|
-
return [];
|
|
552
558
|
const findings = [];
|
|
553
559
|
const reported = new Set();
|
|
554
560
|
for (const [targetName, target] of ctx.parsed.targets) {
|
|
@@ -562,6 +568,15 @@ const UNWIRED_PRIMARY_CONNECTOR = {
|
|
|
562
568
|
const toolName = m[1];
|
|
563
569
|
if (toolName === "execute_skill" || toolName === "json_parse")
|
|
564
570
|
return;
|
|
571
|
+
// v0.7.3 name-match: if the bare op name matches a wired
|
|
572
|
+
// connector, the runtime dispatch resolver routes there directly.
|
|
573
|
+
// (Mirrors `runtime.ts` `$` op dispatch — kept in sync with that
|
|
574
|
+
// fix to prevent the v0.7.2-shape regression of lint-fails-then-
|
|
575
|
+
// user-never-reaches-runtime.)
|
|
576
|
+
if (ctx.mcpConnectorNames.includes(toolName))
|
|
577
|
+
return;
|
|
578
|
+
if (ctx.mcpConnectorNames.includes("primary"))
|
|
579
|
+
return;
|
|
565
580
|
const key = `${targetName}:${toolName}`;
|
|
566
581
|
if (reported.has(key))
|
|
567
582
|
return;
|
|
@@ -569,7 +584,7 @@ const UNWIRED_PRIMARY_CONNECTOR = {
|
|
|
569
584
|
findings.push({
|
|
570
585
|
rule: "unwired-primary-connector",
|
|
571
586
|
severity: "error",
|
|
572
|
-
message: `\`$ ${toolName}\` in target '${targetName}' is a bare tool op
|
|
587
|
+
message: `\`$ ${toolName}\` in target '${targetName}' is a bare tool op — no connector named '${toolName}' wired and no \`primary\` fallback. Wired connectors: ${ctx.mcpConnectorNames.length === 0 ? "(none)" : ctx.mcpConnectorNames.join(", ")}.`,
|
|
573
588
|
block: targetName,
|
|
574
589
|
extras: { tool: toolName },
|
|
575
590
|
});
|
|
@@ -1073,8 +1088,8 @@ const MUTATING_TOOL_PATTERN = /^(?:write_|update_|delete_|remove_|set_|create_|i
|
|
|
1073
1088
|
const UNCONFIRMED_MUTATION = {
|
|
1074
1089
|
id: "unconfirmed-mutation",
|
|
1075
1090
|
severity: "warning",
|
|
1076
|
-
description: "A
|
|
1077
|
-
remediation: "
|
|
1091
|
+
description: "A mutation-class op runs without author authorization. Mutation classes: `$ tool` with mutating-name shape (write/update/delete/...); `$ memory_write` MCP dispatch; `file_write(...)` function-call op. Silent when the skill declares `# Autonomous: true` (v0.4.2), when a preceding `??` / `ask(...)` confirmation gates the op, or (v0.7.0+) when the op carries `approved=\"reason\"` per-op authorization.",
|
|
1092
|
+
remediation: "Three ways to authorize: (1) add `# Autonomous: true` at the skill header for cron/agent-fired skills; (2) add a preceding `??` / `ask(prompt=\"...\")` confirmation op in the same target; (3) v0.7.0+: pass `approved=\"reason\"` kwarg on the mutation op itself (any non-empty string; presence is what matters, value not parsed semantically).",
|
|
1078
1093
|
check: (ctx) => {
|
|
1079
1094
|
// v0.4.2 — `# Autonomous: true` skills are unattended by design;
|
|
1080
1095
|
// the user-confirmation pattern doesn't apply. Silent for the
|
|
@@ -1085,19 +1100,44 @@ const UNCONFIRMED_MUTATION = {
|
|
|
1085
1100
|
for (const [targetName, target] of ctx.parsed.targets) {
|
|
1086
1101
|
let sawConfirm = false;
|
|
1087
1102
|
for (const op of target.ops) {
|
|
1103
|
+
// v0.7.0+: ask(prompt=...) parses to kind "??" in the AST, so the
|
|
1104
|
+
// existing check captures both legacy `??` and canonical `ask()`.
|
|
1088
1105
|
if (op.kind === "??")
|
|
1089
1106
|
sawConfirm = true;
|
|
1090
|
-
if (
|
|
1107
|
+
if (sawConfirm)
|
|
1108
|
+
continue;
|
|
1109
|
+
// v0.7.0+: per-op `approved="reason"` kwarg authorizes individual ops
|
|
1110
|
+
// without requiring # Autonomous: true skill-level or `??` step.
|
|
1111
|
+
const isApproved = typeof op.approved === "string" && op.approved.length > 0;
|
|
1112
|
+
if (isApproved)
|
|
1113
|
+
continue;
|
|
1114
|
+
// Class 1: `$` MCP dispatch with mutating tool name.
|
|
1115
|
+
if (op.kind === "$") {
|
|
1091
1116
|
const toolName = op.body.split(/\s+/)[0] ?? "";
|
|
1092
|
-
|
|
1117
|
+
// memory_write is explicitly a mutation tool name — flag it even
|
|
1118
|
+
// though it doesn't start with `write_` (the pattern's anchor).
|
|
1119
|
+
const isMemoryWrite = toolName === "memory_write" || /(?:^|_)memory_write(?:_|$)/.test(toolName);
|
|
1120
|
+
if (MUTATING_TOOL_PATTERN.test(toolName) || isMemoryWrite) {
|
|
1093
1121
|
findings.push({
|
|
1094
1122
|
rule: "unconfirmed-mutation",
|
|
1095
1123
|
severity: "warning",
|
|
1096
|
-
message: `\`$\` op in target '${targetName}' invokes '${toolName}' (mutating shape) without
|
|
1124
|
+
message: `\`$\` op in target '${targetName}' invokes '${toolName}' (mutating shape) without authorization. Add \`approved="..."\` kwarg, precede with \`ask(...)\`, or declare \`# Autonomous: true\`.`,
|
|
1097
1125
|
block: targetName,
|
|
1126
|
+
extras: { tool_name: toolName },
|
|
1098
1127
|
});
|
|
1099
1128
|
}
|
|
1100
1129
|
}
|
|
1130
|
+
// Class 2: file_write runtime-intrinsic op (v0.7.0).
|
|
1131
|
+
if (op.kind === "file_write") {
|
|
1132
|
+
const path = op.fileParams?.path ?? "";
|
|
1133
|
+
findings.push({
|
|
1134
|
+
rule: "unconfirmed-mutation",
|
|
1135
|
+
severity: "warning",
|
|
1136
|
+
message: `\`file_write(path="${path}")\` in target '${targetName}' is a mutation op without authorization. Add \`approved="..."\` kwarg, precede with \`ask(...)\`, or declare \`# Autonomous: true\`.`,
|
|
1137
|
+
block: targetName,
|
|
1138
|
+
extras: { op_kind: "file_write", path },
|
|
1139
|
+
});
|
|
1140
|
+
}
|
|
1101
1141
|
}
|
|
1102
1142
|
}
|
|
1103
1143
|
return findings;
|
|
@@ -1530,51 +1570,84 @@ function isOriginSuspect(origin) {
|
|
|
1530
1570
|
const UNQUOTED_SUBSTITUTION_IN_KWARG_VALUE = {
|
|
1531
1571
|
id: "unquoted-substitution-in-kwarg-value",
|
|
1532
1572
|
severity: "warning",
|
|
1533
|
-
description: "A `$ tool key=$(VAR)` op kwarg has an unquoted `$(VAR)` substitution where VAR may resolve to a value containing whitespace. Runtime renders into `key=value with spaces` then re-tokenizes on whitespace — only the first chunk binds to `key
|
|
1534
|
-
remediation: "Wrap the substitution in quotes: `key=\"$(VAR)\"
|
|
1573
|
+
description: "A `$ tool key=$(VAR)` op kwarg OR a legacy `@ cmd ... $(VAR)` shell arg has an unquoted `$(VAR)` / `${VAR}` substitution where VAR may resolve to a value containing whitespace. Runtime renders into `key=value with spaces` then re-tokenizes on whitespace — only the first chunk binds to `key` (MCP) or first arg (shell). Silent arg truncation. v0.7.2 extends coverage from `$` ops to `@` ops per R4 minion 4 finding.",
|
|
1574
|
+
remediation: "Wrap the substitution in quotes: `key=\"$(VAR)\"` for MCP kwargs, `\"$(VAR)\"` for shell args. The arg tokenizer respects quoted regions, preventing the re-tokenization split.",
|
|
1535
1575
|
check: (ctx) => {
|
|
1536
1576
|
const findings = [];
|
|
1537
1577
|
const origins = buildBindingOrigins(ctx.parsed);
|
|
1538
1578
|
const reported = new Set();
|
|
1579
|
+
// v0.7.2: shared pattern matches both legacy `$(VAR)` and canonical
|
|
1580
|
+
// `${VAR}` substitution forms. Only the opening delimiter + var-name
|
|
1581
|
+
// are required to match (no closing `)`/`}`) so filter chains like
|
|
1582
|
+
// `$(VAR|trim)` and `${VAR|filter:"x"}` parse cleanly. The capture
|
|
1583
|
+
// groups (1 = paren-form name, 2 = brace-form name) get coalesced.
|
|
1584
|
+
const subStPattern = /\$(?:\(([^|)\s]+)|\{([^|}\s]+))/;
|
|
1539
1585
|
for (const [targetName, target] of ctx.parsed.targets) {
|
|
1540
1586
|
walkOps(target.ops, (op) => {
|
|
1541
|
-
if (op.kind
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
})
|
|
1587
|
+
if (op.kind === "$") {
|
|
1588
|
+
// $ MCP dispatch — scan kwarg values for unquoted substitutions.
|
|
1589
|
+
const tokens = tokenizeKeywordArgs(op.body);
|
|
1590
|
+
for (const tok of tokens) {
|
|
1591
|
+
const eq = tok.indexOf("=");
|
|
1592
|
+
if (eq === -1)
|
|
1593
|
+
continue;
|
|
1594
|
+
const key = tok.slice(0, eq);
|
|
1595
|
+
const value = tok.slice(eq + 1);
|
|
1596
|
+
if (!(value.startsWith("$(") || value.startsWith("${")))
|
|
1597
|
+
continue;
|
|
1598
|
+
const m = subStPattern.exec(value);
|
|
1599
|
+
if (m === null)
|
|
1600
|
+
continue;
|
|
1601
|
+
const varName = (m[1] ?? m[2]);
|
|
1602
|
+
const rootVar = varName.split(".")[0];
|
|
1603
|
+
const origin = origins.get(rootVar);
|
|
1604
|
+
if (!isOriginSuspect(origin))
|
|
1605
|
+
continue;
|
|
1606
|
+
const dedupKey = `${targetName}:$:${key}:${varName}`;
|
|
1607
|
+
if (reported.has(dedupKey))
|
|
1608
|
+
continue;
|
|
1609
|
+
reported.add(dedupKey);
|
|
1610
|
+
findings.push({
|
|
1611
|
+
rule: "unquoted-substitution-in-kwarg-value",
|
|
1612
|
+
severity: "warning",
|
|
1613
|
+
message: `\`$ ... ${key}=\${${varName}}\` in target '${targetName}': unquoted substitution. ${describeOriginRisk(origin)} Wrap as \`${key}="\${${varName}}"\` to prevent silent arg truncation if the value contains whitespace.`,
|
|
1614
|
+
block: targetName,
|
|
1615
|
+
extras: { kwarg: key, var_name: varName, origin: origin.kind, op: "$" },
|
|
1616
|
+
});
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
else if (op.kind === "@") {
|
|
1620
|
+
// v0.7.2 — legacy @ shell op. Tokenize the body the same way the
|
|
1621
|
+
// runtime would (whitespace-separated, quotes respected), then
|
|
1622
|
+
// flag any token that is a bare unquoted substitution. Quoted
|
|
1623
|
+
// tokens (`"${VAR}"` / `'${VAR}'`) are safe.
|
|
1624
|
+
const tokens = tokenizeKeywordArgs(op.body);
|
|
1625
|
+
for (const tok of tokens) {
|
|
1626
|
+
// Skip quoted tokens — the quotes protect against whitespace split.
|
|
1627
|
+
if ((tok.startsWith('"') && tok.endsWith('"')) || (tok.startsWith("'") && tok.endsWith("'")))
|
|
1628
|
+
continue;
|
|
1629
|
+
if (!(tok.startsWith("$(") || tok.startsWith("${")))
|
|
1630
|
+
continue;
|
|
1631
|
+
const m = subStPattern.exec(tok);
|
|
1632
|
+
if (m === null)
|
|
1633
|
+
continue;
|
|
1634
|
+
const varName = (m[1] ?? m[2]);
|
|
1635
|
+
const rootVar = varName.split(".")[0];
|
|
1636
|
+
const origin = origins.get(rootVar);
|
|
1637
|
+
if (!isOriginSuspect(origin))
|
|
1638
|
+
continue;
|
|
1639
|
+
const dedupKey = `${targetName}:@:${varName}`;
|
|
1640
|
+
if (reported.has(dedupKey))
|
|
1641
|
+
continue;
|
|
1642
|
+
reported.add(dedupKey);
|
|
1643
|
+
findings.push({
|
|
1644
|
+
rule: "unquoted-substitution-in-kwarg-value",
|
|
1645
|
+
severity: "warning",
|
|
1646
|
+
message: `\`@ ... \${${varName}}\` shell arg in target '${targetName}': unquoted substitution. ${describeOriginRisk(origin)} Wrap as \`"\${${varName}}"\` to prevent silent word-splitting if the value contains whitespace.`,
|
|
1647
|
+
block: targetName,
|
|
1648
|
+
extras: { var_name: varName, origin: origin.kind, op: "@" },
|
|
1649
|
+
});
|
|
1650
|
+
}
|
|
1578
1651
|
}
|
|
1579
1652
|
});
|
|
1580
1653
|
}
|
|
@@ -1595,6 +1668,183 @@ function describeOriginRisk(origin) {
|
|
|
1595
1668
|
return `Variable is a \`foreach\` iterator — element type unknown statically.`;
|
|
1596
1669
|
}
|
|
1597
1670
|
}
|
|
1671
|
+
/**
|
|
1672
|
+
* v0.7.1 — tier-2 visibility nudge for legacy symbol-form ops (`~`, `>`,
|
|
1673
|
+
* `@`, `!`, `??`, `&`). The parser still accepts these during the v0.7.x
|
|
1674
|
+
* grace period; the runtime dispatches them as before. This rule surfaces
|
|
1675
|
+
* the canonical replacement so authors editing skills see the migration
|
|
1676
|
+
* path. Tier-1 promotion (refuse-to-compile) lands in v0.8 or v0.9 once
|
|
1677
|
+
* the adopter ecosystem confirms migration is settled.
|
|
1678
|
+
*
|
|
1679
|
+
* The `$ tool` op is NOT flagged — that shape is canonical (MCP dispatch
|
|
1680
|
+
* marker). Only the 6 symbol ops that became function-call ops in v0.7.0.
|
|
1681
|
+
*/
|
|
1682
|
+
const DEPRECATED_SYMBOL_OP_REPLACEMENT = {
|
|
1683
|
+
// v0.7.2: bridge classes ship default-wired so `$ llm` / `$ memory` work
|
|
1684
|
+
// out of the box in default deployments. Suggestions are load-bearing
|
|
1685
|
+
// (no more "(or your wired connector name)" caveat).
|
|
1686
|
+
"~": "$ llm prompt=\"...\" [maxTokens=N] [model=\"...\"] -> R",
|
|
1687
|
+
">": "$ memory mode=\"fts|semantic|rerank\" query=\"...\" limit=N -> R",
|
|
1688
|
+
"@": "shell(command=\"...\") [-> R]",
|
|
1689
|
+
"!": "emit(text=\"...\")",
|
|
1690
|
+
"??": "ask(prompt=\"...\") -> R",
|
|
1691
|
+
"&": "inline(skill=\"...\") (or execute_skill(skill_name=\"...\", ...) -> R for procedural composition)",
|
|
1692
|
+
};
|
|
1693
|
+
const DEPRECATED_SYMBOL_OP = {
|
|
1694
|
+
id: "deprecated-symbol-op",
|
|
1695
|
+
severity: "warning",
|
|
1696
|
+
description: "An op uses the legacy symbol form deprecated in v0.7.0.",
|
|
1697
|
+
remediation: "Rewrite to the canonical v0.7.0 form (see message). All legacy ops continue to compile during the grace period; tier-1 promotion (refuse-to-compile) lands in v0.8/v0.9. See CHANGELOG.md `## 0.7.0 — Migration` for the full rewrite rules.",
|
|
1698
|
+
check: (ctx) => {
|
|
1699
|
+
const findings = [];
|
|
1700
|
+
for (const [targetName, target] of ctx.parsed.targets) {
|
|
1701
|
+
const reported = new Set();
|
|
1702
|
+
walkOps(target.ops, (op) => {
|
|
1703
|
+
const replacement = DEPRECATED_SYMBOL_OP_REPLACEMENT[op.kind];
|
|
1704
|
+
if (replacement === undefined)
|
|
1705
|
+
return;
|
|
1706
|
+
// v0.7.1: skip ops authored in canonical function-call form. The
|
|
1707
|
+
// parser collapses both `! x` and `emit(text="x")` to kind "!",
|
|
1708
|
+
// so without the sourceForm marker the lint would fire on
|
|
1709
|
+
// canonical code. Source-form marker preserves which surface
|
|
1710
|
+
// the author wrote.
|
|
1711
|
+
if (op.sourceForm === "function-call")
|
|
1712
|
+
return;
|
|
1713
|
+
// Dedupe per-kind-per-target — one nudge per legacy op type per
|
|
1714
|
+
// target is plenty; further occurrences don't add signal.
|
|
1715
|
+
const key = `${targetName}:${op.kind}`;
|
|
1716
|
+
if (reported.has(key))
|
|
1717
|
+
return;
|
|
1718
|
+
reported.add(key);
|
|
1719
|
+
findings.push({
|
|
1720
|
+
rule: "deprecated-symbol-op",
|
|
1721
|
+
severity: "warning",
|
|
1722
|
+
message: `Op '${op.kind}' in target '${targetName}' is deprecated in v0.7.0. Rewrite as: \`${replacement}\``,
|
|
1723
|
+
block: targetName,
|
|
1724
|
+
extras: { legacy_op: op.kind, canonical_replacement: replacement },
|
|
1725
|
+
});
|
|
1726
|
+
});
|
|
1727
|
+
if (target.elseBlock !== undefined) {
|
|
1728
|
+
walkOps(target.elseBlock, (op) => {
|
|
1729
|
+
const replacement = DEPRECATED_SYMBOL_OP_REPLACEMENT[op.kind];
|
|
1730
|
+
if (replacement === undefined)
|
|
1731
|
+
return;
|
|
1732
|
+
if (op.sourceForm === "function-call")
|
|
1733
|
+
return;
|
|
1734
|
+
const key = `${targetName}:else:${op.kind}`;
|
|
1735
|
+
if (reported.has(key))
|
|
1736
|
+
return;
|
|
1737
|
+
reported.add(key);
|
|
1738
|
+
findings.push({
|
|
1739
|
+
rule: "deprecated-symbol-op",
|
|
1740
|
+
severity: "warning",
|
|
1741
|
+
message: `Op '${op.kind}' in target '${targetName}' (else block) is deprecated in v0.7.0. Rewrite as: \`${replacement}\``,
|
|
1742
|
+
block: targetName,
|
|
1743
|
+
extras: { legacy_op: op.kind, canonical_replacement: replacement },
|
|
1744
|
+
});
|
|
1745
|
+
});
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
return findings;
|
|
1749
|
+
},
|
|
1750
|
+
};
|
|
1751
|
+
/**
|
|
1752
|
+
* v0.7.1 — tier-2 visibility nudge for legacy `$(VAR)` substitution form.
|
|
1753
|
+
* Canonical v0.7.0+ form is `${VAR}`. Parser/runtime accept both during
|
|
1754
|
+
* grace period. Dedupes per-var-per-target; one nudge per `$(VAR)` form
|
|
1755
|
+
* per scope.
|
|
1756
|
+
*
|
|
1757
|
+
* Skips the `$$(...)` escape (used in `@ unsafe` op bodies for shell
|
|
1758
|
+
* literal pass-through). Skips ops where the body is `$set` source
|
|
1759
|
+
* (because $set's RHS is its own substitution context and the lint would
|
|
1760
|
+
* double-fire).
|
|
1761
|
+
*/
|
|
1762
|
+
const DEPRECATED_SUBSTITUTION_SHAPE = {
|
|
1763
|
+
id: "deprecated-substitution-shape",
|
|
1764
|
+
severity: "warning",
|
|
1765
|
+
description: "A `$(VAR)` substitution uses the legacy v0.6.x form deprecated in v0.7.0.",
|
|
1766
|
+
remediation: "Rewrite to `${VAR}` canonical form. Both forms produce identical results during the v0.7.x grace period; tier-1 promotion lands in v0.8/v0.9. The `$$(VAR)` escape (for `@ unsafe` shell literal pass-through) is unchanged.",
|
|
1767
|
+
check: (ctx) => {
|
|
1768
|
+
const findings = [];
|
|
1769
|
+
// Negative lookbehind blocks `$$(VAR)` escape form so the lint doesn't
|
|
1770
|
+
// fire on shell-escape sites authors deliberately wrote.
|
|
1771
|
+
const legacyRe = /(?<!\$)\$\(([^|)\s]+)/g;
|
|
1772
|
+
for (const [targetName, target] of ctx.parsed.targets) {
|
|
1773
|
+
const reported = new Set();
|
|
1774
|
+
const scanOp = (op, scope) => {
|
|
1775
|
+
const text = collectOpText(op);
|
|
1776
|
+
let m;
|
|
1777
|
+
while ((m = legacyRe.exec(text)) !== null) {
|
|
1778
|
+
const varName = m[1];
|
|
1779
|
+
const key = `${targetName}:${scope}:${varName}`;
|
|
1780
|
+
if (reported.has(key))
|
|
1781
|
+
continue;
|
|
1782
|
+
reported.add(key);
|
|
1783
|
+
findings.push({
|
|
1784
|
+
rule: "deprecated-substitution-shape",
|
|
1785
|
+
severity: "warning",
|
|
1786
|
+
message: `Substitution '$(${varName})' in target '${targetName}'${scope === "else" ? " (else block)" : ""} uses the legacy v0.6.x form. Rewrite as '\${${varName}}'.`,
|
|
1787
|
+
block: targetName,
|
|
1788
|
+
extras: { var_name: varName, legacy_form: `$(${varName})`, canonical_form: `\${${varName}}` },
|
|
1789
|
+
});
|
|
1790
|
+
}
|
|
1791
|
+
legacyRe.lastIndex = 0;
|
|
1792
|
+
};
|
|
1793
|
+
walkOps(target.ops, (op) => scanOp(op, "main"));
|
|
1794
|
+
if (target.elseBlock !== undefined) {
|
|
1795
|
+
walkOps(target.elseBlock, (op) => scanOp(op, "else"));
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
return findings;
|
|
1799
|
+
},
|
|
1800
|
+
};
|
|
1801
|
+
/**
|
|
1802
|
+
* v0.7.2 — tier-3 advisory for the R4 cold-author footgun (4 of 5 minions).
|
|
1803
|
+
* `foreach IT in ${VAR}` where VAR's binding origin is a `$` MCP tool output
|
|
1804
|
+
* (and the iteration expression has no `.field` accessor). MCP tools commonly
|
|
1805
|
+
* wrap arrays in an envelope object (e.g., `{issuesPage: [...], hasNextPage}`,
|
|
1806
|
+
* `{items: [...]}`, `{results: [...]}`) — cold authors iterating the bare
|
|
1807
|
+
* bound var get silent stringification + a single-iteration loop with the
|
|
1808
|
+
* stringification as the iterator value. Downstream `${IT.field}` errors.
|
|
1809
|
+
*
|
|
1810
|
+
* Placeholder for the v0.8 tool-schema-introspection solution that catches
|
|
1811
|
+
* this precisely. Advisory hints at the common envelope-field names.
|
|
1812
|
+
*/
|
|
1813
|
+
const OBJECT_ITERATION_ADVISORY = {
|
|
1814
|
+
id: "object-iteration-advisory",
|
|
1815
|
+
severity: "info",
|
|
1816
|
+
description: "A `foreach IT in ${VAR}` iterates a bound variable whose origin is a `$` MCP tool output, without a `.field` accessor. MCP tools commonly wrap arrays in an envelope.",
|
|
1817
|
+
remediation: "Check the tool's response shape — most MCP services wrap arrays under fields like `.items`, `.results`, `.issuesPage`, `.data`, `.records`. Rewrite as `foreach IT in ${VAR.items}` (or the correct field) once you know the shape. v0.8 tool-schema introspection will catch this precisely; today the advisory is a soft nudge.",
|
|
1818
|
+
check: (ctx) => {
|
|
1819
|
+
const findings = [];
|
|
1820
|
+
const origins = buildBindingOrigins(ctx.parsed);
|
|
1821
|
+
// Bare var ref pattern: `$(VAR)` or `${VAR}` — no dotted accessor, no filter chain.
|
|
1822
|
+
const bareRef = /^\s*\$(?:\(([A-Za-z_]\w*)\)|\{([A-Za-z_]\w*)\})\s*$/;
|
|
1823
|
+
for (const [targetName, target] of ctx.parsed.targets) {
|
|
1824
|
+
walkOps(target.ops, (op) => {
|
|
1825
|
+
if (op.kind !== "foreach" || op.foreachList === undefined)
|
|
1826
|
+
return;
|
|
1827
|
+
const m = bareRef.exec(op.foreachList);
|
|
1828
|
+
if (m === null)
|
|
1829
|
+
return;
|
|
1830
|
+
const varName = (m[1] ?? m[2]);
|
|
1831
|
+
const origin = origins.get(varName);
|
|
1832
|
+
if (origin === undefined)
|
|
1833
|
+
return;
|
|
1834
|
+
if (origin.kind !== "op-output" || origin.op !== "$")
|
|
1835
|
+
return;
|
|
1836
|
+
findings.push({
|
|
1837
|
+
rule: "object-iteration-advisory",
|
|
1838
|
+
severity: "info",
|
|
1839
|
+
message: `In target '${targetName}': \`foreach ${op.foreachIter} in \${${varName}}\` iterates a bare \`$\` op output without a \`.field\` accessor. Most MCP tools wrap arrays in an envelope (e.g., \`.items\`, \`.results\`, \`.issuesPage\`, \`.data\`). Check the tool's response shape; rewrite as \`foreach ${op.foreachIter} in \${${varName}.items}\` (or the actual array field) if so.`,
|
|
1840
|
+
block: targetName,
|
|
1841
|
+
extras: { var_name: varName, foreach_iter: op.foreachIter },
|
|
1842
|
+
});
|
|
1843
|
+
});
|
|
1844
|
+
}
|
|
1845
|
+
return findings;
|
|
1846
|
+
},
|
|
1847
|
+
};
|
|
1598
1848
|
const RULES = [
|
|
1599
1849
|
// Tier-1 (error)
|
|
1600
1850
|
PARSE_ERROR,
|
|
@@ -1628,6 +1878,8 @@ const RULES = [
|
|
|
1628
1878
|
MISSING_SKILLSTORE_FOR_DATA_REF,
|
|
1629
1879
|
// Tier-2 (warning)
|
|
1630
1880
|
DEPRECATED_QUESTION,
|
|
1881
|
+
DEPRECATED_SYMBOL_OP,
|
|
1882
|
+
DEPRECATED_SUBSTITUTION_SHAPE,
|
|
1631
1883
|
UNSAFE_SHELL_AMBIGUOUS_SUBST,
|
|
1632
1884
|
UNSAFE_SHELL_OP,
|
|
1633
1885
|
UNSAFE_SHELL_DISABLED,
|
|
@@ -1642,6 +1894,7 @@ const RULES = [
|
|
|
1642
1894
|
DUPLICATE_SKILL_NAME,
|
|
1643
1895
|
PLUGIN_COLLISION,
|
|
1644
1896
|
UNPARSED_JSON_FIELD_ACCESS,
|
|
1897
|
+
OBJECT_ITERATION_ADVISORY,
|
|
1645
1898
|
];
|
|
1646
1899
|
/** Read-only view of the rule registry — for tooling that introspects v1 rules. */
|
|
1647
1900
|
export function listRules() {
|